diff --git a/.claude/rules/feast-components.md b/.claude/rules/feast-components.md new file mode 100644 index 00000000000..5c03cb0bd3d --- /dev/null +++ b/.claude/rules/feast-components.md @@ -0,0 +1,44 @@ +--- +paths: + - sdk/python/feast/infra/online_stores/** + - sdk/python/feast/infra/offline_stores/** + - sdk/python/feast/infra/registry/** + - sdk/python/tests/unit/infra/** + - go/** + - infra/feast-operator/** +--- + +Read `skills/feast-architecture/SKILL.md` for the relevant component section: + +| Working in… | Read section | +|---|---| +| `online_stores/` | Online Store — config pattern, entity key serialization, async support, registration | +| `offline_stores/` | Offline Store — interface, PIT join, pull_latest, adding a new backend | +| `infra/registry/` | Registry — proto vs SQL backend, caching, adding new object types | +| `go/` | Go Feature Server — entry point, serving path, online store interface, build commands | +| `infra/feast-operator/` | Feast Operator — CRD spec, reconcile loop, RBAC markers, dev workflow | + +For testing patterns and debugging, also read `skills/feast-testing/SKILL.md`. + +## When making any component change + +- **Unit tests**: add or update tests in `sdk/python/tests/unit/infra//` +- **Integration tests**: run `make test-python-integration-local`; add a universal test case in `sdk/python/tests/integration/` if the change affects retrieval or materialization behavior +- **Protos**: if you add a field to a proto message, recompile with `make protos` and update serialization helpers in `proto_registry_utils.py` +- **Both SDKs**: if the change affects online serving, check whether the Go server (`go/`) also needs updating +- **Skills/Rules**: if the change introduces new patterns, interfaces, or conventions that agents should follow, update the relevant section in `skills/feast-architecture/SKILL.md` (and `skills/feast-testing/SKILL.md` if testing patterns changed) + +## Documentation — where to add/update + +| Change type | Doc location | Also update | +|---|---|---| +| New **online store** | `docs/reference/online-stores/.md` (copy an existing one as template) | `docs/reference/online-stores/README.md`, `docs/SUMMARY.md` (under "Online stores") | +| New **offline store** | `docs/reference/offline-stores/.md` | `docs/reference/offline-stores/README.md`, `docs/reference/offline-stores/overview.md`, `docs/SUMMARY.md` | +| New **registry backend** | `docs/reference/registries/.md` | `docs/SUMMARY.md` | +| Config option change | `docs/reference/feature-store-yaml.md` | — | +| New CLI flag or command | `docs/reference/feast-cli-commands.md` | — | +| How-to / integration guide | `docs/how-to-guides/customizing-feast/` or `docs/how-to-guides/` | `docs/SUMMARY.md` | +| Architecture / concept | `docs/getting-started/architecture/` or `docs/getting-started/components/` | `docs/SUMMARY.md` | +| Blog post | `/infra/website/docs/blog/` (NOT `docs/blog/`) | — | + +All `docs/` pages are rendered by GitBook via `docs/SUMMARY.md`. Any new page must be added to `SUMMARY.md` or it won't appear in the site navigation. diff --git a/.claude/rules/feast-skills-maintenance.md b/.claude/rules/feast-skills-maintenance.md new file mode 100644 index 00000000000..8be40b3563b --- /dev/null +++ b/.claude/rules/feast-skills-maintenance.md @@ -0,0 +1,28 @@ +--- +paths: + - skills/** + - AGENTS.md + - .cursor/rules/** + - .claude/rules/** +--- + +## When editing skills or rules + +Skills and rules are only useful if they accurately reflect the real codebase. Before finalising any skill/rule edit: + +**Verify against source code:** +- Command examples (lint, test, type-check) — confirm they still match `Makefile` targets and `pyproject.toml` +- File paths and class names — confirm they exist in the repo +- Interface signatures (e.g. `OnlineStore`, `OfflineStore`, `BaseRegistry`) — confirm against the actual base class files +- Config field names — confirm against `RepoConfig` and `FeastConfigBaseModel` subclasses in `sdk/python/feast/repo_config.py` + +**Keep scope consistent:** +- `AGENTS.md` — entry point only; commands, skills table, code style. Max ~120 lines. +- `skills/feast-architecture/SKILL.md` — how each component works internally; data flows; adding new backends +- `skills/feast-testing/SKILL.md` — how to run, write, and debug tests +- `skills/feast-dev/SKILL.md` — contributor workflow; setup; Docker; docs locations; PR process +- `skills/feast-user-guide/SKILL.md` — how to use Feast as an end user; feature definitions; retrieval; RAG +- `.cursor/rules/feast-components.mdc` / `.claude/rules/feast-components.md` — component checklist (tests, docs, skills); keep in sync with each other + +**Keep the two rule files in sync:** +`.cursor/rules/feast-components.mdc` and `.claude/rules/feast-components.md` contain the same content with only different frontmatter (`globs:` vs `paths:`). Any content change must be applied to both. diff --git a/.claude/skills/feast-architecture/SKILL.md b/.claude/skills/feast-architecture/SKILL.md new file mode 120000 index 00000000000..2075b8d0450 --- /dev/null +++ b/.claude/skills/feast-architecture/SKILL.md @@ -0,0 +1 @@ +../../../skills/feast-architecture/SKILL.md \ No newline at end of file diff --git a/.claude/skills/feast-dev/SKILL.md b/.claude/skills/feast-dev/SKILL.md new file mode 120000 index 00000000000..ba44334bd0b --- /dev/null +++ b/.claude/skills/feast-dev/SKILL.md @@ -0,0 +1 @@ +../../../skills/feast-dev/SKILL.md \ No newline at end of file diff --git a/.claude/skills/feast-testing/SKILL.md b/.claude/skills/feast-testing/SKILL.md new file mode 120000 index 00000000000..9af0ba0de43 --- /dev/null +++ b/.claude/skills/feast-testing/SKILL.md @@ -0,0 +1 @@ +../../../skills/feast-testing/SKILL.md \ No newline at end of file diff --git a/.claude/skills/feast-user-guide/SKILL.md b/.claude/skills/feast-user-guide/SKILL.md new file mode 120000 index 00000000000..9fd50297875 --- /dev/null +++ b/.claude/skills/feast-user-guide/SKILL.md @@ -0,0 +1 @@ +../../../skills/feast-user-guide/SKILL.md \ No newline at end of file diff --git a/.cursor/rules/feast-components.mdc b/.cursor/rules/feast-components.mdc new file mode 100644 index 00000000000..a474f00fc47 --- /dev/null +++ b/.cursor/rules/feast-components.mdc @@ -0,0 +1,40 @@ +--- +description: Component-level guidance for Feast subsystems +globs: sdk/python/feast/infra/online_stores/**,sdk/python/feast/infra/offline_stores/**,sdk/python/feast/infra/registry/**,sdk/python/tests/unit/infra/**,go/**,infra/feast-operator/** +alwaysApply: false +--- + +Read `skills/feast-architecture/SKILL.md` for the relevant component section: + +| Working in… | Read section | +|---|---| +| `online_stores/` | Online Store — config pattern, entity key serialization, async support, registration | +| `offline_stores/` | Offline Store — interface, PIT join, pull_latest, adding a new backend | +| `infra/registry/` | Registry — proto vs SQL backend, caching, adding new object types | +| `go/` | Go Feature Server — entry point, serving path, online store interface, build commands | +| `infra/feast-operator/` | Feast Operator — CRD spec, reconcile loop, RBAC markers, dev workflow | + +For testing patterns and debugging, also read `skills/feast-testing/SKILL.md`. + +## When making any component change + +- **Unit tests**: add or update tests in `sdk/python/tests/unit/infra//` +- **Integration tests**: run `make test-python-integration-local`; add a universal test case in `sdk/python/tests/integration/` if the change affects retrieval or materialization behavior +- **Protos**: if you add a field to a proto message, recompile with `make protos` and update serialization helpers in `proto_registry_utils.py` +- **Both SDKs**: if the change affects online serving, check whether the Go server (`go/`) also needs updating +- **Skills/Rules**: if the change introduces new patterns, interfaces, or conventions that agents should follow, update the relevant section in `skills/feast-architecture/SKILL.md` (and `skills/feast-testing/SKILL.md` if testing patterns changed) + +## Documentation — where to add/update + +| Change type | Doc location | Also update | +|---|---|---| +| New **online store** | `docs/reference/online-stores/.md` (copy an existing one as template) | `docs/reference/online-stores/README.md`, `docs/SUMMARY.md` (under "Online stores") | +| New **offline store** | `docs/reference/offline-stores/.md` | `docs/reference/offline-stores/README.md`, `docs/reference/offline-stores/overview.md`, `docs/SUMMARY.md` | +| New **registry backend** | `docs/reference/registries/.md` | `docs/SUMMARY.md` | +| Config option change | `docs/reference/feature-store-yaml.md` | — | +| New CLI flag or command | `docs/reference/feast-cli-commands.md` | — | +| How-to / integration guide | `docs/how-to-guides/customizing-feast/` or `docs/how-to-guides/` | `docs/SUMMARY.md` | +| Architecture / concept | `docs/getting-started/architecture/` or `docs/getting-started/components/` | `docs/SUMMARY.md` | +| Blog post | `/infra/website/docs/blog/` (NOT `docs/blog/`) | — | + +All `docs/` pages are rendered by GitBook via `docs/SUMMARY.md`. Any new page must be added to `SUMMARY.md` or it won't appear in the site navigation. diff --git a/.cursor/rules/feast-skills-maintenance.mdc b/.cursor/rules/feast-skills-maintenance.mdc new file mode 100644 index 00000000000..588cce66b6d --- /dev/null +++ b/.cursor/rules/feast-skills-maintenance.mdc @@ -0,0 +1,26 @@ +--- +description: Guidance for keeping skills and rules accurate and up to date +globs: skills/**,AGENTS.md,.cursor/rules/**,.claude/rules/** +alwaysApply: false +--- + +## When editing skills or rules + +Skills and rules are only useful if they accurately reflect the real codebase. Before finalising any skill/rule edit: + +**Verify against source code:** +- Command examples (lint, test, type-check) — confirm they still match `Makefile` targets and `pyproject.toml` +- File paths and class names — confirm they exist in the repo +- Interface signatures (e.g. `OnlineStore`, `OfflineStore`, `BaseRegistry`) — confirm against the actual base class files +- Config field names — confirm against `RepoConfig` and `FeastConfigBaseModel` subclasses in `sdk/python/feast/repo_config.py` + +**Keep scope consistent:** +- `AGENTS.md` — entry point only; commands, skills table, code style. Max ~120 lines. +- `skills/feast-architecture/SKILL.md` — how each component works internally; data flows; adding new backends +- `skills/feast-testing/SKILL.md` — how to run, write, and debug tests +- `skills/feast-dev/SKILL.md` — contributor workflow; setup; Docker; docs locations; PR process +- `skills/feast-user-guide/SKILL.md` — how to use Feast as an end user; feature definitions; retrieval; RAG +- `.cursor/rules/feast-components.mdc` / `.claude/rules/feast-components.md` — component checklist (tests, docs, skills); keep in sync with each other + +**Keep the two rule files in sync:** +`.cursor/rules/feast-components.mdc` and `.claude/rules/feast-components.md` contain the same content with only different frontmatter (`globs:` vs `paths:`). Any content change must be applied to both. diff --git a/.gitbook.yaml b/.gitbook.yaml index bbdd0c57e3b..8441cf23dd7 100644 --- a/.gitbook.yaml +++ b/.gitbook.yaml @@ -6,3 +6,6 @@ structure: redirects: reference/telemetry: ./reference/usage.md quickstart: ./getting-started/quickstart.md + reference/feature-store-yaml: ./reference/feature-repository/feature-store-yaml.md + reference/feast-ignore: ./reference/feature-repository/feast-ignore.md + reference/feature-repository: ./reference/feature-repository/README.md diff --git a/.github/actions/get-semantic-release-version/action.yml b/.github/actions/get-semantic-release-version/action.yml index 89f6a8f81c1..a53bc337b44 100644 --- a/.github/actions/get-semantic-release-version/action.yml +++ b/.github/actions/get-semantic-release-version/action.yml @@ -2,7 +2,7 @@ name: Get semantic release version description: "" inputs: custom_version: # Optional input for a custom version - description: "Custom version to publish (e.g., v1.2.3) -- only edit if you know what you are doing" + description: "Custom version to publish (e.g., v1.2.3 or v1.2.3.dev4) -- only edit if you know what you are doing" required: false token: description: "Personal Access Token" @@ -10,10 +10,10 @@ inputs: default: "" outputs: release_version: - description: "The release version to use (e.g., v1.2.3)" + description: "The release version to use (e.g., v1.2.3 or v1.2.3.dev4)" value: ${{ steps.get_release_version.outputs.release_version }} version_without_prefix: - description: "The release version to use without 'v' (e.g., 1.2.3)" + description: "The release version to use without 'v' (e.g., 1.2.3 or 1.2.3.dev4)" value: ${{ steps.get_release_version_without_prefix.outputs.version_without_prefix }} highest_semver_tag: description: "The highest semantic version tag without the 'v' prefix (e.g., 1.2.3)" @@ -32,10 +32,10 @@ runs: GIT_COMMITTER_EMAIL: feast-ci-bot@willem.co run: | if [[ -n "${{ inputs.custom_version }}" ]]; then - VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+$" + VERSION_REGEX="^v[0-9]+\.[0-9]+\.[0-9]+(\.dev[0-9]+)?$" echo "Using custom version: ${{ inputs.custom_version }}" if [[ ! "${{ inputs.custom_version }}" =~ $VERSION_REGEX ]]; then - echo "Error: custom_version must match semantic versioning (e.g., v1.2.3)." + echo "Error: custom_version must match semantic versioning (e.g., v1.2.3 or v1.2.3.dev4)." exit 1 fi echo "::set-output name=release_version::${{ inputs.custom_version }}" @@ -84,4 +84,4 @@ runs: run: | echo $RELEASE_VERSION echo $VERSION_WITHOUT_PREFIX - echo $HIGHEST_SEMVER_TAG \ No newline at end of file + echo $HIGHEST_SEMVER_TAG diff --git a/.github/fork_workflows/fork_pr_integration_tests_aws.yml b/.github/fork_workflows/fork_pr_integration_tests_aws.yml index d8a547f5359..6722e225b91 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_aws.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_aws.yml @@ -40,11 +40,11 @@ jobs: architecture: x64 - name: Setup Go id: setup-go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: 1.18.0 - name: Set up AWS SDK - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml index 563111727b9..c6810e1dac2 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_gcp.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_gcp.yml @@ -40,15 +40,15 @@ jobs: architecture: x64 - name: Setup Go id: setup-go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: 1.18.0 - name: Authenticate to Google Cloud - uses: 'google-github-actions/auth@v1' + uses: 'google-github-actions/auth@v2' with: credentials_json: '${{ secrets.GCP_SA_KEY }}' - name: Set up gcloud SDK - uses: google-github-actions/setup-gcloud@v1 + uses: google-github-actions/setup-gcloud@v2 with: project_id: ${{ secrets.GCP_PROJECT_ID }} - name: Use gcloud CLI diff --git a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml index 1983189b4ee..0db580ce7db 100644 --- a/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml +++ b/.github/fork_workflows/fork_pr_integration_tests_snowflake.yml @@ -40,7 +40,7 @@ jobs: architecture: x64 - name: Setup Go id: setup-go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: 1.18.0 - name: Install the latest version of uv @@ -72,7 +72,7 @@ jobs: SNOWFLAKE_CI_WAREHOUSE: ${{ secrets.SNOWFLAKE_CI_WAREHOUSE }} # Run only Snowflake BigQuery and File tests without dynamo and redshift tests. run: | - pytest -n 8 --cov=./ --cov-report=xml --color=yes sdk/python/tests --integration --durations=5 --timeout=1200 --timeout_method=thread -k "Snowflake and not dynamo and not Redshift and not Bigquery and not gcp and not minio_registry" + pytest -n 8 --cov=./ --cov-report=xml --color=yes sdk/python/tests --integration --durations=5 --timeout=1200 --timeout_method=thread -k "(Snowflake or snowflake_registry) and not dynamo and not Redshift and not Bigquery and not gcp and not minio_registry" pytest -n 8 --cov=./ --cov-report=xml --color=yes sdk/python/tests --integration --durations=5 --timeout=1200 --timeout_method=thread -k "File and not dynamo and not Redshift and not Bigquery and not gcp and not minio_registry" - name: Minimize uv cache run: uv cache prune --ci diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 40986a87db9..48bb592ed84 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,7 +11,7 @@ # What this PR does / why we need it: # Which issue(s) this PR fixes: @@ -20,6 +20,16 @@ Outline what you're doing Usage: `Fixes #`, or `Fixes (paste link of issue)`. --> +# Checks +- [ ] I've made sure the tests are passing. +- [ ] My commits are signed off (`git commit -s`) +- [ ] My PR title follows [conventional commits](https://www.conventionalcommits.org/) format + +## Testing Strategy +- [ ] Unit tests +- [ ] Integration tests +- [ ] Manual tests +- [ ] Testing is not required for this change # Misc |manages| Registry + Operator -->|manages| OnlineServer + OnlineServer -->|reads/writes| Redis + OnlineServer -->|reads metadata| Registry + MaterializationJob -->|reads source data| OfflineStore + MaterializationJob -->|writes features| Redis + NotebookPod -->|online features REST| OnlineServer + NotebookPod -->|metadata gRPC| Registry + + Client(["Client / ML Service"]) -->|REST port 6566| OnlineServer + + style Kubernetes fill:#f0f4ff,stroke:#3366cc,color:#000 + style BackingStores fill:#fafafa,stroke:#999,color:#000 + style Operator fill:#e8f5e9,stroke:#388e3c,color:#000 + style Registry fill:#fff3e0,stroke:#f57c00,color:#000 + style OnlineServer fill:#e3f2fd,stroke:#1976d2,color:#000 + style Redis fill:#fce4ec,stroke:#c62828,color:#000 + style OfflineStore fill:#f3e5f5,stroke:#7b1fa2,color:#000 + style MaterializationJob fill:#fff8e1,stroke:#f9a825,color:#000 + style NotebookPod fill:#e8f5e9,stroke:#388e3c,color:#000 +``` + +### Components + +| Component | Configuration | Notes | +|---|---|---| +| **Feast Operator** | Default install | Manages all Feast CRDs | +| **Registry** | REST, 1 replica | Single point of metadata | +| **Online Feature Server** | 1 replica, no autoscaling | Serves online features | +| **Online Store** | Redis standalone (example) | SQLite is simplest for development; Redis for production. See [supported online stores](../reference/online-stores/README.md) for all options | +| **Offline Store** | File-based or MinIO | DuckDB or file-based for development; MinIO/S3 for production. See [supported offline stores](../reference/offline-stores/README.md) for all options | +| **Compute Engine** | In-process (default) | Suitable for small datasets and development; use Spark, Ray, or Snowflake Engine for larger workloads | + +### Sample FeatureStore CR + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: minimal-production +spec: + feastProject: my_project + services: + onlineStore: + persistence: + store: + type: redis + secretRef: + name: feast-online-store + server: + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "1" + memory: 1Gi + offlineStore: + persistence: + file: + type: duckdb # Use type: file for generic file-based; swap for S3/MinIO in production + pvc: + create: + storageClassName: standard + resources: + requests: + storage: 10Gi + mountPath: /data/offline + registry: + local: + server: + restAPI: true + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi +``` + +### Limitations + +{% hint style="warning" %} +* **No high availability** — a single replica failure causes downtime +* **No automatic failover** — manual intervention required on failure +* **Manual scaling** — no HPA configured +* **Limited security** — no TLS, no ingress, no RBAC by default +{% endhint %} + +--- + +## 2. Standard Production (Recommended) + +### When to use + +* Most production ML workloads +* Teams with moderate traffic that need reliability +* Environments that require TLS, RBAC, and automated scaling + +### Architecture + +```mermaid +graph TD + Client(["Client / ML Service"]) -->|HTTPS| Ingress + + subgraph Kubernetes["Kubernetes"] + Ingress["Ingress Controller
(TLS termination)"] + Operator["Feast Operator"] + MaterializationJob["Materialization Job
(CronJob / batchEngine)"] + NotebookPod(["Notebook / Training Pod
(Feast SDK — remote online, offline, registry)"]) + + subgraph FeastDeployment["Feast Deployment (HPA autoscaled — all containers scale together)"] + Registry["Registry Server"] + OnlineServer["Online Feature Server"] + OfflineServer["Offline Feature Server"] + end + + Ingress -->|port 6566| OnlineServer + Operator -->|manages| Registry + Operator -->|manages| OnlineServer + Operator -->|manages| OfflineServer + OnlineServer -->|reads metadata| Registry + OfflineServer -->|reads metadata| Registry + MaterializationJob -->|reads metadata| Registry + NotebookPod -->|online features REST| OnlineServer + NotebookPod -->|historical features Arrow Flight| OfflineServer + NotebookPod -->|metadata gRPC| Registry + end + + subgraph BackingStores["Backing Stores (inside or outside Kubernetes)"] + RedisCluster["Online Store
(e.g. Redis Cluster, DynamoDB, etc.)"] + OfflineStore["Offline Store
(e.g. PostgreSQL, Redshift, BigQuery, etc.)"] + end + + OnlineServer -->|reads/writes| RedisCluster + MaterializationJob -->|writes features| RedisCluster + OfflineServer -->|historical features| OfflineStore + MaterializationJob -->|reads source data| OfflineStore + + style Kubernetes fill:#f0f4ff,stroke:#3366cc,color:#000 + style FeastDeployment fill:#e8f5e9,stroke:#388e3c,color:#000 + style BackingStores fill:#fafafa,stroke:#999,color:#000 + style Ingress fill:#fff9c4,stroke:#f9a825,color:#000 + style Operator fill:#e8f5e9,stroke:#388e3c,color:#000 + style Registry fill:#fff3e0,stroke:#f57c00,color:#000 + style OnlineServer fill:#e3f2fd,stroke:#1976d2,color:#000 + style OfflineServer fill:#ede7f6,stroke:#512da8,color:#000 + style RedisCluster fill:#fce4ec,stroke:#c62828,color:#000 + style OfflineStore fill:#f3e5f5,stroke:#7b1fa2,color:#000 + style MaterializationJob fill:#fff8e1,stroke:#f9a825,color:#000 + style NotebookPod fill:#e8f5e9,stroke:#388e3c,color:#000 +``` + +### Components + +**Core** + +| Component | Configuration | Notes | +|---|---|---| +| **Feast Operator** | Default install | Manages all Feast CRDs | +| **Registry** | SQL-backed (PostgreSQL) | Database-backed for consistency and concurrent access | +| **Online Feature Server** | HPA (min 2 replicas, max based on peak load) | Separate container — serves online features from the online store | +| **Offline Feature Server** | Scales with the same Deployment | Separate container — serves historical features and materialization source reads from the offline store | + +**Storage** + +| Component | Configuration | Notes | +|---|---|---| +| **Online Store** | Redis Cluster (example) | Multi-node for availability and low latency; other production stores are also supported — see [supported online stores](../reference/online-stores/README.md) | +| **Offline Store** | PostgreSQL (example) | Platform-agnostic DB-backed store; use Redshift/Athena for AWS, BigQuery for GCP, Spark for S3/MinIO pipelines — see [supported offline stores](../reference/offline-stores/README.md) for all options | +| **Compute Engine** | Spark, Ray (KubeRay), or Snowflake Engine | Distributed compute for materialization and historical retrieval at scale | + +**Networking & Security** + +| Component | Configuration | Notes | +|---|---|---| +| **Ingress** | TLS-terminated | Secure external access | +| **RBAC** | Kubernetes RBAC | Namespace-scoped permissions | +| **Secrets** | Kubernetes Secrets + `${ENV_VAR}` substitution | Store credentials via `secretRef` / `envFrom` in the FeatureStore CR; inject into `feature_store.yaml` with [environment variable syntax](./running-feast-in-production.md#5-using-environment-variables-in-your-yaml-configuration) | + +### Sample FeatureStore CR + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: standard-production +spec: + feastProject: my_project + authz: + kubernetes: + roles: + - feast-admin-role + - feast-user-role + batchEngine: + configMapRef: + name: feast-batch-engine + services: + scaling: + autoscaling: + minReplicas: 2 + maxReplicas: 10 # Set based on your peak load + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + podDisruptionBudgets: + maxUnavailable: 1 + onlineStore: + persistence: + store: + type: redis + secretRef: + name: feast-online-store + server: + resources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi + offlineStore: + persistence: + store: + type: postgres + secretRef: + name: feast-offline-store + server: + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "1" + memory: 1Gi + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-registry-store + server: + restAPI: true + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "1" + memory: 1Gi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: feast-batch-engine +data: + config: | + type: ray + address: auto # KubeRay cluster address; replace with explicit URL if not using auto-discovery +``` + +{% hint style="success" %} +**Key features:** + +* **High availability** — multi-replica deployment with auto-injected pod anti-affinity and topology spread constraints +* **Scalable serving** — HPA adjusts the shared deployment replicas (all services scale together) based on demand +* **Secure external access** — TLS-terminated ingress with RBAC +* **Persistent storage** — Online Store (Redis Cluster shown as example; see [supported online stores](../reference/online-stores/README.md) for all options) + Offline Store (PostgreSQL shown as example; see [supported offline stores](../reference/offline-stores/README.md) for all options) for durability + +See [Horizontal Scaling with the Feast Operator](./scaling-feast.md#horizontal-scaling-with-the-feast-operator) for full scaling configuration details. +{% endhint %} + +--- + +## 3. Enterprise Production + +### When to use + +* Large organizations with multiple ML teams +* Multi-tenant environments requiring strict isolation +* High-scale deployments with governance, compliance, and SLA requirements + +### Architecture — Isolated Registries (per namespace) + +Each team gets its own registry and online feature server in a dedicated namespace. This provides the strongest isolation but has notable trade-offs: feature discovery is siloed per team (no cross-project visibility), and each registry requires its own [Feast UI](../reference/alpha-web-ui.md) deployment — you cannot view multiple projects in a single UI instance. + +```mermaid +graph TD + Client(["Clients / ML Services"]) -->|HTTPS| Gateway + + subgraph Kubernetes["Kubernetes"] + Gateway["API Gateway / Ingress
(TLS + rate limiting)"] + Operator["Feast Operator
(cluster-scoped)"] + + subgraph NamespaceA["Namespace A — Team A"] + subgraph DeployA["Feast Deployment (HPA autoscaled)"] + RegistryA["Registry Server"] + OnlineServerA["Online Feature Server"] + OfflineServerA["Offline Feature Server"] + end + NotebookPodA(["Notebook — Team A
(Feast SDK)"]) + MaterializationJobA["Materialization Job"] + end + + subgraph NamespaceB["Namespace B — Team B"] + subgraph DeployB["Feast Deployment (HPA autoscaled)"] + RegistryB["Registry Server"] + OnlineServerB["Online Feature Server"] + OfflineServerB["Offline Feature Server"] + end + NotebookPodB(["Notebook — Team B
(Feast SDK)"]) + MaterializationJobB["Materialization Job"] + end + + Gateway -->|port 6566| OnlineServerA + Gateway -->|port 6566| OnlineServerB + Operator -->|manages| RegistryA + Operator -->|manages| OnlineServerA + Operator -->|manages| OfflineServerA + Operator -->|manages| RegistryB + Operator -->|manages| OnlineServerB + Operator -->|manages| OfflineServerB + OnlineServerA -->|metadata| RegistryA + OnlineServerB -->|metadata| RegistryB + OfflineServerA -->|metadata| RegistryA + OfflineServerB -->|metadata| RegistryB + NotebookPodA -.->|online REST| OnlineServerA + NotebookPodA -.->|Arrow Flight| OfflineServerA + NotebookPodA -.->|metadata| RegistryA + NotebookPodB -.->|online REST| OnlineServerB + NotebookPodB -.->|Arrow Flight| OfflineServerB + NotebookPodB -.->|metadata| RegistryB + MaterializationJobA -->|metadata| RegistryA + MaterializationJobB -->|metadata| RegistryB + end + + subgraph BackingStores["Backing Stores (inside or outside Kubernetes)"] + RedisA["Online Store — Team A
(e.g. Redis, DynamoDB, etc.)"] + RedisB["Online Store — Team B
(e.g. Redis, DynamoDB, etc.)"] + OfflineStore["Offline Store — shared instance
(e.g. BigQuery, Redshift, etc.)
isolated via per-team datasets / schemas"] + end + + subgraph Observability["Observability Stack"] + OTel["OpenTelemetry
(traces + metrics)"] + Prometheus["Prometheus"] + Grafana["Grafana"] + Jaeger["Jaeger"] + end + + OnlineServerA -->|reads/writes| RedisA + OnlineServerB -->|reads/writes| RedisB + OfflineServerA -->|Team A dataset| OfflineStore + OfflineServerB -->|Team B dataset| OfflineStore + MaterializationJobA -->|Team A data| OfflineStore + MaterializationJobA -->|writes| RedisA + MaterializationJobB -->|Team B data| OfflineStore + MaterializationJobB -->|writes| RedisB + + style Kubernetes fill:#f0f4ff,stroke:#3366cc,color:#000 + style NamespaceA fill:#e8f5e9,stroke:#388e3c,color:#000 + style NamespaceB fill:#e3f2fd,stroke:#1976d2,color:#000 + style DeployA fill:#c8e6c9,stroke:#2e7d32,color:#000 + style DeployB fill:#bbdefb,stroke:#1565c0,color:#000 + style BackingStores fill:#fafafa,stroke:#999,color:#000 + style Observability fill:#fff3e0,stroke:#f57c00,color:#000 + style Gateway fill:#fff9c4,stroke:#f9a825,color:#000 + style Operator fill:#e8f5e9,stroke:#388e3c,color:#000 +``` + +### Architecture — Shared Registry (cross-namespace) + +Alternatively, a single centralized registry server can serve multiple tenant namespaces. Tenant online feature servers connect to the shared registry via the [Remote Registry](../reference/registries/remote.md) gRPC client. This reduces operational overhead, enables cross-team feature discovery, and allows a single [Feast UI](../reference/alpha-web-ui.md) deployment to browse all projects — while Feast [permissions](#feast-permissions-and-rbac) enforce tenant isolation at the data level. + +```mermaid +graph TD + Client(["Clients / ML Services"]) -->|HTTPS| Gateway + + subgraph Kubernetes["Kubernetes"] + Gateway["API Gateway / Ingress
(TLS + rate limiting)"] + + subgraph SharedInfra["Shared Infrastructure Namespace"] + Operator["Feast Operator
(cluster-scoped)"] + subgraph SharedDeploy["Feast Deployment (3 replicas)"] + SharedRegistry["Registry Server
(gRPC + REST)"] + end + SharedDB[("SQL Database
(PostgreSQL)")] + SharedRegistry -->|persists| SharedDB + end + + subgraph NamespaceA["Namespace A — Team A"] + subgraph DeployA2["Feast Deployment (HPA autoscaled)"] + OnlineServerA["Online Feature Server"] + OfflineServerA["Offline Feature Server"] + end + NotebookPodA(["Notebook — Team A
(Feast SDK)"]) + MaterializationJobA["Materialization Job"] + ConfigA["registry_type: remote
path: shared-registry:6570"] + end + + subgraph NamespaceB["Namespace B — Team B"] + subgraph DeployB2["Feast Deployment (HPA autoscaled)"] + OnlineServerB["Online Feature Server"] + OfflineServerB["Offline Feature Server"] + end + NotebookPodB(["Notebook — Team B
(Feast SDK)"]) + MaterializationJobB["Materialization Job"] + ConfigB["registry_type: remote
path: shared-registry:6570"] + end + + Gateway -->|port 6566| OnlineServerA + Gateway -->|port 6566| OnlineServerB + OnlineServerA -->|gRPC port 6570| SharedRegistry + OnlineServerB -->|gRPC port 6570| SharedRegistry + OfflineServerA -->|gRPC port 6570| SharedRegistry + OfflineServerB -->|gRPC port 6570| SharedRegistry + Operator -->|manages| SharedRegistry + Operator -->|manages| OnlineServerA + Operator -->|manages| OfflineServerA + Operator -->|manages| OnlineServerB + Operator -->|manages| OfflineServerB + NotebookPodA -.->|online REST| OnlineServerA + NotebookPodA -.->|Arrow Flight| OfflineServerA + NotebookPodA -.->|metadata| SharedRegistry + NotebookPodB -.->|online REST| OnlineServerB + NotebookPodB -.->|Arrow Flight| OfflineServerB + NotebookPodB -.->|metadata| SharedRegistry + MaterializationJobA -->|gRPC port 6570| SharedRegistry + MaterializationJobB -->|gRPC port 6570| SharedRegistry + end + + subgraph BackingStores["Backing Stores (inside or outside Kubernetes)"] + RedisA["Online Store — Team A
(e.g. Redis, DynamoDB, etc.)"] + RedisB["Online Store — Team B
(e.g. Redis, DynamoDB, etc.)"] + OfflineStore["Offline Store — shared instance
(e.g. BigQuery, Redshift, etc.)
isolated via per-team datasets / schemas"] + end + + OnlineServerA -->|reads/writes| RedisA + OnlineServerB -->|reads/writes| RedisB + OfflineServerA -->|Team A dataset| OfflineStore + OfflineServerB -->|Team B dataset| OfflineStore + MaterializationJobA -->|Team A data| OfflineStore + MaterializationJobA -->|writes| RedisA + MaterializationJobB -->|Team B data| OfflineStore + MaterializationJobB -->|writes| RedisB + + style Kubernetes fill:#f0f4ff,stroke:#3366cc,color:#000 + style SharedInfra fill:#fff3e0,stroke:#f57c00,color:#000 + style SharedDeploy fill:#ffe0b2,stroke:#e65100,color:#000 + style NamespaceA fill:#e8f5e9,stroke:#388e3c,color:#000 + style NamespaceB fill:#e3f2fd,stroke:#1976d2,color:#000 + style DeployA2 fill:#c8e6c9,stroke:#2e7d32,color:#000 + style DeployB2 fill:#bbdefb,stroke:#1565c0,color:#000 + style BackingStores fill:#fafafa,stroke:#999,color:#000 + style Gateway fill:#fff9c4,stroke:#f9a825,color:#000 + style Operator fill:#e8f5e9,stroke:#388e3c,color:#000 + style OfflineStore fill:#f3e5f5,stroke:#7b1fa2,color:#000 +``` + +**Shared registry client configuration** — each tenant's `feature_store.yaml` points to the centralized registry: + +```yaml +registry: + registry_type: remote + path: shared-registry.feast-system.svc.cluster.local:6570 +``` + +{% hint style="info" %} +**Shared vs isolated registries:** + +| | Shared Registry | Isolated Registries | +|---|---|---| +| **Feature discovery** | Cross-team — all projects visible | Siloed — each team sees only its own | +| **Feast UI** | Single deployment serves all projects | Separate UI deployment per registry | +| **Isolation** | Logical (Feast permissions + tags) | Physical (separate metadata stores) | +| **Operational cost** | Lower — one registry to manage | Higher — N registries to maintain | +| **Best for** | Feature reuse, shared ML platform | Regulatory/compliance separation | + +Use a shared registry when teams need to discover and reuse features across projects, and rely on Feast permissions for access control. Use isolated registries when regulatory or compliance requirements demand physical separation of metadata. +{% endhint %} + +### Components + +**Multi-tenancy** + +| Aspect | Configuration | Notes | +|---|---|---| +| **Isolation model** | Namespace-per-team | Physical isolation via Kubernetes namespaces | +| **Registry strategy** | Shared (remote) or isolated (per-namespace) | See architecture variants above | +| **Network boundaries** | NetworkPolicy enforced | Cross-namespace traffic denied by default (allow-listed for shared registry) | + +**Storage** + +| Component | Configuration | Notes | +|---|---|---| +| **Online Store** | Managed Redis / DynamoDB / Elasticsearch | Cloud-managed, per-tenant instances; see [supported online stores](../reference/online-stores/README.md) for all options | +| **Offline Store** | External data warehouse (Snowflake, BigQuery) | Shared or per-tenant access controls; see [supported offline stores](../reference/offline-stores/README.md) for all options | + +**Scaling** + +| Component | Configuration | Notes | +|---|---|---| +| **FeatureStore Deployment** | HPA + Cluster Autoscaler | All services (Online Feature Server, Registry, Offline Feature Server) scale together per tenant; set `maxReplicas` based on your peak load. Independent scaling across tenants. | +| **Cluster** | Multi-zone node pools | Zone-aware scheduling with auto-injected topology spread constraints | + +**Security** + +| Component | Configuration | Notes | +|---|---|---| +| **Authentication** | OIDC via Keycloak | Centralized identity provider | +| **Authorization** | Feast permissions + Kubernetes RBAC | See [Permissions and RBAC](#feast-permissions-and-rbac) below | +| **Network** | NetworkPolicies per namespace | Microsegmentation | +| **Secrets** | Kubernetes Secrets (`secretRef` / `envFrom`) | Credentials injected via FeatureStore CR; use Kubernetes-native tooling (e.g. External Secrets Operator) to sync from external vaults if needed | + +**Observability** + +| Component | Purpose | Notes | +|---|---|---| +| **[OpenTelemetry](../getting-started/components/open-telemetry.md)** | Traces + metrics export | Built-in Feast integration; emits spans for feature retrieval, materialization, and registry operations | +| **Prometheus** | Metrics collection | Collects OpenTelemetry metrics from Online Feature Server + Online Store | +| **Grafana** | Dashboards + traces | Per-tenant and aggregate views; can display OpenTelemetry traces via Tempo or Jaeger data source | +| **Jaeger** | Distributed tracing | Visualize OpenTelemetry traces for request latency analysis and debugging | + +**Reliability & Disaster Recovery** + +| Aspect | Configuration | Notes | +|---|---|---| +| **PodDisruptionBudgets** | Configured per deployment | Protects against voluntary disruptions | +| **Multi-zone** | Topology spread constraints | Auto-injected by operator when scaling; survives single zone failures | +| **Backup / Restore** | See recovery priority below | Strategy depends on component criticality | + +**Recovery priority guidance** + +Not all Feast components carry the same recovery urgency. The table below ranks components by restoration priority and provides guidance for **RPO** (Recovery Point Objective — maximum acceptable data loss) and **RTO** (Recovery Time Objective — maximum acceptable downtime). Specific targets depend on your backing store SLAs and organizational requirements. + +| Priority | Component | RPO guidance | RTO guidance | Rationale | +|---|---|---|---|---| +| 1 — Critical | **Registry DB** (PostgreSQL / MySQL) | Minutes (continuous replication or frequent backups) | Minutes (failover to standby) | Contains all feature definitions and metadata; without it, no service can resolve features | +| 2 — High | **Online Store** (Redis / DynamoDB) | Reconstructible via materialization | Minutes to hours (depends on data volume) | Can be fully rebuilt by re-running materialization from the offline store; no unique data to lose | +| 3 — Medium | **Offline Store** (Redshift / BigQuery) | Per data warehouse SLA | Per data warehouse SLA | Source of truth for historical data; typically managed by the cloud provider with built-in replication | +| 4 — Low | **Feast Operator + CRDs** | N/A (declarative, stored in Git) | Minutes (re-apply manifests) | Stateless; redeployable from version-controlled manifests | + +{% hint style="info" %} +**Key insight:** The online store is *reconstructible* — it can always be rebuilt from the offline store by re-running materialization. This means its RPO is effectively zero (no unique data to lose), but RTO depends on how long full materialization takes for your dataset volume. For large datasets, consider maintaining Redis persistence (RDB snapshots or AOF) to reduce recovery time. +{% endhint %} + +**Backup recommendations by topology** + +| Topology | Registry | Online Store | Offline Store | +|---|---|---|---| +| **Minimal** | Manual file backups; accept downtime on failure | Not backed up (re-materialize) | N/A (file-based) | +| **Standard** | Automated PostgreSQL backups (daily + WAL archiving) | Redis RDB snapshots or AOF persistence | Per cloud provider SLA | +| **Enterprise** | Managed DB replication (multi-AZ); cross-region replicas for DR | Managed Redis with automatic failover (ElastiCache Multi-AZ, Memorystore HA) | Managed warehouse replication (Redshift cross-region, BigQuery cross-region) | + +### Sample FeatureStore CR (per tenant) + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: team-a-production + namespace: team-a +spec: + feastProject: team_a + authz: + oidc: + secretRef: + name: feast-oidc-secret # Secret keys: client_id, client_secret, auth_discovery_url + batchEngine: + configMapRef: + name: feast-batch-engine + services: + scaling: + autoscaling: + minReplicas: 3 + maxReplicas: 20 # Set based on your peak load + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 65 + podDisruptionBudgets: + minAvailable: 2 + onlineStore: + persistence: + store: + type: redis + secretRef: + name: feast-online-store + server: + resources: + requests: + cpu: "2" + memory: 2Gi + limits: + cpu: "4" + memory: 4Gi + offlineStore: + persistence: + store: + type: bigquery # Use snowflake.offline, redshift, etc. as alternatives — see supported offline stores + secretRef: + name: feast-offline-store + server: + resources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-registry-store + server: + restAPI: true + resources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: feast-batch-engine + namespace: team-a +data: + config: | + type: spark + spark_master: k8s://https://kubernetes.default.svc:443 + spark_app_name: feast-materialization +``` + +--- + +## Feast Permissions and RBAC + +Feast provides a built-in permissions framework that secures resources at the application level, independently of Kubernetes RBAC. Permissions are defined as Python objects in your feature repository and registered via `feast apply`. + +For full details, see the [Permission concept](../getting-started/concepts/permission.md) and [RBAC architecture](../getting-started/architecture/rbac.md) docs. + +### How it works + +```mermaid +graph LR + subgraph Client["Client Request"] + Token["Auth Token
(OIDC / K8s SA)"] + end + + subgraph Server["Feast Server"] + Extractor["Token Extractor"] + Parser["Token Parser"] + Enforcer["Policy Enforcer"] + end + + subgraph Registry["Registry"] + Permissions["Permission Objects"] + end + + Token --> Extractor + Extractor --> Parser + Parser -->|user roles/groups/ns| Enforcer + Enforcer -->|match resource + action| Permissions + Enforcer -->|allow / deny| Response(["Response"]) + + style Client fill:#e3f2fd,stroke:#1976d2,color:#000 + style Server fill:#fff3e0,stroke:#f57c00,color:#000 + style Registry fill:#e8f5e9,stroke:#388e3c,color:#000 +``` + +Permission enforcement happens on the server side (Online Feature Server, Offline Feature Server, Registry Server). There is no enforcement when using the Feast SDK with a local provider. + +### Actions + +Feast defines eight granular actions: + +| Action | Description | +|---|---| +| `CREATE` | Create a new Feast object | +| `DESCRIBE` | Read object metadata/state | +| `UPDATE` | Modify an existing object | +| `DELETE` | Remove an object | +| `READ_ONLINE` | Read from the online store | +| `READ_OFFLINE` | Read from the offline store | +| `WRITE_ONLINE` | Write to the online store | +| `WRITE_OFFLINE` | Write to the offline store | + +Convenience aliases are provided: + +| Alias | Includes | +|---|---| +| `ALL_ACTIONS` | All eight actions | +| `READ` | `READ_ONLINE` + `READ_OFFLINE` | +| `WRITE` | `WRITE_ONLINE` + `WRITE_OFFLINE` | +| `CRUD` | `CREATE` + `DESCRIBE` + `UPDATE` + `DELETE` | + +### Protected resource types + +Permissions can be applied to any of these Feast object types: + +`Project`, `Entity`, `FeatureView`, `OnDemandFeatureView`, `BatchFeatureView`, `StreamFeatureView`, `FeatureService`, `DataSource`, `ValidationReference`, `SavedDataset`, `Permission` + +The constant `ALL_RESOURCE_TYPES` includes all of the above. `ALL_FEATURE_VIEW_TYPES` includes all feature view subtypes. + +### Policy types + +| Policy | Match criteria | Use case | +|---|---|---| +| `RoleBasedPolicy(roles=[...])` | User must have at least one of the listed roles | Kubernetes RBAC roles, OIDC roles | +| `GroupBasedPolicy(groups=[...])` | User must belong to at least one of the listed groups | LDAP/OIDC group membership | +| `NamespaceBasedPolicy(namespaces=[...])` | User's service account must be in one of the listed namespaces | Kubernetes namespace-level isolation | +| `CombinedGroupNamespacePolicy(groups=[...], namespaces=[...])` | User must match at least one group **or** one namespace | Flexible cross-cutting policies | +| `AllowAll` | Always grants access | Development / unsecured resources | + +### Example: Role-based permissions + +This is the most common pattern — separate admin and read-only roles: + +```python +from feast.feast_object import ALL_RESOURCE_TYPES +from feast.permissions.action import READ, ALL_ACTIONS, AuthzedAction +from feast.permissions.permission import Permission +from feast.permissions.policy import RoleBasedPolicy + +admin_perm = Permission( + name="feast_admin_permission", + types=ALL_RESOURCE_TYPES, + policy=RoleBasedPolicy(roles=["feast-admin-role"]), + actions=ALL_ACTIONS, +) + +user_perm = Permission( + name="feast_user_permission", + types=ALL_RESOURCE_TYPES, + policy=RoleBasedPolicy(roles=["feast-user-role"]), + actions=[AuthzedAction.DESCRIBE] + READ, +) +``` + +### Example: Namespace-based isolation for multi-tenant deployments + +Use `NamespaceBasedPolicy` to restrict access based on the Kubernetes namespace of the calling service account — ideal for the shared-registry enterprise topology. + +Each team gets two permissions: full access to its own resources (matched by `team` tag), and read-only access to resources any team has explicitly published as shared (matched by `visibility: shared` tag). The two `required_tags` target **different** resources — a feature view tagged `team: team-b, visibility: shared` matches only the second permission for Team A, enabling cross-team discovery without granting write access: + +```python +from feast.feast_object import ALL_RESOURCE_TYPES +from feast.permissions.action import ALL_ACTIONS, READ, AuthzedAction +from feast.permissions.permission import Permission +from feast.permissions.policy import NamespaceBasedPolicy + +# Team A: full access to its own resources +team_a_own = Permission( + name="team_a_full_access", + types=ALL_RESOURCE_TYPES, + required_tags={"team": "team-a"}, # matches only Team A's resources + policy=NamespaceBasedPolicy(namespaces=["team-a"]), + actions=ALL_ACTIONS, +) + +# Team A: read-only access to shared resources published by ANY team +# e.g. a Team B feature view tagged {team: team-b, visibility: shared} +# satisfies required_tags here but NOT team_a_own above +team_a_read_shared = Permission( + name="team_a_read_shared", + types=ALL_RESOURCE_TYPES, + required_tags={"visibility": "shared"}, # matches shared resources from any team + policy=NamespaceBasedPolicy(namespaces=["team-a"]), + actions=[AuthzedAction.DESCRIBE] + READ, +) + +# Team B: mirror of the above — full access to its own, read-only to shared +team_b_own = Permission( + name="team_b_full_access", + types=ALL_RESOURCE_TYPES, + required_tags={"team": "team-b"}, + policy=NamespaceBasedPolicy(namespaces=["team-b"]), + actions=ALL_ACTIONS, +) + +team_b_read_shared = Permission( + name="team_b_read_shared", + types=ALL_RESOURCE_TYPES, + required_tags={"visibility": "shared"}, + policy=NamespaceBasedPolicy(namespaces=["team-b"]), + actions=[AuthzedAction.DESCRIBE] + READ, +) +``` + +### Example: Combined group + namespace policy + +For organizations that use both OIDC groups and Kubernetes namespaces for identity — ideal when platform engineers lack a dedicated namespace but need cross-team visibility, or when OIDC group membership and namespace ownership should independently grant access: + +```python +from feast.feast_object import ALL_RESOURCE_TYPES +from feast.permissions.action import ALL_ACTIONS, READ, AuthzedAction +from feast.permissions.permission import Permission +from feast.permissions.policy import CombinedGroupNamespacePolicy + +# Platform engineers (OIDC group) OR any team namespace can read shared features. +# This covers platform engineers who have no dedicated K8s namespace of their own +# but need cross-team feature discovery. +platform_read_shared = Permission( + name="platform_read_shared", + types=ALL_RESOURCE_TYPES, + required_tags={"visibility": "shared"}, + policy=CombinedGroupNamespacePolicy( + groups=["ml-platform"], # OIDC group for platform/infra engineers + namespaces=["team-a", "team-b"], # team namespaces from enterprise topology + ), + actions=[AuthzedAction.DESCRIBE] + READ, +) + +# ML engineers (OIDC) OR team namespace owners have full write access. +# Either identity alone is sufficient — useful during namespace migration or +# when the same person holds both the OIDC role and the team namespace. +ml_engineer_write = Permission( + name="ml_engineer_full_access", + types=ALL_RESOURCE_TYPES, + policy=CombinedGroupNamespacePolicy( + groups=["ml-engineers"], + namespaces=["team-a", "team-b"], + ), + actions=ALL_ACTIONS, +) +``` + +### Example: Fine-grained resource filtering + +Permissions support `name_patterns` (regex) and `required_tags` for targeting specific resources: + +```python +from feast.feature_view import FeatureView +from feast.data_source import DataSource +from feast.permissions.action import AuthzedAction, READ +from feast.permissions.permission import Permission +from feast.permissions.policy import RoleBasedPolicy + +sensitive_fv_perm = Permission( + name="sensitive_feature_reader", + types=[FeatureView], + name_patterns=[".*sensitive.*", ".*pii.*"], + policy=RoleBasedPolicy(roles=["trusted-reader"]), + actions=[AuthzedAction.READ_OFFLINE], +) + +high_risk_ds_writer = Permission( + name="high_risk_ds_writer", + types=[DataSource], + required_tags={"risk_level": "high"}, + policy=RoleBasedPolicy(roles=["admin", "data_team"]), + actions=[AuthzedAction.WRITE_ONLINE, AuthzedAction.WRITE_OFFLINE], +) +``` + +### Authorization configuration + +Enable auth enforcement in `feature_store.yaml`: + +```yaml +auth: + type: kubernetes # or: oidc +``` + +For OIDC: + +```yaml +auth: + type: oidc + client_id: feast-client + auth_server_url: https://keycloak.example.com/realms/feast + auth_discovery_url: https://keycloak.example.com/realms/feast/.well-known/openid-configuration +``` + +{% hint style="warning" %} +**Permission granting order:** Feast uses an *affirmative* decision strategy — if **any** matching permission grants access, the request is allowed. Access is denied only when **all** matching permissions deny the user. If no permission matches a resource + action combination, access is **denied**. Resources that do not match any configured permission are unsecured. Always define explicit coverage for all critical resources. +{% endhint %} + +### Recommended RBAC by topology + +| Topology | Auth type | Policy type | Guidance | +|---|---|---|---| +| **Minimal** | `no_auth` or `kubernetes` | `RoleBasedPolicy` | Basic admin/reader roles | +| **Standard** | `kubernetes` | `RoleBasedPolicy` | K8s service account roles | +| **Enterprise (isolated)** | `oidc` or `kubernetes` | `RoleBasedPolicy` + `GroupBasedPolicy` | Per-team OIDC groups | +| **Enterprise (shared registry)** | `kubernetes` | `NamespaceBasedPolicy` or `CombinedGroupNamespacePolicy` | Namespace isolation with tag-based resource scoping | + +--- + +## Infrastructure-Specific Recommendations + +Choosing the right online store, offline store, and registry backend depends on your cloud environment and existing infrastructure. The table below maps common deployment environments to recommended Feast components. + +### Recommendation matrix + +```mermaid +graph TD + subgraph AWS["AWS / EKS / ROSA"] + A_Online["Online: ElastiCache Redis
or DynamoDB"] + A_Offline["Offline: Redshift
or Snowflake or Athena"] + A_Registry["Registry: RDS PostgreSQL (SQL)
or S3"] + A_Compute["Compute: Snowflake Engine
or Spark on EMR
or Ray (KubeRay)"] + end + + subgraph GCP["GCP / GKE"] + G_Online["Online: Memorystore Redis
or Bigtable or Datastore"] + G_Offline["Offline: BigQuery
or Snowflake"] + G_Registry["Registry: Cloud SQL PostgreSQL
or GCS"] + G_Compute["Compute: Snowflake Engine
or Spark on Dataproc
or Ray (KubeRay)"] + end + + subgraph OnPrem["On-Premise / OpenShift"] + O_Online["Online: Redis
or PostgreSQL"] + O_Offline["Offline: Spark + MinIO
or PostgreSQL or Trino or Oracle"] + O_Registry["Registry: PostgreSQL (SQL)"] + O_Compute["Compute: Spark
or Ray (KubeRay)"] + end + + style AWS fill:#fff3e0,stroke:#f57c00,color:#000 + style GCP fill:#e3f2fd,stroke:#1976d2,color:#000 + style OnPrem fill:#e8f5e9,stroke:#388e3c,color:#000 +``` + +### AWS / EKS / ROSA + +| Component | Recommended | Alternative | Notes | +|---|---|---|---| +| **Online Store** | **Redis** (ElastiCache) | DynamoDB | Redis offers TTL at retrieval, concurrent writes, Java/Go SDK support. DynamoDB is fully managed with zero ops. | +| **Offline Store** | **Redshift** | Snowflake, Athena (contrib), Spark | Redshift is the core AWS offline store. Use Snowflake if it's already your warehouse. Athena for S3-native query patterns. | +| **Registry** | **SQL** (RDS PostgreSQL) | S3 | SQL registry required for concurrent materialization writers. S3 registry is simpler but limited to single-writer. | +| **Compute Engine** | **Snowflake Engine** | Spark on EMR, [Ray (KubeRay)](../reference/compute-engine/ray.md) | Snowflake engine when your offline/online stores are Snowflake. Spark for S3-based pipelines. Ray with KubeRay for Kubernetes-native distributed processing. | + +{% hint style="info" %} +**ROSA (Red Hat OpenShift on AWS):** Same store recommendations as EKS. Use OpenShift Routes instead of Ingress for TLS termination. Leverage OpenShift's built-in OAuth for `auth.type: kubernetes` integration. +{% endhint %} + +### GCP / GKE + +| Component | Recommended | Alternative | Notes | +|---|---|---|---| +| **Online Store** | **Redis** (Memorystore) | Bigtable, Datastore | Redis for latency-sensitive workloads. Bigtable for very large-scale feature storage. Datastore is GCP-native and zero-ops. | +| **Offline Store** | **BigQuery** | Snowflake, Spark (Dataproc) | BigQuery is the core GCP offline store with full feature support. | +| **Registry** | **SQL** (Cloud SQL PostgreSQL) | GCS | SQL for multi-writer. GCS for simple single-writer setups. | +| **Compute Engine** | **Snowflake Engine** | Spark on Dataproc, [Ray (KubeRay)](../reference/compute-engine/ray.md) | Use Snowflake engine if your offline store is Snowflake. Spark for BigQuery + GCS pipelines. Ray with KubeRay for Kubernetes-native distributed processing. | + +### On-Premise / OpenShift / Self-Managed Kubernetes + +| Component | Recommended | Alternative | Notes | +|---|---|---|---| +| **Online Store** | **Redis** (self-managed or operator) | PostgreSQL (contrib) | Redis for best performance. PostgreSQL if you want to minimize infrastructure components. | +| **Offline Store** | **Spark** + MinIO (contrib) | PostgreSQL (contrib), Trino (contrib), Oracle (contrib), DuckDB | Spark for scale. PostgreSQL for simpler setups. Oracle for enterprise customers with existing Oracle infrastructure. DuckDB for development only. | +| **Registry** | **SQL** (PostgreSQL) | — | Always use SQL registry in production on-prem. File-based registries do not support concurrent writers. | +| **Compute Engine** | **Spark** | [Ray (KubeRay)](../reference/compute-engine/ray.md) | Run Spark on Kubernetes or standalone. Ray with KubeRay for Kubernetes-native distributed DAG execution. | + +{% hint style="warning" %} +**Multi-replica constraint:** When scaling any Feast service to multiple replicas (via the Feast Operator), you **must** use database-backed persistence for all enabled services. File-based stores (SQLite, DuckDB, `registry.db`) are incompatible with multi-replica deployments. See [Scaling Feast](./scaling-feast.md#horizontal-scaling-with-the-feast-operator) for details. +{% endhint %} + +--- + +## Air-Gapped / Disconnected Environment Deployments + +Production environments in regulated industries (finance, government, defense) often have no outbound internet access from the Kubernetes cluster. The Feast Operator supports air-gapped deployments through custom container images, init container controls, and standard Kubernetes image-pull mechanisms. + +### Default init container behavior + +When `feastProjectDir` is set on the FeatureStore CR, the operator creates up to two init containers: + +1. **`feast-init`** — bootstraps the feature repository by running either `git clone` (if `feastProjectDir.git` is set) or `feast init` (if `feastProjectDir.init` is set), then writes the generated `feature_store.yaml` into the repo directory. +2. **`feast-apply`** — runs `feast apply` to register feature definitions in the registry. Controlled by `runFeastApplyOnInit` (defaults to `true`). Skipped when `disableInitContainers` is `true`. + +In air-gapped environments, `git clone` will fail because the cluster cannot reach external Git repositories. The solution is to **pre-bake** the feature repository into a custom container image and disable the init containers entirely. + +### Air-gapped deployment workflow + +```mermaid +graph TD + subgraph BuildEnv["Build Environment (internet access)"] + Code["Feature repo source code"] + Base["Base Feast image
(feastdev/feature-server)"] + Custom["Custom image with
bundled feature repo"] + Code --> Custom + Base --> Custom + end + + subgraph InternalRegistry["Internal Container Registry"] + Mirror["registry.internal.example.com
/feast/feature-server:v0.61"] + end + + subgraph AirGappedCluster["Air-Gapped Kubernetes Cluster"] + SA["ServiceAccount
(imagePullSecrets)"] + CR["FeatureStore CR
disableInitContainers: true
image: registry.internal..."] + Deploy["Feast Deployment
(no init containers)"] + SA --> Deploy + CR --> Deploy + end + + Custom -->|push| Mirror + Mirror -->|pull| Deploy +``` + +**Steps:** + +1. **Build a custom container image** that bundles the feature repository and all Python dependencies into the Feast base image. +2. **Push** the image to your internal container registry. +3. **Set `services.disableInitContainers: true`** on the FeatureStore CR to skip `git clone` / `feast init` and `feast apply`. +4. **Override the image** on each service using the per-service `image` field. +5. **Set `imagePullPolicy: IfNotPresent`** (or `Never` if images are pre-loaded on nodes). +6. **Configure `imagePullSecrets`** on the namespace's ServiceAccount — the FeatureStore CRD does not expose an `imagePullSecrets` field, so use the standard Kubernetes approach of attaching secrets to the ServiceAccount that the pods run under. + +### Sample FeatureStore CR (air-gapped) + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: airgap-production +spec: + feastProject: my_project + services: + disableInitContainers: true + onlineStore: + persistence: + store: + type: redis + secretRef: + name: feast-online-store + server: + image: registry.internal.example.com/feast/feature-server:v0.61 + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: "1" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-registry-store + server: + image: registry.internal.example.com/feast/feature-server:v0.61 + imagePullPolicy: IfNotPresent +``` + +{% hint style="info" %} +**Pre-populating the registry:** With init containers disabled, `feast apply` does not run on pod startup. You can populate the registry by: + +1. **Running `feast apply` from your CI/CD pipeline** that has network access to the registry DB. +2. **Using the FeatureStore CR's built-in CronJob** (`spec.cronJob`) — the operator creates a Kubernetes CronJob that runs `feast apply` and `feast materialize-incremental` on a schedule. The CronJob runs inside the cluster (no external access needed) and can use a custom image just like the main deployment. This is the recommended approach for air-gapped environments. +3. **Running `feast apply` manually** from the build environment before deploying the CR. +{% endhint %} + +### Air-gapped deployment checklist + +{% hint style="warning" %} +**Pre-stage the following artifacts before deploying Feast in an air-gapped environment:** + +* **Container images** — Feast feature server image (with bundled feature repo) pushed to internal registry +* **CRD manifests** — Feast Operator CRDs and operator deployment manifests available locally +* **Store credentials** — Kubernetes Secrets for online store, offline store, and registry DB connections created in the target namespace +* **Python packages** (if using custom on-demand transforms) — bundled into the custom image or available from an internal PyPI mirror +* **ServiceAccount configuration** — `imagePullSecrets` attached to the ServiceAccount used by the Feast deployment +{% endhint %} + +--- + +## Hybrid Store Configuration + +The hybrid store feature allows a single Feast deployment to route feature operations to multiple backends based on tags or data sources. This is useful when different feature views have different latency, cost, or compliance requirements. + +### Hybrid online store + +The `HybridOnlineStore` routes online operations to different backends based on a configurable tag on the `FeatureView`. + +```mermaid +graph LR + FS["Online Feature Server"] --> Router["HybridOnlineStore
(routes by tag)"] + Router -->|"tag: dynamodb"| DDB["DynamoDB"] + Router -->|"tag: redis"| RD["Redis"] + + style Router fill:#fff3e0,stroke:#f57c00,color:#000 + style DDB fill:#e3f2fd,stroke:#1976d2,color:#000 + style RD fill:#fce4ec,stroke:#c62828,color:#000 +``` + +**`feature_store.yaml` configuration:** + +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: hybrid + routing_tag: team + online_stores: + - type: dynamodb + conf: + region: us-east-1 + - type: redis + conf: + connection_string: "redis-cluster:6379" + redis_type: redis_cluster +``` + +**Feature view with routing tag:** + +```python +from feast import FeatureView + +user_features = FeatureView( + name="user_features", + entities=[user_entity], + source=user_source, + tags={"team": "dynamodb"}, # Routes to DynamoDB backend +) + +transaction_features = FeatureView( + name="transaction_features", + entities=[txn_entity], + source=txn_source, + tags={"team": "redis"}, # Routes to Redis backend +) +``` + +The tag value must match the online store `type` name (e.g. `dynamodb`, `redis`, `bigtable`). + +### Hybrid offline store + +The `HybridOfflineStore` routes offline operations to different backends based on the `batch_source` type of each `FeatureView`. + +```mermaid +graph LR + Client["Materialization /
Training Job"] --> Router["HybridOfflineStore
(routes by source type)"] + Router -->|"SparkSource"| Spark["Spark"] + Router -->|"RedshiftSource"| RS["Redshift"] + + style Router fill:#fff3e0,stroke:#f57c00,color:#000 + style Spark fill:#e8f5e9,stroke:#388e3c,color:#000 + style RS fill:#e3f2fd,stroke:#1976d2,color:#000 +``` + +**`feature_store.yaml` configuration:** + +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +offline_store: + type: hybrid_offline_store.HybridOfflineStore + offline_stores: + - type: spark + conf: + spark_master: local[*] + spark_app_name: feast_spark_app + - type: redshift + conf: + cluster_id: my-redshift-cluster + region: us-east-1 + database: feast_db + user: feast_user + s3_staging_location: s3://my-bucket/feast-staging + iam_role: arn:aws:iam::123456789012:role/FeastRedshiftRole +``` + +**Feature views with different sources:** + +```python +from feast import FeatureView, Entity, ValueType +from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import SparkSource +from feast.infra.offline_stores.redshift_source import RedshiftSource + +user_features = FeatureView( + name="user_features", + entities=[user_entity], + source=SparkSource(path="s3://bucket/user_features"), # Routes to Spark +) + +activity_features = FeatureView( + name="user_activity", + entities=[user_entity], + source=RedshiftSource( # Routes to Redshift + table="user_activity", + event_timestamp_column="event_ts", + ), +) +``` + +{% hint style="warning" %} +**Hybrid offline store constraint:** `get_historical_features` requires all requested feature views to share the same `batch_source` type within a single call. You cannot join features across different offline engines in one retrieval request. +{% endhint %} + +--- + +## Performance Considerations + +For detailed server-level tuning (worker counts, timeouts, keep-alive, etc.), see the [Online Server Performance Tuning](./online-server-performance-tuning.md) guide. + +### Online feature server sizing + +| Traffic tier | Replicas | CPU (per pod) | Memory (per pod) | Notes | +|---|---|---|---|---| +| Low (<100 RPS) | 1–2 | 500m–1 | 512Mi–1Gi | Minimal production | +| Medium (100–1000 RPS) | 2–5 (HPA) | 1–2 | 1–2Gi | Standard production | +| High (>1000 RPS) | 5–20 (HPA) | 2–4 | 2–4Gi | Enterprise, per-tenant | + +### Online store latency guidelines + +| Store | p50 latency | p99 latency | Best for | +|---|---|---|---| +| **Redis** (single) | <1ms | <5ms | Lowest latency, small-medium datasets | +| **Redis Cluster** | <2ms | <10ms | High availability + low latency | +| **DynamoDB** | <5ms | <20ms | Serverless, variable traffic | +| **PostgreSQL** | <5ms | <30ms | On-prem, simplicity | +| **Remote (HTTP)** | <10ms | <50ms | Client-server separation | + +### Connection pooling for remote online store + +When using the [Remote Online Store](../reference/online-stores/remote.md) (client-server architecture), connection pooling significantly reduces latency by reusing TCP/TLS connections: + +```yaml +online_store: + type: remote + path: http://feast-feature-server:80 + connection_pool_size: 50 # Max connections in pool (default: 50) + connection_idle_timeout: 300 # Idle timeout in seconds (default: 300) + connection_retries: 3 # Retry count with exponential backoff +``` + +**Tuning by workload:** + +| Workload | `connection_pool_size` | `connection_idle_timeout` | `connection_retries` | +|---|---|---|---| +| High-throughput inference | 100 | 600 | 5 | +| Long-running batch service | 50 | 0 (never close) | 3 | +| Resource-constrained edge | 10 | 60 | 2 | + +### Registry performance + +* **SQL registry** (PostgreSQL, MySQL) is required for concurrent materialization jobs writing to the registry simultaneously. +* **File-based registries** (S3, GCS, local) serialize the entire registry on each write — suitable only for single-writer scenarios. +* For read-heavy workloads, scale the Registry Server to multiple replicas (all connecting to the same database). + +### Registry cache tuning at scale + +Each Feast server pod maintains its own in-memory copy of the registry metadata. With multiple Gunicorn workers per pod, the total number of independent registry copies is **replicas x workers**. For example, 5 replicas with 4 workers each means 20 copies of the registry in memory, each refreshing independently. + +With the default `cache_mode: sync`, the refresh is **synchronous** — when the TTL expires, the next request blocks until the full registry is re-downloaded. At scale, this causes periodic latency spikes across multiple pods simultaneously. + +**Recommendation:** Use `cache_mode: thread` with a higher TTL in production to avoid refresh storms: + +```yaml +# In the Operator secret for SQL/DB-backed registries: +registry: + registry_type: sql + path: postgresql://:@:5432/feast + cache_mode: thread + cache_ttl_seconds: 300 +``` + +For the server-side refresh interval, set `registryTTLSeconds` on the CR: + +```yaml +spec: + services: + onlineStore: + server: + workerConfigs: + registryTTLSeconds: 300 +``` + +| Scenario | `cache_mode` | `cache_ttl_seconds` | `registryTTLSeconds` | +|---|---|---|---| +| Development / iteration | `sync` (default) | 5–10 | 5 | +| Production (low-latency) | `thread` | 300 | 300 | +| Production (frequent schema changes) | `thread` | 60 | 60 | + +{% hint style="info" %} +`registryTTLSeconds` on the CR controls the **server-side** refresh interval. `cache_ttl_seconds` in the registry secret controls the **SDK client** refresh. In Operator deployments, the CR field is what matters for serving performance. For a deep dive into sync vs thread mode trade-offs, memory impact, and freshness considerations, see the [Registry Cache Tuning](./online-server-performance-tuning.md#registry-cache-tuning) section in the performance tuning guide. +{% endhint %} + +### Materialization performance + +| Data volume | Recommended engine | Notes | +|---|---|---| +| <1M rows | In-process (default) | Simple, no external dependencies | +| 1M–100M rows | Snowflake Engine, Spark, or Ray | Distributed processing | +| >100M rows | Spark on Kubernetes / EMR / Dataproc, or Ray via KubeRay | Full cluster-scale materialization with distributed DAG execution | + +For detailed engine configuration, see [Scaling Materialization](./scaling-feast.md#scaling-materialization). + +### Redis sizing guidelines + +| Metric | Guideline | +|---|---| +| **Memory** | ~100 bytes per feature value (varies by data type). For 1M entities x 50 features = ~5GB. | +| **Connections** | Each online feature server replica opens a connection pool. Plan for `replicas x pool_size`. | +| **TTL** | Set `key_ttl_seconds` in `feature_store.yaml` to auto-expire stale data and bound memory usage. | +| **Cluster mode** | Use Redis Cluster for >25GB datasets or >10K connections. | + +--- + +## Design Principles + +Understanding the following principles helps you choose and customize the right topology. + +### Control plane vs data plane + +```mermaid +graph LR + subgraph ControlPlane["Control Plane"] + Operator["Feast Operator"] + Registry["Registry Server"] + end + + subgraph DataPlane["Data Plane"] + OnlineServer["Online Feature Server"] + OfflineServer["Offline Feature Server"] + end + + subgraph BackingStores["Backing Stores (external)"] + OnlineStore["Online Store
(e.g. Redis, DynamoDB, PostgreSQL, etc.)"] + OfflineStore["Offline Store
(e.g. Redshift, BigQuery, Spark, etc.)"] + RegistryDB["Registry DB
(PostgreSQL / MySQL)"] + end + + ControlPlane -->|configures| DataPlane + DataPlane -->|reports status| ControlPlane + OnlineServer --> OnlineStore + OfflineServer --> OfflineStore + Registry --> RegistryDB + + style ControlPlane fill:#e8f5e9,stroke:#388e3c,color:#000 + style DataPlane fill:#e3f2fd,stroke:#1976d2,color:#000 + style BackingStores fill:#fce4ec,stroke:#c62828,color:#000 +``` + +* **Control plane** (Operator + Registry Server) manages feature definitions, metadata, and lifecycle. It changes infrequently and should be highly available. +* **Data plane** (Online Feature Server + Offline Feature Server) handles the actual feature reads/writes at request time. It must scale with traffic. +* **Backing stores** (databases, object storage) hold the actual data. These are stateful and managed independently. + +### Stateless vs stateful components + +The Feast Operator deploys all Feast services (Online Feature Server, Offline Feature Server, Registry Server) in a **single shared Deployment**. When scaling (`spec.replicas > 1` or HPA autoscaling), all services scale together. + +{% hint style="warning" %} +**Scaling requires DB-backed persistence for all enabled services.** The operator enforces this via CRD validation: + +* **Online Store** — must use DB persistence (e.g. `type: redis`, `type: dynamodb`, `type: postgres`) +* **Offline Store** — if enabled, must use DB persistence (e.g. `type: redshift`, `type: bigquery`, `type: spark`, `type: postgres`) +* **Registry** — must use SQL persistence (`type: sql`), a remote registry, or S3/GCS file-backed registry + +File-based stores (SQLite, DuckDB, `registry.db`) are **rejected** when `replicas > 1` or autoscaling is configured. +{% endhint %} + +| Component | Type | Scaling | DB-backed requirement | +|---|---|---|---| +| Online Feature Server | **Stateless** (server) | Scales with the shared Deployment (HPA or `spec.replicas`) | Online store must use DB persistence (e.g. Redis, DynamoDB, PostgreSQL) | +| Offline Feature Server | **Stateless** (server) | Scales with the shared Deployment (HPA or `spec.replicas`) | Offline store must use DB persistence (e.g. Redshift, BigQuery, Spark, PostgreSQL) | +| Registry Server | **Stateless** (server) | Scales with the shared Deployment (HPA or `spec.replicas`) | Registry must use SQL, remote, or S3/GCS persistence | +| Online Store (Redis, DynamoDB, etc.) | **Stateful** (backing store) | Scale via managed service or clustering | Managed independently of Feast services | +| Offline Store (Redshift, BigQuery, etc.) | **Stateful** (backing store) | Scale via cloud-managed infrastructure | Managed independently of Feast services | +| Registry DB (PostgreSQL, MySQL) | **Stateful** (backing store) | Scale via managed database service | Managed independently of Feast services | + +### Scalability guidelines + +```mermaid +graph TD + Read["Read traffic increase"] -->|scale| FS["Online Feature Server replicas (HPA)"] + Write["Write / materialization load"] -->|scale| Engine["Compute Engine
(Spark / Ray / Snowflake)"] + Storage["Data volume growth"] -->|scale| Store["Online / Offline Store capacity"] + + FS -.- Independent["Scale independently"] + Engine -.- Independent + Store -.- Independent + + style Read fill:#e3f2fd,stroke:#1976d2,color:#000 + style Write fill:#fff3e0,stroke:#f57c00,color:#000 + style Storage fill:#f3e5f5,stroke:#7b1fa2,color:#000 + style FS fill:#e3f2fd,stroke:#1976d2,color:#000 + style Engine fill:#fff3e0,stroke:#f57c00,color:#000 + style Store fill:#f3e5f5,stroke:#7b1fa2,color:#000 +``` + +* **Read scaling** — increase Online Feature Server replicas; they are stateless and scale linearly. +* **Write scaling** — use a distributed compute engine ([Spark](../reference/compute-engine/spark.md), [Ray/KubeRay](../reference/compute-engine/ray.md), or [Snowflake](../reference/compute-engine/snowflake.md)) for materialization. +* **Storage scaling** — scale online and offline stores independently based on data volume and query patterns. + +For detailed scaling configuration, see [Scaling Feast](./scaling-feast.md). + +--- + +## Topology Comparison + +| Capability | Minimal | Standard | Enterprise | +|---|:---:|:---:|:---:| +| **High availability** | No | Yes | Yes | +| **Autoscaling** | No | HPA | HPA + Cluster Autoscaler | +| **TLS / Ingress** | No | Yes | Yes + API Gateway | +| **RBAC** | No | Kubernetes RBAC | OIDC + fine-grained RBAC | +| **Multi-tenancy** | No | No | Namespace-per-team | +| **Shared registry** | N/A | N/A | Optional (remote registry) | +| **Hybrid stores** | No | Optional | Recommended for mixed backends | +| **Observability** | Logs only | Basic metrics | OpenTelemetry + Prometheus + Grafana + Jaeger | +| **Disaster recovery** | No | Partial | Full backup/restore | +| **Network policies** | No | Optional | Enforced | +| **Recommended team size** | 1–3 | 3–15 | 15+ | + +--- + +## Next Steps + +* [Feast on Kubernetes](./feast-on-kubernetes.md) — install the Feast Operator and deploy your first FeatureStore CR +* [Scaling Feast](./scaling-feast.md) — detailed HPA, registry scaling, and materialization engine configuration +* [Online Server Performance Tuning](./online-server-performance-tuning.md) — worker counts, timeouts, keep-alive, and server-level tuning +* [Starting Feast Servers in TLS Mode](./starting-feast-servers-tls-mode.md) — enable TLS for secure communication +* [Running Feast in Production](./running-feast-in-production.md) — CI/CD, materialization scheduling, and model serving patterns +* [Multi-Team Feature Store Setup](./federated-feature-store.md) — federated feature store for multi-team environments +* [Permission Concepts](../getting-started/concepts/permission.md) — full permission model reference +* [RBAC Architecture](../getting-started/architecture/rbac.md) — authorization architecture details +* [OpenTelemetry Integration](../getting-started/components/open-telemetry.md) — traces and metrics for Feast servers +* [Hybrid Online Store](../reference/online-stores/hybrid.md) — hybrid online store configuration reference +* [Hybrid Offline Store](../reference/offline-stores/hybrid.md) — hybrid offline store configuration reference diff --git a/docs/how-to-guides/running-feast-in-production.md b/docs/how-to-guides/running-feast-in-production.md index be6fd2afeb4..d26e0234b2e 100644 --- a/docs/how-to-guides/running-feast-in-production.md +++ b/docs/how-to-guides/running-feast-in-production.md @@ -18,6 +18,10 @@ For example, you might not have a stream source and, thus, no need to write feat Additionally, please check the how-to guide for some specific recommendations on [how to scale Feast](./scaling-feast.md). {% endhint %} +{% hint style="info" %} +**Looking for production deployment patterns?** See the [Feast Production Deployment Topologies](./production-deployment-topologies.md) guide for three Kubernetes-ready topologies (Minimal, Standard, Enterprise), sample FeatureStore CRs, RBAC policies, infrastructure recommendations, and scaling best practices. +{% endhint %} + In this guide we will show you how to: 1. Deploy your feature store and keep your infrastructure in sync with your feature repository @@ -71,6 +75,15 @@ Feast keeps the history of materialization in its registry so that the choice co However, the amount of work can quickly outgrow the resources of a single machine. That happens because the materialization job needs to repackage all rows before writing them to an online store. That leads to high utilization of CPU and memory. In this case, you might want to use a job orchestrator to run multiple jobs in parallel using several workers. Kubernetes Jobs or Airflow are good choices for more comprehensive job orchestration. +For large datasets, you can also reduce peak memory on the materialization worker by setting `online_write_batch_size` in `feature_store.yaml`. This breaks the proto conversion and write into chunks instead of loading the entire dataset into memory at once: + +```yaml +materialization: + online_write_batch_size: 10000 # rows per write batch; reduces peak memory proportionally +``` + +See the [Materialization write performance](./online-server-performance-tuning.md#materialization-write-performance) guide for sizing recommendations and the full option reference in [feature_store.yaml](../reference/feature-repository/feature-store-yaml.md#online_write_batch_size). + If you are using Airflow as a scheduler, Feast can be invoked through a [PythonOperator](https://airflow.apache.org/docs/apache-airflow/stable/howto/operator/python.html) after the [Python SDK](https://pypi.org/project/feast/) has been installed into a virtual environment and your feature repo has been synced: ```python diff --git a/docs/how-to-guides/starting-feast-servers-tls-mode.md b/docs/how-to-guides/starting-feast-servers-tls-mode.md index ffc7e5d9e90..c3696a35532 100644 --- a/docs/how-to-guides/starting-feast-servers-tls-mode.md +++ b/docs/how-to-guides/starting-feast-servers-tls-mode.md @@ -128,6 +128,52 @@ auth: `cert` is an optional configuration to the public certificate path when the registry server starts in TLS(SSL) mode. Typically, this file ends with `*.crt`, `*.cer`, or `*.pem`. +### Feast client connecting to remote registry server with mTLS + +If the Registry Server requires mutual TLS (mTLS), the client must present a certificate and private key in addition to trusting the server's CA certificate. Add `client_cert` and `client_key` to the registry configuration: + +```yaml +project: feast-project +registry: + registry_type: remote + path: feature-registry.example.com:443 + cert: /path/to/ca.crt + client_cert: /path/to/tls.crt + client_key: /path/to/tls.key +provider: local +online_store: + path: http://localhost:6566 + type: remote +entity_key_serialization_version: 3 +auth: + type: no_auth +``` + +* `cert` — CA certificate used to verify the server (or use the `SSL_CERT_FILE` / `REQUESTS_CA_BUNDLE` environment variable). +* `client_cert` — Client certificate presented to the server. Must be paired with `client_key`. +* `client_key` — Private key for the client certificate. + +#### Connecting through a tunnel or proxy + +When connecting through a tunnel (e.g. `gcloud compute start-iap-tunnel`) the client connects to `localhost`, but the server certificate is issued for the real service hostname. Set the `authority` field so that gRPC's TLS hostname verification passes: + +```shell +# In one terminal — start the tunnel: +gcloud compute start-iap-tunnel feature-registry.example.com 443 --local-host-port=localhost:8443 +``` + +```yaml +registry: + registry_type: remote + path: localhost:8443 + cert: /path/to/ca.crt + client_cert: /path/to/tls.crt + client_key: /path/to/tls.key + authority: feature-registry.example.com +``` + +Without `authority`, the gRPC client would check the server certificate against `localhost`, which would fail because the certificate's Subject Alternative Name (SAN) is `feature-registry.example.com`. + ## Starting feast offline server in TLS mode To start the offline server in TLS mode, you need to provide the private and public keys using the `--key` and `--cert` arguments with the `feast serve_offline` command. diff --git a/docs/project/contributing.md b/docs/project/contributing.md index cded378951d..d79291b9aa8 100644 --- a/docs/project/contributing.md +++ b/docs/project/contributing.md @@ -22,9 +22,22 @@ PRs that are submitted by the general public need to be identified as `ok-to-tes See also [Making a pull request](development-guide.md#making-a-pull-request) for other guidelines on making pull requests in Feast. +## RFCs and Architecture Decision Records + +For substantial changes (new features, architecture changes, removing features), we use an RFC process. See the [governance document](../../community/governance.md#rfcs-process) for details. + +Once an RFC is finalized and approved, it should be recorded as an Architecture Decision Record (ADR) in the [`docs/adr/`](../adr/README.md) directory. This ensures that architectural decisions are version-controlled alongside the codebase and easily accessible to all contributors. + +To add a finalized RFC as an ADR: + +1. Copy the [ADR template](../adr/ADR-TEMPLATE.md) to a new file with the next sequential number. +2. Summarize the RFC's context, decision, and consequences. +3. Submit a pull request with the new ADR. + ## Resources - [Community](../community.md) for other ways to get involved with the community - [Development guide](development-guide.md) for tips on how to contribute - [Feast GitHub issues](https://github.com/feast-dev/feast/issues) to see what others are working on -- [Feast RFCs](https://drive.google.com/drive/u/0/folders/1msUsgmDbVBaysmhBlg9lklYLLTMk4bC3) for a folder of previously written RFCs \ No newline at end of file +- [Feast RFCs](https://drive.google.com/drive/u/0/folders/1msUsgmDbVBaysmhBlg9lklYLLTMk4bC3) for a folder of previously written RFCs +- [Architecture Decision Records](../adr/README.md) for documented architectural decisions \ No newline at end of file diff --git a/docs/reference/alpha-feature-view-versioning.md b/docs/reference/alpha-feature-view-versioning.md new file mode 100644 index 00000000000..5cdf2845ebc --- /dev/null +++ b/docs/reference/alpha-feature-view-versioning.md @@ -0,0 +1,229 @@ +# \[Alpha\] Feature View Versioning + +{% hint style="warning" %} +**Warning**: This is an _experimental_ feature. It is stable but there are still rough edges. Contributions are welcome! +{% endhint %} + +## Overview + +Feature view versioning automatically tracks schema and UDF changes to feature views. Every time `feast apply` detects a change, a versioned snapshot is saved to the registry. This enables: + +- **Audit trail** — see what a feature view looked like at any point in time +- **Safe rollback** — pin serving to a prior version with `version="v0"` in your definition +- **Multi-version serving** — serve both old and new schemas simultaneously using `@v` syntax +- **Staged publishing** — use `feast apply --no-promote` to publish a new version without making it the default + +## How It Works + +Version tracking is fully automatic. You don't need to set any version parameter — just use `feast apply` as usual: + +1. **First apply** — Your feature view definition is saved as **v0**. +2. **Change something and re-apply** — Feast detects the change, saves the old definition as a snapshot, and saves the new one as **v1**. The version number auto-increments on each real change. +3. **Re-apply without changes** — Nothing happens. Feast compares the new definition against the active one and skips creating a version if they're identical (idempotent). +4. **Another change** — Creates **v2**, and so on. + +``` +feast apply # First apply → v0 +# ... edit schema ... +feast apply # Detects change → v1 +feast apply # No change detected → still v1 (no new version) +# ... edit source ... +feast apply # Detects change → v2 +``` + +**Key details:** + +* **Automatic snapshots**: Versions are created only when Feast detects an actual change to the feature view definition (schema or UDF). Metadata-only changes (description, tags, TTL) update in place without creating a new version. +* **Separate history storage**: Version history is stored separately from the active feature view definition, keeping the main registry lightweight. +* **Backward compatible**: The `version` parameter is fully optional. Omitting it (or setting `version="latest"`) preserves existing behavior — you get automatic versioning with zero changes to your code. + +## Configuration + +{% hint style="info" %} +Version history tracking is **always active** — no configuration needed. Every `feast apply` that changes a feature view automatically records a version snapshot. + +To enable **versioned online reads** (e.g., `fv@v2:feature`), add `enable_online_feature_view_versioning: true` to your registry config in `feature_store.yaml`: + +```yaml +registry: + path: data/registry.db + enable_online_feature_view_versioning: true +``` + +When this flag is off, version-qualified refs (e.g., `fv@v2:feature`) in online reads will raise errors, but version history, version listing, version pinning, and version lookups all work normally. +{% endhint %} + +## Pinning to a Specific Version + +You can pin a feature view to a specific historical version by setting the `version` parameter. When pinned, `feast apply` replaces the active feature view with the snapshot from that version. This is useful for reverting to a known-good definition. + +```python +from feast import FeatureView + +# Default behavior: always use the latest version (auto-increments on changes) +driver_stats = FeatureView( + name="driver_stats", + entities=[driver], + schema=[...], + source=my_source, +) + +# Pin to a specific version (reverts the active definition to v2's snapshot) +driver_stats = FeatureView( + name="driver_stats", + entities=[driver], + schema=[...], + source=my_source, + version="v2", # also accepts "version2" +) +``` + +When pinning, the feature view definition (schema, source, transformations, etc.) must match the currently active definition. If you've also modified the definition alongside the pin, `feast apply` will raise a `FeatureViewPinConflict` error. To apply changes, use `version="latest"`. To revert, only change the `version` parameter. + +The snapshot's content replaces the active feature view. Version history is not modified by a pin; the existing v0, v1, v2, etc. snapshots remain intact. + +After reverting with a pin, you can go back to normal auto-incrementing behavior by removing the `version` parameter (or setting it to `"latest"`) and running `feast apply` again. If the restored definition differs from the pinned snapshot, a new version will be created. + +### Version string formats + +| Format | Meaning | +|--------|---------| +| `"latest"` (or omitted) | Always use the latest version (auto-increments on changes) | +| `"v0"`, `"v1"`, `"v2"`, ... | Pin to a specific version number | +| `"version0"`, `"version1"`, ... | Equivalent long form (case-insensitive) | + +## Staged Publishing (`--no-promote`) + +By default, `feast apply` atomically saves a version snapshot **and** promotes it to the active definition. For breaking schema changes, you may want to stage the new version without disrupting unversioned consumers. + +The `--no-promote` flag saves the version snapshot without updating the active feature view definition. The new version is accessible only via explicit `@v` reads and `--version` materialization. + +**CLI usage:** + +```bash +feast apply --no-promote +``` + +**Python SDK equivalent:** + +```python +store.apply([entity, feature_view], no_promote=True) +``` + +### Phased rollout workflow + +1. **Stage the new version:** + ```bash + feast apply --no-promote + ``` + This publishes v2 without promoting it. All unversioned consumers continue using v1. + +2. **Populate the v2 online table:** + ```bash + feast materialize --views driver_stats --version v2 ... + ``` + +3. **Migrate consumers one at a time:** + - Consumer A switches to `driver_stats@v2:trips_today` + - Consumer B switches to `driver_stats@v2:avg_rating` + +4. **Promote v2 as the default:** + ```bash + feast apply + ``` + Or pin to v2: set `version="v2"` in the definition and run `feast apply`. + +## Listing Version History + +Use the CLI to inspect version history: + +```bash +feast feature-views list-versions driver_stats +``` + +```text +VERSION TYPE CREATED VERSION_ID +v0 feature_view 2024-01-15 10:30:00 a1b2c3d4-... +v1 feature_view 2024-01-16 14:22:00 e5f6g7h8-... +v2 feature_view 2024-01-20 09:15:00 i9j0k1l2-... +``` + +Or programmatically via the Python SDK: + +```python +store = FeatureStore(repo_path=".") +versions = store.list_feature_view_versions("driver_stats") +for v in versions: + print(f"{v['version']} created at {v['created_timestamp']}") +``` + +## Version-Qualified Feature References + +You can read features from a **specific version** of a feature view by using version-qualified feature references with the `@v` syntax: + +```python +online_features = store.get_online_features( + features=[ + "driver_stats:trips_today", # latest version (default) + "driver_stats@v2:trips_today", # specific version + "driver_stats@latest:trips_today", # explicit latest + ], + entity_rows=[{"driver_id": 1001}], +) +``` + +**How it works:** + +* `driver_stats:trips_today` is equivalent to `driver_stats@latest:trips_today` — it reads from the currently active version +* `driver_stats@v2:trips_today` reads from the v2 snapshot stored in version history, using a version-specific online store table +* Multiple versions of the same feature view can be queried in a single request (e.g., `driver_stats@v1:trips` and `driver_stats@v2:trips_daily`) + +**Backward compatibility:** + +* The unversioned online store table (e.g., `project_driver_stats`) is treated as v0 +* Only versions >= 1 get `_v{N}` suffixed tables (e.g., `project_driver_stats_v1`) +* Pre-versioning users' existing data continues to work without changes — `@latest` resolves to the active version, which for existing unversioned FVs is v0 + +**Materialization:** Each version requires its own materialization. After applying a new version, run `feast materialize` to populate the versioned table before querying it with `@v`. + +## Supported Feature View Types + +Versioning is supported on all three feature view types: + +* `FeatureView` (and `BatchFeatureView`) +* `StreamFeatureView` +* `OnDemandFeatureView` + +## Online Store Support + +{% hint style="info" %} +**Currently, version-qualified online reads (`@v`) are only supported with the SQLite online store.** Support for additional online stores (Redis, DynamoDB, Bigtable, Postgres, etc.) will be added based on community priority. + +If you need versioned online reads for a specific online store, please [open a GitHub issue](https://github.com/feast-dev/feast/issues/new) describing your use case and which store you need. This helps us prioritize development. +{% endhint %} + +Version history tracking in the registry (listing versions, pinning, `--no-promote`) works with **all** registry backends (file, SQL, Snowflake). + +## Full Details + +For the complete design, concurrency semantics, and feature service interactions, see the [Feature View Versioning RFC](../adr/feature-view-versioning.md). + +## Naming Restrictions + +Feature references use a structured format: `feature_view_name@v:feature_name`. To avoid +ambiguity, the following characters are reserved and must not appear in feature view or feature names: + +- **`@`** — Reserved as the version delimiter (e.g., `driver_stats@v2:trips_today`). `feast apply` + will reject feature views with `@` in their name. If you have existing feature views with `@` in + their names, they will continue to work for unversioned reads, but we recommend renaming them to + avoid ambiguity with the `@v` syntax. +- **`:`** — Reserved as the separator between feature view name and feature name in fully qualified + feature references (e.g., `driver_stats:trips_today`). + +## Known Limitations + +- **Online store coverage** — Version-qualified reads (`@v`) are SQLite-only today. Other online stores are follow-up work. +- **Offline store versioning** — Versioned historical retrieval is not yet supported. +- **Version deletion** — There is no mechanism to prune old versions from the registry. +- **Cross-version joins** — Joining features from different versions of the same feature view in `get_historical_features` is not supported. +- **Feature services** — Feature services always resolve to the active (promoted) version. `--no-promote` versions are not served until promoted. diff --git a/docs/reference/alpha-web-ui.md b/docs/reference/alpha-web-ui.md index 80c5b824c5a..0556482fcf8 100644 --- a/docs/reference/alpha-web-ui.md +++ b/docs/reference/alpha-web-ui.md @@ -35,6 +35,18 @@ Options: This will spin up a Web UI on localhost which automatically refreshes its view of the registry every `registry_ttl_sec` +#### Curl Generator Feature Server URL + +The Curl Generator uses a default Feature Server URL when building the example curl command. You can configure +this default at build time using: + +```bash +REACT_APP_FEAST_FEATURE_SERVER_URL="http://your-server:6566" +``` + +If this environment variable is not set, the UI falls back to `http://localhost:6566`. A user-edited value in +the UI is still stored in localStorage and will take precedence for that browser. + ### Importing as a module to integrate with an existing React App This is the recommended way to use Feast UI for teams maintaining their own internal UI for their deployment of Feast. diff --git a/docs/reference/beta-on-demand-feature-view.md b/docs/reference/beta-on-demand-feature-view.md index efb7023d567..684bc0ac4b2 100644 --- a/docs/reference/beta-on-demand-feature-view.md +++ b/docs/reference/beta-on-demand-feature-view.md @@ -69,6 +69,42 @@ def driver_aggregated_stats(inputs): Aggregated columns are automatically named using the pattern `{function}_{column}` (e.g., `sum_trips`, `mean_rating`). +### Using `input_schema` with Aggregations + +When the input data is not already stored as a feature view, use `input_schema` instead of `sources` to describe the fields that will be passed at request time. Feast will create an internal `RequestSource` automatically. + +```python +from datetime import timedelta +from feast import Field, on_demand_feature_view +from feast.aggregation import Aggregation +from feast.types import Float64, Int64 + +@on_demand_feature_view( + input_schema=[ + Field(name="txn_amount", dtype=Float64), + ], + schema=[ + Field(name="txn_count", dtype=Int64), + Field(name="total_txn_amount", dtype=Float64), + Field(name="avg_txn_amount", dtype=Float64), + ], + aggregations=[ + Aggregation(column="txn_amount", function="count", name="txn_count", + time_window=timedelta(days=30)), + Aggregation(column="txn_amount", function="sum", name="total_txn_amount", + time_window=timedelta(days=30)), + Aggregation(column="txn_amount", function="mean", name="avg_txn_amount", + time_window=timedelta(days=30)), + ], + entities=[user], +) +def user_transaction_stats(inputs): + # Aggregations replace the transformation function — no body needed. + pass +``` + +`input_schema` also accepts fields that are not aggregation columns — for example, thresholds, currency codes, or other contextual values passed at request time that your UDF needs but that are not stored as features. + ## Example See [https://github.com/feast-dev/on-demand-feature-views-demo](https://github.com/feast-dev/on-demand-feature-views-demo) for an example on how to use on demand feature views. diff --git a/docs/reference/codebase-structure.md b/docs/reference/codebase-structure.md index 80608b5929a..6c5ad9a141e 100644 --- a/docs/reference/codebase-structure.md +++ b/docs/reference/codebase-structure.md @@ -28,7 +28,7 @@ The majority of Feast logic lives in these Python files: There are also several important submodules: * `infra/` contains all the infrastructure components, such as the provider, offline store, online store, batch materialization engine, and registry. -* `dqm/` covers data quality monitoring, such as the dataset profiler. +* `dqm/` covers data quality monitoring. The legacy Great Expectations profiler (`profilers/ge_profiler`) is deprecated; see [`monitoring/`](../../sdk/python/feast/monitoring/) for the current built-in monitoring system. * `diff/` covers the logic for determining how to apply infrastructure changes upon feature repo changes (e.g. the output of `feast plan` and `feast apply`). * `embedded_go/` covers the Go feature server. * `ui/` contains the embedded Web UI, to be launched on the `feast ui` command. diff --git a/docs/reference/compute-engine/README.md b/docs/reference/compute-engine/README.md index dad2ede75a6..920d5761d28 100644 --- a/docs/reference/compute-engine/README.md +++ b/docs/reference/compute-engine/README.md @@ -57,6 +57,14 @@ An example of built output from FeatureBuilder: - Supports point-in-time joins and large-scale materialization - Integrates with `SparkOfflineStore` and `SparkMaterializationJob` +### 🌊 FlinkComputeEngine + +{% page-ref page="flink.md" %} + +- Distributed DAG execution through Apache Flink's PyFlink Table API +- Supports materialization and historical retrieval with Feast offline stores +- Integrates with `FlinkMaterializationJob` and `FlinkDAGRetrievalJob` + ### ⚡ RayComputeEngine (contrib) - Distributed DAG execution via Ray diff --git a/docs/reference/compute-engine/flink.md b/docs/reference/compute-engine/flink.md new file mode 100644 index 00000000000..0dd5560f70e --- /dev/null +++ b/docs/reference/compute-engine/flink.md @@ -0,0 +1,124 @@ +# Apache Flink + +## Description + +The Apache Flink compute engine provides a distributed execution engine for +feature pipelines through the PyFlink Table API. It implements Feast's unified +`ComputeEngine` interface and can be used for batch materialization operations +(`materialize` and `materialize-incremental`) and historical retrieval +(`get_historical_features`). + +The engine reads data through the configured Feast offline store and executes +the Feast DAG as PyFlink tables. Offline stores that expose a native +`to_flink_table(table_env)` retrieval job hand Flink tables directly to the +engine. Retrieval jobs that only expose the standard Arrow path are also +supported and are converted into Flink tables by the engine. The engine then +uses Flink Table/SQL operations for join, filter, aggregate, dedupe, and +projection steps, and writes materialization results to the configured online +and/or offline store. + +## Configuration + +Install the Flink extra from a Feast source checkout with `uv` before using the +engine: + +```bash +uv sync --extra flink --no-dev +``` + +The `flink` extra installs PyFlink directly. PyFlink currently requires +`pyarrow<21`, while the default Feast install keeps `pyarrow>=21`; Feast's uv +lock resolves the Flink extra in a separate dependency fork so normal Feast +installs do not downgrade Arrow. + +Configure the engine in `feature_store.yaml`: + +```yaml +project: my_project +registry: data/registry.db +provider: local +offline_store: + type: file +online_store: + type: sqlite + path: data/online_store.db +batch_engine: + type: flink.engine + execution_mode: batch + parallelism: 4 + table_config: + pipeline.name: "Feast Flink Compute Engine" + pandas_split_num: 4 +``` + +## Configuration Options + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `type` | string | `flink.engine` | Must be `flink.engine`. | +| `execution_mode` | string | `batch` | PyFlink execution mode: `batch` or `streaming`. | +| `parallelism` | integer | `null` | Default Flink parallelism for jobs created by the engine. | +| `table_config` | map | `null` | Additional PyFlink table configuration entries. | +| `pandas_split_num` | integer | `1` | Number of PyFlink Arrow source splits when converting pandas entity DataFrames into Flink tables. | + +## Flink Transformations + +Use `mode="flink"` when a `BatchFeatureView` transformation should receive and +return PyFlink table objects: + +```python +from feast import BatchFeatureView, Field +from feast.types import Float32 + + +def double_rates(table): + # In production this can use PyFlink Table API operations and return a table. + return table + + +driver_stats = BatchFeatureView( + name="driver_stats", + entities=[driver], + mode="flink", + udf=double_rates, + schema=[Field(name="conv_rate", dtype=Float32)], + source=driver_stats_source, + online=True, +) +``` + +Flink transformations must return PyFlink table objects. pandas-returning UDFs +are not accepted by the Flink compute engine. + +## DAG Support + +The Flink engine implements Feast's compute DAG with Flink-specific nodes: + +- Source reads from Feast offline stores, preferring native Flink tables when a + retrieval job supports `to_flink_table(table_env)` and otherwise converting + Arrow results into Flink tables. +- Transform nodes pass PyFlink tables to `mode="flink"` UDFs and preserve native + Flink table outputs. +- Join nodes use Flink SQL temporary views for feature joins and entity joins. +- Filter nodes apply point-in-time, TTL, and custom filter expressions in Flink + SQL. +- Aggregate nodes support non-windowed Feast aggregations using Flink SQL + aggregate functions. +- Dedupe nodes use `ROW_NUMBER()` over entity keys or internal entity-row ids so + historical retrieval keeps one latest feature row per entity row. +- Validation nodes check required output columns. JSON value validation must be + handled upstream in Flink SQL. +- Output nodes write only for materialization tasks; historical retrieval is + read-only. +- Historical retrieval accepts pandas entity DataFrames and SQL-string entity + DataFrames. SQL strings are interpreted as Flink SQL queries against the + configured TableEnvironment/catalog and must select an `event_timestamp` + column. + +## Current Limitations + +- Windowed aggregations are not yet implemented in the Flink compute engine. Use + non-windowed Feast aggregations or pre-window upstream in Flink. +- JSON value validation is not implemented inside the Flink compute engine + because the engine does not collect intermediate data out of Flink for + validation. diff --git a/docs/reference/compute-engine/ray.md b/docs/reference/compute-engine/ray.md index 22b1e1a4700..19604e21788 100644 --- a/docs/reference/compute-engine/ray.md +++ b/docs/reference/compute-engine/ray.md @@ -28,6 +28,7 @@ The Ray compute engine provides: - **Lazy Evaluation**: Deferred execution for optimal performance - **Resource Management**: Automatic scaling and resource optimization - **Point-in-Time Joins**: Efficient temporal joins for historical feature retrieval +- **GPU Support**: Schedule transformation workers on GPU nodes via `num_gpus` config (all modes including KubeRay) ## Architecture @@ -87,6 +88,9 @@ batch_engine: | `enable_distributed_joins` | boolean | true | Enable distributed joins for large datasets | | `staging_location` | string | None | Remote path for batch materialization jobs | | `ray_conf` | dict | None | Ray configuration parameters (memory, CPU limits) | +| `num_gpus` | float | None | Number of GPUs to request per worker task. Requires GPU nodes in the Ray cluster. Fractional values (e.g. `0.5`) are supported. Supported in all modes including KubeRay. | +| `gpu_batch_format` | string | `"pandas"` | Batch format for `map_batches` when `num_gpus` is set. Use `"numpy"` or `"pyarrow"` for GPU-native libraries (e.g. cuDF, PyTorch). | +| `worker_task_options` | dict | None | Arbitrary Ray `.options()` kwargs applied to every worker task. See [Worker Resource Scheduling](#worker-resource-scheduling) for the full reference. | ### Mode Detection Precedence @@ -344,6 +348,7 @@ import ray # Check cluster resources resources = ray.cluster_resources() print(f"Available CPUs: {resources.get('CPU', 0)}") +print(f"Available GPUs: {resources.get('GPU', 0)}") print(f"Available memory: {resources.get('memory', 0) / 1e9:.2f} GB") # Monitor job progress @@ -351,6 +356,89 @@ job = store.get_historical_features(...) # Ray compute engine provides built-in progress tracking ``` +## Worker Resource Scheduling + +`worker_task_options` is a passthrough dict of [Ray `.options()` kwargs](https://docs.ray.io/en/latest/ray-core/api/doc/ray.remote_function.RemoteFunction.options.html) applied to every worker task Feast dispatches. It pairs with `ray_conf` (cluster-level `ray.init` options) — `worker_task_options` targets individual worker tasks. Options are forwarded at two levels so Ray schedules correctly: + +1. On the `@ray.remote` orchestration task via `.options(**worker_task_options)` — controls node selection. +2. Inside `map_batches` for the scheduling-relevant subset (`num_gpus`, `num_cpus`, `accelerator_type`, `resources`) — controls which nodes run the data workers. + +This is supported across **all execution modes**: local, remote, and KubeRay. + +### Common `worker_task_options` keys + +| Key | Type | Description | +|-----|------|-------------| +| `num_cpus` | float | CPUs per task (default: 1). Fractional values supported. | +| `memory` | int | Heap memory in **bytes** (e.g. `8589934592` for 8 GB). | +| `accelerator_type` | string | Pin tasks to a specific GPU model — `"A100"`, `"T4"`, `"V100"`, etc. Useful on KubeRay clusters with mixed GPU node pools. | +| `resources` | dict | Custom/Kubernetes extended resource labels, e.g. `{"intel.com/gpu": 1}`. | +| `runtime_env` | dict | Per-task [Ray runtime environment](https://docs.ray.io/en/latest/ray-core/handling-dependencies.html) — `pip`, `conda`, `env_vars`, `working_dir`, etc. For KubeRay, use this to install packages on worker pods without rebuilding images. | +| `max_retries` | int | Task retry count on worker failure (default: 3). | +| `scheduling_strategy` | string | `"DEFAULT"`, `"SPREAD"`, or a placement group strategy. | + +> For the full list of supported keys see the [Ray RemoteFunction.options() API docs](https://docs.ray.io/en/latest/ray-core/api/doc/ray.remote_function.RemoteFunction.options.html). + +### GPU support + +`num_gpus` is the only first-class GPU field because it also drives `gpu_batch_format` selection inside Feast. Set it directly rather than inside `worker_task_options`: + +```yaml +batch_engine: + type: ray.engine + num_gpus: 1 # GPUs per task (fractional values like 0.5 supported) + gpu_batch_format: numpy # numpy/pyarrow for GPU-native libs (cuDF, PyTorch) +``` + +When `num_gpus` is set your transformation UDF runs on a GPU worker: + +```python +import cudf # RAPIDS cuDF – GPU-accelerated DataFrame library + +def gpu_transform(batch): + gpu_df = cudf.from_pandas(batch) + gpu_df["score"] = gpu_df["raw_value"] * 2.0 + return gpu_df.to_pandas() +``` + +### Full example — KubeRay with GPU + all common options + +```yaml +batch_engine: + type: ray.engine + use_kuberay: true + kuberay_conf: + cluster_name: "feast-gpu-cluster" + namespace: "feast-system" + auth_token: "${RAY_AUTH_TOKEN}" + auth_server: "https://api.openshift.com:6443" + num_gpus: 1 + gpu_batch_format: numpy + worker_task_options: + num_cpus: 4 + memory: 8589934592 # 8 GB + accelerator_type: "A100" # pin to A100 nodes on mixed GPU pool + max_retries: 5 + runtime_env: + pip: + - cudf-cu12==24.10.0 + - torch==2.4.0 + env_vars: + CUDA_VISIBLE_DEVICES: "0" +``` + +### Checking cluster resources + +```python +import ray + +ray.init(address="auto") +resources = ray.cluster_resources() +print(f"Available CPUs: {resources.get('CPU', 0)}") +print(f"Available GPUs: {resources.get('GPU', 0)}") +print(f"Available memory: {resources.get('memory', 0) / 1e9:.2f} GB") +``` + ## Integration Examples ### With Spark Offline Store diff --git a/docs/reference/data-sources/README.md b/docs/reference/data-sources/README.md index 53e1920e254..24bf18dbe86 100644 --- a/docs/reference/data-sources/README.md +++ b/docs/reference/data-sources/README.md @@ -58,6 +58,18 @@ Please see [Data Source](../../getting-started/concepts/data-ingestion.md) for a [clickhouse.md](clickhouse.md) {% endcontent-ref %} +{% content-ref url="athena.md" %} +[athena.md](athena.md) +{% endcontent-ref %} + {% content-ref url="oracle.md" %} [oracle.md](oracle.md) {% endcontent-ref %} + +{% content-ref url="ray.md" %} +[ray.md](ray.md) +{% endcontent-ref %} + +{% content-ref url="mongodb.md" %} +[mongodb.md](mongodb.md) +{% endcontent-ref %} diff --git a/docs/reference/data-sources/athena.md b/docs/reference/data-sources/athena.md new file mode 100644 index 00000000000..d3ca67dcb10 --- /dev/null +++ b/docs/reference/data-sources/athena.md @@ -0,0 +1,37 @@ +# Athena source (contrib) + +## Description + +Athena data sources are AWS Athena tables or views. +These can be specified either by a table reference or a SQL query. + +## Disclaimer + +The Athena data source does not achieve full test coverage. +Please do not assume complete stability. + +## Examples + +Defining an Athena source: + +```python +from feast.infra.offline_stores.contrib.athena_offline_store.athena_source import ( + AthenaSource, +) + +driver_stats_source = AthenaSource( + name="driver_hourly_stats", + table="driver_hourly_stats", + database="my_database", + data_source="AwsDataCatalog", + timestamp_field="event_timestamp", + created_timestamp_column="created", +) +``` + +The full set of configuration options is available [here](https://rtd.feast.dev/en/master/#feast.infra.offline_stores.contrib.athena_offline_store.athena_source.AthenaSource). + +## Supported Types + +Athena data sources support standard Athena types mapped through the AWS Athena API. +For a comparison against other batch data sources, please see [here](overview.md#functionality-matrix). diff --git a/docs/reference/data-sources/kafka.md b/docs/reference/data-sources/kafka.md index 8794c7a1e81..dd7203a6149 100644 --- a/docs/reference/data-sources/kafka.md +++ b/docs/reference/data-sources/kafka.md @@ -72,4 +72,4 @@ def driver_hourly_stats_stream(df: DataFrame): ``` ### Ingesting data -See [here](https://github.com/feast-dev/streaming-tutorial) for a example of how to ingest data from a Kafka source into Feast. +See [here](https://github.com/feast-dev/streaming-tutorial) for an example of how to ingest data from a Kafka source into Feast. diff --git a/docs/reference/data-sources/kinesis.md b/docs/reference/data-sources/kinesis.md index f2adadfec03..09706617da9 100644 --- a/docs/reference/data-sources/kinesis.md +++ b/docs/reference/data-sources/kinesis.md @@ -71,4 +71,4 @@ def driver_hourly_stats_stream(df: DataFrame): ``` ### Ingesting data -See [here](https://github.com/feast-dev/streaming-tutorial) for a example of how to ingest data from a Kafka source into Feast. The approach used in the tutorial can be easily adapted to work for Kinesis as well. +See [here](https://github.com/feast-dev/streaming-tutorial) for an example of how to ingest data from a Kafka source into Feast. The approach used in the tutorial can be easily adapted to work for Kinesis as well. diff --git a/docs/reference/data-sources/mongodb.md b/docs/reference/data-sources/mongodb.md new file mode 100644 index 00000000000..8902affd3c5 --- /dev/null +++ b/docs/reference/data-sources/mongodb.md @@ -0,0 +1,103 @@ +# MongoDB source (contrib) + +## Description + +MongoDB data sources are [MongoDB](https://www.mongodb.com/) collections that can be used as a source for feature data. The `MongoDBSource` points at a MongoDB collection and provides the metadata Feast needs to read historical features from the offline store's collection. + +## Examples + +Defining a MongoDB source: + +```python +from feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb import ( + MongoDBSource, +) + +driver_stats_source = MongoDBSource( + name="driver_stats", + timestamp_field="event_timestamp", + created_timestamp_column="created_at", +) +``` + +The `name` field becomes the `feature_view` discriminator stored in every document in the `feature_history` collection. + +Configuration options such as `connection_string`, `database`, and `collection` are inherited from the offline store configuration in `feature_store.yaml`. + +The full set of configuration options is available [here](https://rtd.feast.dev/en/master/#feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBSource). + +## Vector Search + +The MongoDB online store supports [MongoDB Vector Search](https://www.mongodb.com/docs/atlas/atlas-vector-search/), enabling similarity search over feature embeddings stored in MongoDB. This is powered by the `$vectorSearch` aggregation stage and supports MongoDB Atlas, self-hosted MongoDB with Atlas Search indexes, and the `mongodb/mongodb-atlas-local` Docker image for local development. + +### Configuration + +Enable vector search in your `feature_store.yaml`: + +```yaml +project: my_project +provider: local +online_store: + type: mongodb + connection_string: mongodb+srv://:@cluster.mongodb.net # pragma: allowlist secret + vector_enabled: true + similarity: cosine # cosine | euclidean | dotProduct + vector_index_wait_timeout: 60 # seconds to wait for index to become queryable + vector_index_wait_poll_interval: 1.0 # seconds between polls +``` + +### Defining a Feature View with Vector Index + +Mark embedding fields with `vector_index=True` and specify `vector_length`: + +```python +from feast import Entity, FeatureView, Field, FileSource +from feast.types import Array, Float32, Int64, String +from datetime import timedelta + +item_embeddings = FeatureView( + name="item_embeddings", + entities=[Entity(name="item_id", join_keys=["item_id"])], + schema=[ + Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=384, + vector_search_metric="cosine", + ), + Field(name="title", dtype=String), + Field(name="item_id", dtype=Int64), + ], + source=FileSource(path="items.parquet", timestamp_field="event_timestamp"), + ttl=timedelta(hours=24), +) +``` + +When `feast apply` (or `store.update()`) runs with `vector_enabled=True`, MongoDB vector search indexes are automatically created for any field with `vector_index=True`. Indexes are also automatically dropped when feature views are removed. + +### Retrieving Documents via Vector Search + +Use `retrieve_online_documents_v2()` to perform similarity search: + +```python +store = FeatureStore(repo_path=".") +results = store.retrieve_online_documents_v2( + features=["item_embeddings:embedding", "item_embeddings:title"], + query=[0.1, 0.2, ...], # query vector + top_k=5, +) +``` + +### How It Works + +- **Index creation**: `update()` creates a MongoDB vector search index named `____vs_index` for each vector-indexed field. It waits for the index to reach `READY` status before proceeding. +- **Query execution**: `retrieve_online_documents_v2()` builds a `$vectorSearch` aggregation pipeline with `numCandidates = max(top_k * 10, 100)` and the specified `limit`. +- **Score**: Results include a `distance` field populated from `$meta: "vectorSearchScore"`. +- **BSON compatibility**: Query vectors are coerced to native Python floats to avoid numpy serialization issues. +- **Idempotency**: Calling `update()` multiple times will not duplicate indexes. + +## Supported Types + +MongoDB data sources support all eight primitive types (`bytes`, `string`, `int32`, `int64`, `float32`, `float64`, `bool`, `timestamp`) and their corresponding array types. Complex types such as `Map` and `Struct` are preserved through the MongoDB document model. +For a comparison against other batch data sources, please see [here](overview.md#functionality-matrix). diff --git a/docs/reference/data-sources/overview.md b/docs/reference/data-sources/overview.md index 7cffc4154dd..5cc5285f77e 100644 --- a/docs/reference/data-sources/overview.md +++ b/docs/reference/data-sources/overview.md @@ -5,7 +5,7 @@ In Feast, each batch data source is associated with corresponding offline stores. For example, a `SnowflakeSource` can only be processed by the Snowflake offline store, while a `FileSource` can be processed by both File and DuckDB offline stores. Otherwise, the primary difference between batch data sources is the set of supported types. -Feast has an internal type system, and aims to support eight primitive types (`bytes`, `string`, `int32`, `int64`, `float32`, `float64`, `bool`, and `timestamp`) along with the corresponding array types. +Feast has an internal type system that supports primitive types (`bytes`, `string`, `int32`, `int64`, `float32`, `float64`, `bool`, `timestamp`), array types, set types, map/JSON types, and struct types. However, not every batch data source supports all of these types. For more details on the Feast type system, see [here](../type-system.md). @@ -29,3 +29,9 @@ Below is a matrix indicating which data sources support which types. | `bool` | yes | yes | yes | yes | yes | yes | yes | yes | | `timestamp` | yes | yes | yes | yes | yes | yes | yes | yes | | array types | yes | yes | yes | no | yes | yes | yes | no | +| `Map` | yes | no | yes | yes | yes | yes | yes | no | +| `Json` | yes | yes | yes | yes | yes | no | no | no | +| `Struct` | yes | yes | no | no | yes | yes | no | no | +| set types | yes* | no | no | no | no | no | no | no | + +\* **Set types** are defined in Feast's proto and Python type system but are **not inferred** by any backend. They must be explicitly declared in the feature view schema and are best suited for online serving use cases. See [Type System](../type-system.md#set-types) for details. diff --git a/docs/reference/data-sources/ray.md b/docs/reference/data-sources/ray.md new file mode 100644 index 00000000000..30d4880a58a --- /dev/null +++ b/docs/reference/data-sources/ray.md @@ -0,0 +1,233 @@ +# Ray Data Source (contrib) + +> **⚠️ Contrib Plugin:** +> `RaySource` is a contributed plugin shipped alongside the [Ray offline store](../offline-stores/ray.md). It may not be as stable or fully supported as core data sources. + +`RaySource` is a pure-metadata descriptor that tells Feast **how** to load a +[Ray Dataset](https://docs.ray.io/en/latest/data/api/dataset.html) from any +source that Ray Data supports natively — Parquet, CSV, JSON, HuggingFace +Datasets, MongoDB, binary files, images, TFRecords, and more. + +It is the recommended data source when using the +[Ray offline store](../offline-stores/ray.md) and replaces the need for +`FileSource` for all non-Parquet and non-file-based data. + +--- + +## When to use RaySource vs FileSource + +| Scenario | Recommended source | +|---|---| +| Parquet files on disk / S3 / GCS (existing setup) | `FileSource` (backward compatible) | +| Parquet via Ray reader (pipelines, remote auth) | `RaySource(reader_type="parquet")` | +| CSV, JSON, text, images via Ray | `RaySource` | +| HuggingFace `datasets` library | `RaySource(reader_type="huggingface")` | +| MongoDB, SQL, TFRecords, WebDataset | `RaySource` | + +--- + +## Installation + +`RaySource` is bundled with the Ray offline store contrib package: + +```bash +pip install 'feast[ray]' +``` + +--- + +## Supported `reader_type` values + +| `reader_type` | Underlying Ray API | Notes | +|---|---|---| +| `parquet` | `ray.data.read_parquet` | S3, GCS, HDFS, local | +| `csv` | `ray.data.read_csv` | | +| `json` | `ray.data.read_json` | | +| `text` | `ray.data.read_text` | | +| `images` | `ray.data.read_images` | | +| `binary_files` | `ray.data.read_binary_files` | | +| `tfrecords` | `ray.data.read_tfrecords` | | +| `webdataset` | `ray.data.read_webdataset` | | +| `huggingface` | `ray.data.from_huggingface` | Wraps `datasets.load_dataset` | +| `mongo` | `ray.data.read_mongo` | | +| `sql` | `ray.data.read_sql` | Pass `connection_url` in `reader_options` | + +--- + +## Configuration + +### Parameters + +| Parameter | Type | Required | Description | +|---|---|---|---| +| `name` | `str` | Yes | Unique name for this data source | +| `reader_type` | `str` | Yes | One of the supported reader types above | +| `path` | `str` | No | File or directory path (required for file-based readers) | +| `reader_options` | `dict` | No | Extra keyword arguments forwarded to the Ray reader | +| `timestamp_field` | `str` | No | Column containing event timestamps | +| `created_timestamp_column` | `str` | No | Column containing row creation timestamps | +| `tags` | `dict` | No | Arbitrary key-value metadata | +| `description` | `str` | No | Human-readable description | +| `owner` | `str` | No | Owning team or contact | + +--- + +## Usage examples + +### Parquet on S3 + +```python +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import RaySource + +driver_stats = RaySource( + name="driver_stats_parquet", + reader_type="parquet", + path="s3://my-bucket/driver_stats/", + timestamp_field="event_timestamp", +) +``` + +### CSV + +```python +sensor_readings = RaySource( + name="sensor_readings_csv", + reader_type="csv", + path="/data/sensors/", + timestamp_field="ts", +) +``` + +### HuggingFace dataset + +Load a dataset from the [HuggingFace Hub](https://huggingface.co/datasets) +directly into Feast. + +```python +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import RaySource + +cheque_images = RaySource( + name="cheque_images_hf", + reader_type="huggingface", + reader_options={ + "dataset_name": "cheques_sample_data", + "split": "train", + }, + timestamp_field="event_timestamp", +) +``` + +### MongoDB + +```python +transaction_log = RaySource( + name="transactions_mongo", + reader_type="mongo", + reader_options={ + "uri": "mongodb://localhost:27017", + "database": "featuredb", + "collection": "transactions", + }, + timestamp_field="created_at", +) +``` + +### SQL (via connection URL) + +```python +user_features = RaySource( + name="user_features_sql", + reader_type="sql", + reader_options={ + "connection_url": "postgresql+psycopg2://user:password@host:5432/db", # pragma: allowlist secret + "query": "SELECT * FROM user_features", + }, + timestamp_field="event_timestamp", +) +``` + +--- + +## Using RaySource in a BatchFeatureView + +```python +from datetime import timedelta +from feast import BatchFeatureView, Entity, Field +from feast.types import Float32, Int64, String +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import RaySource + +cheque = Entity(name="cheque_id", description="Unique cheque identifier") + +cheque_source = RaySource( + name="cheque_images_hf", + reader_type="huggingface", + reader_options={ + "dataset_name": "cheques_sample_data", + "split": "train", + }, + timestamp_field="event_timestamp", +) + +cheque_ocr_fv = BatchFeatureView( + name="cheque_ocr_features", + entities=[cheque], + ttl=timedelta(days=365), + schema=[ + Field(name="cheque_id", dtype=Int64), + Field(name="payee_name", dtype=String), + Field(name="amount", dtype=String), + Field(name="bank_name", dtype=String), + Field(name="raw_text", dtype=String), + ], + source=cheque_source, +) +``` + +--- + +## Retrieving data as a Ray Dataset + +Once the feature view is materialised you can retrieve the offline features +directly as a Ray Dataset using the first-class `to_ray_dataset()` method: + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +# Chain directly on the retrieval job — to_ray_dataset() is a first-class +# method on every RetrievalJobs. +ds = store.get_historical_features( + features=["cheque_ocr_features:payee_name", "cheque_ocr_features:amount"], + entity_df=entity_df, +).to_ray_dataset() + +# Use the dataset downstream in Ray or ML pipelines +ds.show(3) +``` + +--- + +## Proto serialisation + +`RaySource` is fully serialisable to Feast's protobuf registry format. The +`reader_type`, `path`, and `reader_options` dict are all persisted and can be +round-tripped via `to_proto()` / `from_proto()`. + +--- + +## Limitations + +* The Ray offline store (and therefore `RaySource`) requires `feast[ray]`. +* `reader_type="sql"` requires a serialisable `connection_url`; raw + `sqlalchemy.engine.Engine` objects cannot be pickled across Ray workers. +* Streaming sources (Kafka, Kinesis) are not supported via `RaySource`; use + the dedicated [Kafka](kafka.md) or [Kinesis](kinesis.md) data sources. + +--- + +## Related pages + +* [Ray Offline Store](../offline-stores/ray.md) +* [Ray Compute Engine](../compute-engine/ray.md) +* [Feature Retrieval](../../getting-started/concepts/feature-retrieval.md) diff --git a/docs/reference/dqm.md b/docs/reference/dqm.md index 5a02413e534..51f98686dee 100644 --- a/docs/reference/dqm.md +++ b/docs/reference/dqm.md @@ -1,67 +1,50 @@ # Data Quality Monitoring -Data Quality Monitoring (DQM) is a Feast module aimed to help users to validate their data with the user-curated set of rules. -Validation could be applied during: -* Historical retrieval (training dataset generation) -* [planned] Writing features into an online store -* [planned] Reading features from an online store +{% hint style="warning" %} +**Deprecated:** The Great Expectations-based validation described on this page is deprecated and will be removed in a future release. It has been superseded by Feast's built-in [Feature Quality Monitoring](../how-to-guides/feature-monitoring.md) system, which provides richer metrics (histograms, percentiles, drift detection), works across batch data and serving logs, requires no external dependencies, and includes a built-in UI dashboard. -Its goal is to address several complex data problems, namely: -* Data consistency - new training datasets can be significantly different from previous datasets. This might require a change in model architecture. -* Issues/bugs in the upstream pipeline - bugs in upstream pipelines can cause invalid values to overwrite existing valid values in an online store. -* Training/serving skew - distribution shift could significantly decrease the performance of the model. +Please migrate to the new monitoring system. See the [Feature Quality Monitoring guide](../how-to-guides/feature-monitoring.md) for setup instructions. +{% endhint %} -> To monitor data quality, we check that the characteristics of the tested dataset (aka the tested dataset's profile) are "equivalent" to the characteristics of the reference dataset. -> How exactly profile equivalency should be measured is up to the user. +## Legacy: Great Expectations Integration + +The following documents the deprecated Great Expectations-based validation that was previously the only DQM option in Feast. This integration relied on `pip install 'feast[ge]'` and only supported validation during historical retrieval. + +--- ### Overview -The validation process consists of the following steps: -1. User prepares reference dataset (currently only [saved datasets](../getting-started/concepts/dataset.md) from historical retrieval are supported). -2. User defines profiler function, which should produce profile by given dataset (currently only profilers based on [Great Expectations](https://docs.greatexpectations.io) are allowed). -3. Validation of tested dataset is performed with reference dataset and profiler provided as parameters. +The legacy validation process consists of the following steps: +1. User prepares reference dataset (only [saved datasets](../getting-started/concepts/dataset.md) from historical retrieval are supported). +2. User defines a profiler function that produces a profile using [Great Expectations](https://docs.greatexpectations.io). +3. Validation of the tested dataset is performed with the reference dataset and profiler provided as parameters. -### Preparations -Feast with Great Expectations support can be installed via +### Installation ```shell pip install 'feast[ge]' ``` ### Dataset profile -Currently, Feast supports only [Great Expectation's](https://greatexpectations.io/) [ExpectationSuite](https://legacy.docs.greatexpectations.io/en/latest/autoapi/great_expectations/core/expectation_suite/index.html#great_expectations.core.expectation_suite.ExpectationSuite) -as dataset's profile. Hence, the user needs to define a function (profiler) that would receive a dataset and return an [ExpectationSuite](https://legacy.docs.greatexpectations.io/en/latest/autoapi/great_expectations/core/expectation_suite/index.html#great_expectations.core.expectation_suite.ExpectationSuite). -Great Expectations supports automatic profiling as well as manually specifying expectations: +This integration uses [Great Expectation's](https://greatexpectations.io/) [ExpectationSuite](https://legacy.docs.greatexpectations.io/en/latest/autoapi/great_expectations/core/expectation_suite/index.html#great_expectations.core.expectation_suite.ExpectationSuite) +as the dataset profile format. The user defines a profiler function that receives a dataset and returns an ExpectationSuite. + ```python from great_expectations.dataset import Dataset from great_expectations.core.expectation_suite import ExpectationSuite from feast.dqm.profilers.ge_profiler import ge_profiler -@ge_profiler -def automatic_profiler(dataset: Dataset) -> ExpectationSuite: - from great_expectations.profile.user_configurable_profiler import UserConfigurableProfiler - - return UserConfigurableProfiler( - profile_dataset=dataset, - ignored_columns=['conv_rate'], - value_set_threshold='few' - ).build_suite() -``` -However, from our experience capabilities of automatic profiler are quite limited. So we would recommend crafting your own expectations: -```python @ge_profiler def manual_profiler(dataset: Dataset) -> ExpectationSuite: dataset.expect_column_max_to_be_between("column", 1, 2) return dataset.get_expectation_suite() ``` - - ### Validating Training Dataset + During retrieval of historical features, `validation_reference` can be passed as a parameter to methods `.to_df(validation_reference=...)` or `.to_arrow(validation_reference=...)` of RetrievalJob. -If parameter is provided Feast will run validation once dataset is materialized. In case if validation successful materialized dataset is returned. -Otherwise, `feast.dqm.errors.ValidationFailed` exception would be raised. It will consist of all details for expectations that didn't pass. +If validation is successful, the materialized dataset is returned. Otherwise, `feast.dqm.errors.ValidationFailed` exception is raised with details for expectations that didn't pass. ```python from feast import FeatureStore @@ -75,3 +58,32 @@ job.to_df( .as_reference(profiler=manual_profiler) ) ``` + +--- + +## Migration Guide + +The new [Feature Quality Monitoring](../how-to-guides/feature-monitoring.md) system replaces this integration with: + +| Capability | GE-based (deprecated) | New DQM | +|---|---|---| +| Scope | Historical retrieval only | Batch data + serving logs | +| Dependencies | `feast[ge]` extra required | No extra dependencies | +| Metrics | User-defined expectations | Automatic: null rates, percentiles, histograms, drift | +| UI | None | Built-in monitoring dashboard | +| Automation | Manual profiler code | `feast monitor run` CLI + REST API | +| Backends | Limited | All offline store backends | + +To migrate: + +1. Enable DQM in `feature_store.yaml`: + ```yaml + data_quality_monitoring: + auto_baseline: true + ``` + +2. Run `feast apply` to compute baseline metrics automatically. + +3. Schedule `feast monitor run` for ongoing monitoring. + +4. Remove the `feast[ge]` dependency from your requirements. diff --git a/docs/reference/feast-cli-commands.md b/docs/reference/feast-cli-commands.md index eb6fa90d280..99a99ab1707 100644 --- a/docs/reference/feast-cli-commands.md +++ b/docs/reference/feast-cli-commands.md @@ -21,6 +21,7 @@ Commands: apply Create or update a feature store deployment configuration Display Feast configuration delete Delete a Feast object from the registry + demo-notebooks Generate demo Jupyter notebooks for the project entities Access entities feature-views Access feature views init Create a new Feast repository @@ -142,6 +143,47 @@ The delete operation is permanent and will remove the object from the registry. If multiple objects have the same name across different types, `feast delete` will delete the first one it finds. For programmatic deletion with more control, use the Python SDK methods like `store.delete_feature_view()`, `store.delete_feature_service()`, etc. {% endhint %} +## Demo Notebooks + +Generate tailored demo Jupyter notebooks for each Feast project found in the current directory. + +```bash +feast demo-notebooks +``` + +The command searches for `feature_store.yaml` in the current directory and every file inside the `feast-config/` directory. Each file is treated as a separate project config, and notebooks are created under `./feast-demo-notebooks//`. + +The generated notebooks adapt to your project configuration (online/offline store types, authentication, vector search) and cover: + +* **Feature store overview** — explore registered entities, feature views, and services. +* **Historical feature retrieval** — build training datasets with point-in-time correct joins. +* **Online feature serving** — materialize features and retrieve them at low latency. + +**Options:** + +* `-o, --output-dir` — Directory where the notebooks are written. Default: `./feast-demo-notebooks`. +* `--overwrite` — Overwrite existing notebooks if the output directory already exists. + +```bash +feast demo-notebooks -o ./my-notebooks --overwrite +``` + +You can also use the `--chdir` global option to point at a different feature repository: + +```bash +feast -c /path/to/feature_repo demo-notebooks +``` + +The same functionality is available via the Python SDK: + +```python +from feast import copy_demo_notebooks + +copy_demo_notebooks(output_dir="./feast-demo-notebooks", repo_path=".") +``` + +For more details see the [Demo Notebooks tutorial](../tutorials/demo-notebooks.md). + ## Entities List all registered entities @@ -176,6 +218,18 @@ NAME ENTITIES TYPE driver_hourly_stats {'driver'} FeatureView ``` +List version history for a feature view + +```text +feast feature-views list-versions FEATURE_VIEW_NAME +``` + +```text +VERSION TYPE CREATED VERSION_ID +v0 feature_view 2024-01-15 10:30:00 a1b2c3d4-... +v1 feature_view 2024-01-16 14:22:00 e5f6g7h8-... +``` + ## Init Creates a new feature repository diff --git a/docs/reference/feature-repository/README.md b/docs/reference/feature-repository/README.md index 2c1b112a783..38968825c1d 100644 --- a/docs/reference/feature-repository/README.md +++ b/docs/reference/feature-repository/README.md @@ -127,4 +127,4 @@ To declare new feature definitions, just add code to the feature repository, eit ### Next steps * See [Create a feature repository](../../how-to-guides/feast-snowflake-gcp-aws/create-a-feature-repository.md) to get started with an example feature repository. -* See [feature_store.yaml](feature-store-yaml.md), [.feastignore](feast-ignore.md), or [Feature Views](../../getting-started/concepts/feature-view.md) for more information on the configuration files that live in a feature registry. +* See [feature_store.yaml](feature-store-yaml.md), [.feastignore](feast-ignore.md), [Registration inferencing](registration-inferencing.md), or [Feature Views](../../getting-started/concepts/feature-view.md) for more information on the configuration files that live in a feature registry. diff --git a/docs/reference/feature-repository/feature-store-yaml.md b/docs/reference/feature-repository/feature-store-yaml.md index a87e09ba43e..aec6082b383 100644 --- a/docs/reference/feature-repository/feature-store-yaml.md +++ b/docs/reference/feature-repository/feature-store-yaml.md @@ -25,5 +25,69 @@ The following top-level configuration options exist in the `feature_store.yaml` * **offline_store** — Configures the offline store. * **project** — Defines a namespace for the entire feature store. Can be used to isolate multiple deployments in a single installation of Feast. Should only contain letters, numbers, and underscores. * **engine** - Configures the batch materialization engine. +* **materialization** - Configures materialization behavior (write batching, feature pull strategy). See below. Please see the [RepoConfig](https://rtd.feast.dev/en/latest/#feast.repo_config.RepoConfig) API reference for the full list of configuration options. + +--- + +## `materialization` configuration + +The `materialization` block controls how Feast reads from the offline store and writes to the online store during `feast materialize` / `feast materialize-incremental` runs. + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: redis + connection_string: "localhost:6379" +materialization: + online_write_batch_size: 10000 # write rows in chunks of 10 000 + pull_latest_features: false # pull full time range (default) +``` +{% endcode %} + +### `online_write_batch_size` + +| Field | Type | Default | Supported engines | +| --- | --- | --- | --- | +| `online_write_batch_size` | `int` (positive) | `null` | local, spark, ray | + +Controls how many rows are converted to protobuf and written to the online store per batch during materialization. + +**Default behaviour (`null`):** All rows fetched from the offline store are converted to protobuf in a single in-memory operation before writing. This is fast but can exhaust memory for large datasets — every row must be held as a Python proto object simultaneously. + +**With `online_write_batch_size` set:** The Arrow table returned by the offline store is split into chunks of at most `online_write_batch_size` rows. Each chunk is converted and written independently, keeping peak memory proportional to the batch size rather than the full dataset size. + +```yaml +# Recommended for datasets > a few million rows or memory-constrained workers +materialization: + online_write_batch_size: 10000 +``` + +**Choosing a value:** + +| Dataset size | Worker memory | Recommended batch size | +| --- | --- | --- | +| < 1 M rows | Any | `null` (default — single batch is fine) | +| 1–10 M rows | ≥ 4 GB | `50000` | +| 10–100 M rows | ≥ 8 GB | `10000` | +| > 100 M rows | Any | `5000`–`10000` | + +A smaller batch size reduces peak memory at the cost of more `online_write_batch` calls to the online store. For Redis, each call is a pipelined batch, so the overhead is low. For stores with higher per-call latency (e.g. DynamoDB), prefer larger batch sizes. + +{% hint style="info" %} +`online_write_batch_size` is applied **per feature view** within a single materialization job. If you materialize five feature views in parallel, peak memory is `5 × batch_size × bytes_per_row`. +{% endhint %} + +### `pull_latest_features` + +| Field | Type | Default | +| --- | --- | --- | +| `pull_latest_features` | `bool` | `false` | + +When `false` (default), the offline store retrieves **all** feature values within the requested time range for each entity. + +When `true`, only the **latest** value per entity is retrieved. This reduces I/O and memory for feature views where historical values are not needed (e.g., slowly changing dimensions). It is equivalent to running a `GROUP BY entity, MAX(event_timestamp)` on the offline data before writing. diff --git a/docs/reference/feature-servers/mcp-feature-server.md b/docs/reference/feature-servers/mcp-feature-server.md new file mode 100644 index 00000000000..8bfc96b1891 --- /dev/null +++ b/docs/reference/feature-servers/mcp-feature-server.md @@ -0,0 +1,51 @@ +# MCP Feature Server + +## Overview + +Feast can expose the Python Feature Server as an MCP (Model Context Protocol) server using `fastapi_mcp`. When enabled, MCP clients can discover and call Feast tools such as online feature retrieval. + +## Installation + +```bash +pip install feast[mcp] +``` + +## Configuration + +Add an MCP `feature_server` block to your `feature_store.yaml`: + +```yaml +feature_server: + type: mcp + enabled: true + mcp_enabled: true + mcp_transport: http + mcp_server_name: "feast-feature-store" + mcp_server_version: "1.0.0" +``` + +### mcp_transport + +`mcp_transport` controls how MCP is mounted into the Feature Server: + +- `sse`: SSE-based transport. This is the default for backward compatibility. +- `http`: Streamable HTTP transport. This is recommended for improved compatibility with some MCP clients. + +If `mcp_transport: http` is configured but your installed `fastapi_mcp` version does not support Streamable HTTP mounting, Feast will fail fast with an error asking you to upgrade `fastapi_mcp` (or reinstall `feast[mcp]`). + +## Endpoints + +MCP is mounted at: + +- `/mcp` + +## Connecting an MCP client + +Use your MCP client’s “HTTP” configuration and point it to the Feature Server base URL. For example, if your Feature Server runs at `http://localhost:6566`, use: + +- `http://localhost:6566/mcp` + +## Troubleshooting + +- If you see a deprecation warning about `mount()` at runtime, upgrade `fastapi_mcp` and use `mcp_transport: http` or `mcp_transport: sse`. +- If your MCP client has intermittent connectivity issues with `mcp_transport: sse`, switch to `mcp_transport: http`. diff --git a/docs/reference/feature-servers/python-feature-server.md b/docs/reference/feature-servers/python-feature-server.md index bf288b191ef..4802599866d 100644 --- a/docs/reference/feature-servers/python-feature-server.md +++ b/docs/reference/feature-servers/python-feature-server.md @@ -352,26 +352,128 @@ feature_server: push: true # push request counters materialization: true # materialization counters & duration freshness: true # feature freshness gauges + offline_features: true # offline store retrieval counters & latency + audit_logging: false # structured JSON audit logs (see below) ``` Any category set to `false` will emit no metrics and start no background threads (e.g., setting `freshness: false` prevents the registry polling -thread from starting). All categories default to `true`. +thread from starting). All categories default to `true` except +`audit_logging`, which defaults to `false`. ### Available metrics -| Metric | Type | Labels | Description | -|--------|------|--------|-------------| -| `feast_feature_server_cpu_usage` | Gauge | — | Process CPU usage % | -| `feast_feature_server_memory_usage` | Gauge | — | Process memory usage % | -| `feast_feature_server_request_total` | Counter | `endpoint`, `status` | Total requests per endpoint | -| `feast_feature_server_request_latency_seconds` | Histogram | `endpoint`, `feature_count`, `feature_view_count` | Request latency with p50/p95/p99 support | -| `feast_online_features_request_total` | Counter | — | Total online feature retrieval requests | -| `feast_online_features_entity_count` | Histogram | — | Entity rows per online feature request | -| `feast_push_request_total` | Counter | `push_source`, `mode` | Push requests by source and mode | -| `feast_materialization_total` | Counter | `feature_view`, `status` | Materialization runs (success/failure) | -| `feast_materialization_duration_seconds` | Histogram | `feature_view` | Materialization duration per feature view | -| `feast_feature_freshness_seconds` | Gauge | `feature_view`, `project` | Seconds since last materialization | +| Metric | Type | Labels | Category | Description | +|--------|------|--------|----------|-------------| +| `feast_feature_server_cpu_usage` | Gauge | — | `resource` | Process CPU usage % | +| `feast_feature_server_memory_usage` | Gauge | — | `resource` | Process memory usage % | +| `feast_feature_server_request_total` | Counter | `endpoint`, `status` | `request` | Total requests per endpoint | +| `feast_feature_server_request_latency_seconds` | Histogram | `endpoint`, `feature_count`, `feature_view_count` | `request` | Request latency with p50/p95/p99 support | +| `feast_online_features_request_total` | Counter | — | `online_features` | Total online feature retrieval requests | +| `feast_online_features_entity_count` | Histogram | — | `online_features` | Entity rows per online feature request | +| `feast_feature_server_online_store_read_duration_seconds` | Histogram | — | `online_features` | Online store read phase duration (sync and async) | +| `feast_feature_server_transformation_duration_seconds` | Histogram | `odfv_name`, `mode` | `online_features` | ODFV read-path transformation duration (requires `track_metrics=True` on the ODFV) | +| `feast_feature_server_write_transformation_duration_seconds` | Histogram | `odfv_name`, `mode` | `online_features` | ODFV write-path transformation duration (requires `track_metrics=True` on the ODFV) | +| `feast_push_request_total` | Counter | `push_source`, `mode` | `push` | Push requests by source and mode | +| `feast_materialization_result_total` | Counter | `feature_view`, `status` | `materialization` | Materialization runs (success/failure) | +| `feast_materialization_duration_seconds` | Histogram | `feature_view` | `materialization` | Materialization duration per feature view | +| `feast_feature_freshness_seconds` | Gauge | `feature_view`, `project` | `freshness` | Seconds since last materialization | +| `feast_offline_store_request_total` | Counter | `method`, `status` | `offline_features` | Total offline store retrieval requests | +| `feast_offline_store_request_latency_seconds` | Histogram | `method` | `offline_features` | Latency of offline store retrieval operations | +| `feast_offline_store_row_count` | Histogram | `method` | `offline_features` | Rows returned by offline store retrieval | + +### Per-ODFV transformation metrics + +The `transformation_duration_seconds` and `write_transformation_duration_seconds` +metrics are gated behind **two** conditions — both must be true for any +instrumentation to run: + +1. **Server-level**: the `online_features` category must be enabled in the + metrics configuration. +2. **ODFV-level**: the `OnDemandFeatureView` must have `track_metrics=True`. + +This defaults to `False`, so no ODFV incurs timing overhead unless explicitly +opted in: + +```python +from feast.on_demand_feature_view import on_demand_feature_view + +@on_demand_feature_view( + sources=[my_feature_view, my_request_source], + schema=[Field(name="output", dtype=Float64)], + track_metrics=True, # opt in to transformation timing +) +def my_transform(inputs: pd.DataFrame) -> pd.DataFrame: + ... +``` + +The `odfv_name` label lets you filter or group by individual ODFV, +and the `mode` label (`python`, `pandas`, `substrait`) lets you compare +transformation engines. + +### Audit logging + +Feast can emit structured JSON audit log entries for every online and offline +feature retrieval. These are written via the standard `feast.audit` Python +logger, so you can route them to a dedicated file, SIEM, or log aggregator +independently of application logs. + +Audit logging is **disabled by default**. Enable it in `feature_store.yaml`: + +```yaml +feature_server: + type: local + metrics: + enabled: true + audit_logging: true +``` + +**Online audit log** (emitted per `/get-online-features` call): + +```json +{ + "event": "online_feature_request", + "timestamp": "2026-05-11T08:30:00.123456+00:00", + "requestor_id": "user@example.com", + "entity_keys": ["driver_id"], + "entity_count": 3, + "feature_views": ["driver_hourly_stats"], + "feature_count": 3, + "status": "success", + "latency_ms": 12.34 +} +``` + +**Offline audit log** (emitted per `RetrievalJob.to_arrow()` call): + +```json +{ + "event": "offline_feature_retrieval", + "timestamp": "2026-05-11T08:31:00.456789+00:00", + "method": "to_arrow", + "start_time": "2026-05-11T08:30:59.226789+00:00", + "end_time": "2026-05-11T08:31:00.456789+00:00", + "feature_views": ["driver_hourly_stats"], + "feature_count": 3, + "row_count": 500, + "status": "success", + "duration_ms": 1230.0 +} +``` + +The `requestor_id` field in online audit logs is populated from the +security manager's current user when authentication is configured, and +falls back to `"anonymous"` otherwise. + +To route audit logs to a separate file: + +```python +import logging + +handler = logging.FileHandler("/var/log/feast/audit.log") +handler.setFormatter(logging.Formatter("%(message)s")) +logging.getLogger("feast.audit").addHandler(handler) +``` ### Scraping with Prometheus diff --git a/docs/reference/feature-store-yaml.md b/docs/reference/feature-store-yaml.md index 7411c673576..9c8975eb335 100644 --- a/docs/reference/feature-store-yaml.md +++ b/docs/reference/feature-store-yaml.md @@ -40,7 +40,7 @@ feature_server: enabled: true # Enable Prometheus metrics server on port 8000 resource: true # CPU / memory gauges request: true # endpoint latency histograms & request counters - online_features: true # online feature retrieval counters + online_features: true # online feature retrieval counters + store read & ODFV transform timing push: true # push request counters materialization: true # materialization counters & duration histograms freshness: true # per-feature-view freshness gauges @@ -49,6 +49,29 @@ feature_server: offline_push_batching_batch_interval_seconds: 5 # Maximum time rows may remain buffered before a forced flush. ``` +### registry + +The `registry` field can be a simple path string or an object with additional +configuration. When using the REST registry server, MCP support can be enabled: + +```yaml +registry: + registry_type: sql + path: postgresql+psycopg://feast:feast@localhost:5432/feast #pragma: allowlist secret + mcp: + enabled: true +``` + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `registry_type` | string | `file` | Registry backend (`file`, `sql`, etc.) | +| `path` | string | — | Connection string or file path | +| `mcp.enabled` | bool | `false` | Enable MCP (Model Context Protocol) on the REST registry server | + +When `registry.mcp.enabled` is `true`, the REST registry server exposes registry +metadata (entities, feature views, feature services) as MCP tool endpoints for +LLM agents. Requires `feast[mcp]` to be installed. + ## Providers The `provider` field defines the environment in which Feast will execute data flows. As a result, it also determines the default values for other fields. diff --git a/docs/reference/mlflow.md b/docs/reference/mlflow.md new file mode 100644 index 00000000000..6522478409c --- /dev/null +++ b/docs/reference/mlflow.md @@ -0,0 +1,347 @@ +# MLflow Integration + +Feast provides **native integration** with [MLflow](https://mlflow.org/) for automatic feature lineage tracking alongside ML experiments. When enabled, every feature retrieval is logged to the active MLflow run. + +## Overview + +- **Which features did this model use?** -- auto-logged on every `get_historical_features()` / `get_online_features()` call +- **Which feature service should I use to serve this model?** -- resolved from model URI via `store.mlflow.resolve_features()` +- **Can I reproduce the exact training data?** -- entity DataFrame saved as an MLflow artifact +- **Which models break if I change a feature view?** -- reverse index via the Feast UI `/api/mlflow-feature-usage` endpoint +- **When was the feature store last updated?** -- `feast apply` and `feast materialize` logged to a separate ops experiment + +### Capabilities + +| Capability | How | +|---|---| +| Auto-log feature metadata | Tags on every retrieval inside an active MLflow run | +| Entity DataFrame archival | `entity_df.parquet` artifact for full reproducibility | +| Model registration with lineage | `feast.feature_service` tag propagated to model versions | +| Training-to-prediction linkage | `store.mlflow.load_model()` links prediction runs back to training runs | +| Model-to-feature resolution | Map any model URI back to its Feast feature service | +| Operation audit trail | `feast apply` / `feast materialize` logged to `{project}-feast-ops` | +| `store.mlflow` API | Single entry point — zero `import mlflow`, zero client objects | +| Feast UI integration | Per-feature-view usage stats and registered model associations | + +## Installation + +MLflow is an optional dependency: + +```bash +pip install feast[mlflow] +``` + +## Configuration + +Add the `mlflow` section to your `feature_store.yaml`: + +```yaml +project: my_project +registry: data/registry.db +provider: local +online_store: + type: sqlite + path: data/online_store.db + +mlflow: + enabled: true + tracking_uri: http://127.0.0.1:5000 # optional, falls back to MLFLOW_TRACKING_URI env var + auto_log: true # default + auto_log_entity_df: false # default + entity_df_max_rows: 100000 # default + log_operations: false # default + ops_experiment_suffix: "-feast-ops" # default +``` + +### Configuration options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Master switch for the entire integration | +| `tracking_uri` | string | *(none)* | MLflow tracking server URI. Falls back to `MLFLOW_TRACKING_URI` env var, then MLflow default (`./mlruns`) | +| `auto_log` | bool | `true` | Automatically log feature metadata on every retrieval when an active MLflow run exists | +| `auto_log_entity_df` | bool | `false` | Save the entity DataFrame as `entity_df.parquet` artifact on historical retrieval | +| `entity_df_max_rows` | int | `100000` | Skip entity DataFrame artifact upload for DataFrames exceeding this limit | +| `log_operations` | bool | `false` | Log `feast apply` and `feast materialize` to a separate MLflow experiment | +| `ops_experiment_suffix` | string | `"-feast-ops"` | Suffix appended to project name for the operations experiment | + +### Tracking URI resolution + +The tracking URI is resolved in this order: + +1. `tracking_uri` field in `feature_store.yaml` +2. `MLFLOW_TRACKING_URI` environment variable +3. MLflow's default (`./mlruns` local directory) + +This means you can omit `tracking_uri` from the YAML and set `MLFLOW_TRACKING_URI` in your environment instead, or it would be pulled from `./mlruns` automatically when both are not set. + +## What gets logged + +### Tags on retrieval runs + +When `auto_log: true` and an active MLflow run exists, each `get_historical_features()` or `get_online_features()` call records: + +| Tag | Example | Description | +|-----|---------|-------------| +| `feast.project` | `my_project` | Feast project name | +| `feast.retrieval_type` | `historical` / `online` | Type of feature retrieval | +| `feast.feature_service` | `driver_activity_v1` | Auto-resolved feature service name (if matched) | +| `feast.feature_views` | `driver_hourly_stats` | Comma-separated feature view names | +| `feast.feature_refs` | `driver_hourly_stats:conv_rate,...` | All feature references | +| `feast.entity_count` | `200` | Number of entities in the request | +| `feast.feature_count` | `5` | Number of features retrieved | + +### Metrics + +| Metric | Example | Description | +|--------|---------|-------------| +| `feast.job_submission_sec` | `0.4321` | Feature retrieval duration in seconds | + +### Artifacts + +When `auto_log_entity_df: true` and the entity DataFrame has fewer than `entity_df_max_rows` rows: + +| Artifact | Description | +|----------|-------------| +| `entity_df.parquet` | Full entity DataFrame used in the retrieval | + +When a model is logged via `store.mlflow.log_model()`: + +| Artifact | Description | +|----------|-------------| +| `feast_features.json` | JSON list of feature references the model was trained on | + +### Entity DataFrame metadata + +Regardless of `auto_log_entity_df`, the following metadata is logged when present: + +| Tag / Param | When | Description | +|-------------|------|-------------| +| `feast.entity_df_type` | Always | `dataframe`, `sql`, or `range` | +| `feast.entity_df_rows` | DataFrame input | Row count | +| `feast.entity_df_columns` | DataFrame input | Column names | +| `feast.entity_df_query` | SQL input | The SQL query string | +| `feast.start_date` / `feast.end_date` | Range-based input | Date range | + +### Operation logs + +When `log_operations: true`, `feast apply` and `feast materialize` create self-contained runs in the `{project}{ops_experiment_suffix}` experiment (default: `my_project-feast-ops`): + +**Apply runs:** + +| Tag / Metric | Example | +|--------------|---------| +| `feast.operation` | `apply` | +| `feast.project` | `my_project` | +| `feast.feature_views_changed` | `driver_hourly_stats,order_stats` | +| `feast.feature_services_changed` | `driver_activity_v1` | +| `feast.entities_changed` | `driver,restaurant` | +| `feast.apply.feature_views_count` | `2` | +| `feast.apply.feature_services_count` | `1` | +| `feast.apply.entities_count` | `2` | + +**Materialize runs:** + +| Tag / Metric | Example | +|--------------|---------| +| `feast.operation` | `materialize` / `materialize_incremental` | +| `feast.project` | `my_project` | +| `feast.materialize.feature_views` | `driver_hourly_stats` | +| `feast.materialize.start_date` | `2024-01-01T00:00:00` | +| `feast.materialize.end_date` | `2024-01-02T00:00:00` | +| `feast.materialize.duration_sec` | `12.3456` | + +## Usage + +### Automatic logging (zero code) + +With the configuration above, feature metadata is logged automatically whenever there is an active MLflow run. No explicit `import mlflow` is needed — just use `store.mlflow`: + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +with store.mlflow.start_run(run_name="my_training"): + training_df = store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + # The run is now tagged with feast.feature_refs, feast.feature_views, etc. + + model = train(training_df) + store.mlflow.log_model(model, "model") +``` + +No extra code needed — the tags are written automatically. + +### `store.mlflow` API (recommended) + +`store.mlflow` is the primary way to interact with the Feast–MLflow integration. It provides Feast-enhanced versions of common MLflow operations, and delegates everything else to the raw `mlflow` module: + +```python +from feast import FeatureStore +from sklearn.linear_model import LogisticRegression + +store = FeatureStore(".") + +# Training +with store.mlflow.start_run(run_name="v1_training"): + df = store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + model = LogisticRegression().fit(X, y) + store.mlflow.log_model(model, "model") # Feast-enhanced: saves feast_features.json + train_run_id = store.mlflow.active_run_id + +# Register model (auto-tags version with feast.feature_service) +store.mlflow.register_model(f"runs:/{train_run_id}/model", "driver_model") + +# Prediction (auto-links to training run) +with store.mlflow.start_run(run_name="prediction"): + model = store.mlflow.load_model("models:/driver_model/1") + online_features = store.get_online_features( + features=store.get_feature_service("driver_activity_v1"), + entity_rows=[{"driver_id": 1001}], + ) + predictions = model.predict(...) +``` + +### `feast.mlflow` module API (alternative) + +For users who prefer a module-level import, `feast.mlflow` is a **drop-in replacement for `import mlflow`** that delegates to the same `store.mlflow` client under the hood: + +```python +import feast.mlflow +from feast import FeatureStore + +store = FeatureStore(".") # auto-registers with feast.mlflow + +with feast.mlflow.start_run(run_name="training"): + df = store.get_historical_features(...).to_df() + feast.mlflow.log_params({"lr": "0.01"}) # plain passthrough + feast.mlflow.log_metrics({"f1": 0.85}) # plain passthrough + feast.mlflow.log_model(model, "model") # Feast-enhanced +``` + +#### Store resolution + +`feast.mlflow` resolves its `FeatureStore` in this order: + +1. **Explicit `feast.mlflow.init(store)`** — if called, overrides everything +2. **Auto-registered** — the most recently created `FeatureStore` with `mlflow.enabled=true` registers itself automatically +3. **Auto-discovery** — falls back to `FeatureStore(".")` from the current directory + +In most cases, simply creating a `FeatureStore(...)` is enough — no `init()` needed. + +#### Error handling + +`feast.mlflow` raises clear errors on first use if something is misconfigured: + +| Condition | Error | +|-----------|-------| +| No `feature_store.yaml` in cwd and no store created | `RuntimeError` with guidance to call `feast.mlflow.init(store)` | +| `mlflow.enabled` is not set to `true` | `RuntimeError` with guidance to set `mlflow.enabled=true` | +| `mlflow` pip package not installed | `ImportError` with guidance to run `pip install feast[mlflow]` | + +When `mlflow.enabled` is `false` (or omitted), `store.mlflow` returns `None`, allowing callers to guard with `if store.mlflow:`. The `feast.mlflow` module raises `RuntimeError` only when you attempt to use it without an enabled store. + +### Feast-enhanced functions + +These functions add automatic Feast tagging and lineage on top of their MLflow counterparts: + +| Function | Enhancement | +|----------|-------------| +| `store.mlflow.start_run(run_name, tags)` | Auto-tags run with `feast.project` | +| `store.mlflow.log_model(model, path, flavor)` | Auto-attaches `feast_features.json` artifact | +| `store.mlflow.register_model(model_uri, name)` | Auto-tags model version with `feast.feature_service` | +| `store.mlflow.load_model(model_uri)` | Auto-tags prediction run with training lineage | + +**Supported model flavors for `log_model()`:** `sklearn`, `pytorch`, `xgboost`, `lightgbm`, `tensorflow`, `keras`, `pyfunc`. + +### Feast-only functions + +These are unique to the Feast integration and have no `mlflow` equivalent: + +| Function | Description | +|----------|-------------| +| `store.mlflow.resolve_features(model_uri)` | Resolve model URI to Feast feature service name | +| `store.mlflow.get_training_entity_df(run_id, ...)` | Recover entity DataFrame from a past MLflow run | +| `store.mlflow.log_training_dataset(df, dataset_name)` | Log a training DataFrame as an MLflow dataset input | +| `store.mlflow.active_run_id` | Current active MLflow run ID (or `None`) | +| `store.mlflow.client` | The underlying `MlflowClient` instance for advanced queries | +| `feast.mlflow.init(store)` | Explicitly bind `feast.mlflow` module to a `FeatureStore` (optional) | + +### Passthrough behavior + +The `feast.mlflow` module delegates any attribute not listed above to the raw `mlflow` module. This means you can use `feast.mlflow` as a drop-in replacement for `import mlflow`: + +```python +feast.mlflow.log_params(params) # passes through to mlflow.log_params +feast.mlflow.log_metrics(metrics) +feast.mlflow.set_tag("env", "staging") +feast.mlflow.MlflowClient() +``` + +`store.mlflow` does **not** have this passthrough — it only exposes the Feast-enhanced and Feast-only methods listed above. To access raw `mlflow` functions from `store.mlflow`, use the escape hatches: + +```python +store.mlflow.client.log_param(run_id, "lr", "0.01") # via MlflowClient instance +store.mlflow.mlflow.log_params(params) # via raw mlflow module +``` + +### Resolve a model back to its feature service + +```python +from feast import FeatureStore + +store = FeatureStore(".") +fs_name = store.mlflow.resolve_features("models:/driver_model/1") +# Returns: "driver_activity_v1" +``` + +Resolution order: +1. Model version tag `feast.feature_service` (set by `register_model()`) +2. Training run tag `feast.feature_service` (set by auto-logging) + +### Reproduce training from a past run + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +entity_df = store.mlflow.get_training_entity_df(run_id="abc123") + +with store.mlflow.start_run(run_name="retrain_v2"): + new_df = store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + model = train(new_df) + store.mlflow.log_model(model, "model") +``` + +This requires `auto_log_entity_df: true` to have been enabled when the original run was recorded. + +## Feast UI integration + +The Feast UI server exposes three API endpoints that aggregate data from MLflow: + +| Endpoint | Description | +|----------|-------------| +| `/api/mlflow-runs` | All Feast-tagged MLflow runs with linked registered models | +| `/api/mlflow-feature-usage` | Per-feature-view usage stats (run count, last used, associated models) | +| `/api/mlflow-feature-models` | Reverse index of feature refs to registered models | + +The feature view detail page in the Feast UI displays: +- **MLflow Training Runs** count and **Last Used** date in the header stats +- An **MLflow Usage** panel showing training run count, relative last-used time, and a table of registered models that depend on the feature view + +Start the Feast UI with: + +```bash +feast ui --host 127.0.0.1 --port 8888 +``` diff --git a/docs/reference/offline-stores/README.md b/docs/reference/offline-stores/README.md index e207d72c28a..1c0d24c8d07 100644 --- a/docs/reference/offline-stores/README.md +++ b/docs/reference/offline-stores/README.md @@ -53,3 +53,23 @@ Please see [Offline Store](../../getting-started/components/offline-store.md) fo {% content-ref url="oracle.md" %} [oracle.md](oracle.md) {% endcontent-ref %} + +{% content-ref url="athena.md" %} +[athena.md](athena.md) +{% endcontent-ref %} + +{% content-ref url="clickhouse.md" %} +[clickhouse.md](clickhouse.md) +{% endcontent-ref %} + +{% content-ref url="mongodb.md" %} +[mongodb.md](mongodb.md) +{% endcontent-ref %} + +{% content-ref url="remote-offline-store.md" %} +[remote-offline-store.md](remote-offline-store.md) +{% endcontent-ref %} + +{% content-ref url="hybrid.md" %} +[hybrid.md](hybrid.md) +{% endcontent-ref %} diff --git a/docs/reference/offline-stores/athena.md b/docs/reference/offline-stores/athena.md new file mode 100644 index 00000000000..3fbe77681ee --- /dev/null +++ b/docs/reference/offline-stores/athena.md @@ -0,0 +1,66 @@ +# Athena offline store (contrib) + +## Description + +The Athena offline store provides support for reading [AthenaSources](../data-sources/athena.md). +* Entity dataframes can be provided as a SQL query or can be provided as a Pandas dataframe. + +## Disclaimer + +The Athena offline store does not achieve full test coverage. +Please do not assume complete stability. + +## Getting started +In order to use this offline store, you'll need to run `pip install 'feast[aws]'`. + +## Example + +{% code title="feature_store.yaml" %} +```yaml +project: my_project +registry: data/registry.db +provider: local +offline_store: + type: athena + data_source: AwsDataCatalog + region: us-east-1 + database: my_database + workgroup: primary +online_store: + path: data/online_store.db +``` +{% endcode %} + +The full set of configuration options is available in [AthenaOfflineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.offline_stores.contrib.athena_offline_store.athena.AthenaOfflineStoreConfig). + +## Functionality Matrix + +The set of functionality supported by offline stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the Athena offline store. + +| | Athena | +| :----------------------------------------------------------------- |:-------| +| `get_historical_features` (point-in-time correct join) | yes | +| `pull_latest_from_table_or_query` (retrieve latest feature values) | yes | +| `pull_all_from_table_or_query` (retrieve a saved dataset) | yes | +| `offline_write_batch` (persist dataframes to offline store) | no | +| `write_logged_features` (persist logged features to offline store) | yes | + +Below is a matrix indicating which functionality is supported by `AthenaRetrievalJob`. + +| | Athena | +| ----------------------------------------------------- |--------| +| export to dataframe | yes | +| export to arrow table | yes | +| export to arrow batches | no | +| export to SQL | yes | +| export to data lake (S3, GCS, etc.) | no | +| export to data warehouse | no | +| export as Spark dataframe | no | +| local execution of Python-based on-demand transforms | yes | +| remote execution of Python-based on-demand transforms | no | +| persist results in the offline store | yes | +| preview the query plan before execution | yes | +| read partitioned data | yes | + +To compare this set of functionality against other offline stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/reference/offline-stores/mongodb.md b/docs/reference/offline-stores/mongodb.md new file mode 100644 index 00000000000..a41d43ca676 --- /dev/null +++ b/docs/reference/offline-stores/mongodb.md @@ -0,0 +1,101 @@ +# MongoDB offline store (contrib) + +## Description + +The MongoDB offline store provides support for reading [MongoDBSource](../data-sources/mongodb.md). + +## Getting started + +In order to use this offline store, you'll need to run `pip install 'feast[mongodb]'`. + +## Example + +{% code title="feature_store.yaml" %} +```yaml +project: my_project +registry: data/registry.db +provider: local +offline_store: + type: feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore + connection_string: "mongodb+srv://user:pass@cluster.mongodb.net" # pragma: allowlist secret + database: feast + collection: feature_history +online_store: + type: mongodb + connection_string: "mongodb+srv://user:pass@cluster.mongodb.net" # pragma: allowlist secret + database_name: feast_online_store + collection_suffix: latest + client_kwargs: {} +``` +{% endcode %} + +The full set of configuration options is available in [MongoDBOfflineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStoreConfig). + +## Data Model + +The offline store uses a single shared collection (by default `feature_history`) that stores append-only historical feature rows for all feature views. Each document represents one observation of one entity for one FeatureView at a specific event timestamp: + +```json +{ + "entity_id": "Binary(...)", + "feature_view": "driver_stats", + "event_timestamp": "ISODate(2024-01-15T12:00:00Z)", + "created_at": "ISODate(2024-01-15T12:01:00Z)", + "features": { + "conv_rate": 0.72, + "acc_rate": 0.91, + "avg_daily_trips": 14 + } +} +``` + +Key properties: + +* **Append-only**: Historical data is treated as immutable; corrections are written as new rows with newer `created_at` timestamps rather than in-place updates. +* **Time-series friendly**: `event_timestamp` represents when the feature value was observed; `created_at` is used as a tie-breaker when multiple observations share the same event timestamp. +* **Feature grouping by FeatureView**: `feature_view` identifies which FeatureView the row belongs to, so a single collection can host multiple FVs. + +A single compound index supports all major query patterns: + +``` +(entity_id ASC, feature_view ASC, event_timestamp DESC, created_at DESC) +``` + +This index enables efficient range scans over entities and feature views, while ensuring that the most recent observation per `(entity_id, feature_view)` is seen first during aggregation. The index is created lazily on first use and cached per connection string. + +## Key Optimizations + +* **Scoring vs. training paths**: When each entity appears only once in `entity_df` (scoring/inference — one feature lookup per entity), server-side `$group $first` efficiently returns the single latest value per entity. When the same entity appears at multiple timestamps (training — building a dataset with many historical snapshots per entity), the store retrieves all candidate rows and uses `pd.merge_asof` to select the correct point-in-time value for each request timestamp. +* **Two-level chunking**: `CHUNK_SIZE` (50,000 rows) controls the size of intermediate DataFrames in memory; `MONGO_BATCH_SIZE` (10,000 entity IDs) limits the query size sent to MongoDB. + +## Functionality Matrix + +The set of functionality supported by offline stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the MongoDB offline store. + +| | MongoDB | +| :----------------------------------------------------------------- | :------ | +| `get_historical_features` (point-in-time correct join) | yes | +| `pull_latest_from_table_or_query` (retrieve latest feature values) | yes | +| `pull_all_from_table_or_query` (retrieve a saved dataset) | yes | +| `offline_write_batch` (persist dataframes to offline store) | yes | +| `write_logged_features` (persist logged features to offline store) | no | + +Below is a matrix indicating which functionality is supported by `MongoDBRetrievalJob`. + +| | MongoDB | +| ----------------------------------------------------- | ------- | +| export to dataframe | yes | +| export to arrow table | yes | +| export to arrow batches | no | +| export to SQL | no | +| export to data lake (S3, GCS, etc.) | no | +| export to data warehouse | no | +| export as Spark dataframe | no | +| local execution of Python-based on-demand transforms | yes | +| remote execution of Python-based on-demand transforms | no | +| persist results in the offline store | yes | +| preview the query plan before execution | no | +| read partitioned data | no | + +To compare this set of functionality against other offline stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/reference/offline-stores/postgres.md b/docs/reference/offline-stores/postgres.md index 321ddcf25e7..7e9f112b3b3 100644 --- a/docs/reference/offline-stores/postgres.md +++ b/docs/reference/offline-stores/postgres.md @@ -38,7 +38,7 @@ online_store: ``` {% endcode %} -Note that `sslmode`, `sslkey_path`, `sslcert_path`, and `sslrootcert_path` are optional parameters. +Note that `sslmode` defaults to `require`, which encrypts the connection without certificate verification. To disable SSL (e.g. for local development), set `sslmode: disable`. For certificate verification, set `sslmode` to `verify-ca` or `verify-full` and provide the corresponding `sslrootcert_path` (and optionally `sslcert_path` and `sslkey_path` for mutual TLS). The full set of configuration options is available in [PostgreSQLOfflineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.offline_stores.contrib.postgres_offline_store.postgres.PostgreSQLOfflineStoreConfig). Additionally, a new optional parameter `entity_select_mode` was added to tell how Postgres should load the entity data. By default(`temp_table`), a temporary table is created and the entity data frame or sql is loaded into that table. A new value of `embed_query` was added to allow directly loading the SQL query into a CTE, providing improved performance and skipping the need to CREATE and DROP the temporary table. diff --git a/docs/reference/offline-stores/ray.md b/docs/reference/offline-stores/ray.md index 063ffcb209a..a9d8cd7ef08 100644 --- a/docs/reference/offline-stores/ray.md +++ b/docs/reference/offline-stores/ray.md @@ -31,6 +31,7 @@ The Ray offline store provides: - Efficient data filtering and column selection - Timestamp-based data processing with timezone awareness - Enterprise-ready KubeRay cluster support via CodeFlare SDK +- **GPU support**: schedule worker tasks on GPU nodes via `num_gpus` config (all modes including KubeRay) ## Functionality Matrix @@ -246,6 +247,9 @@ batch_engine: | `max_parallelism_multiplier` | int | 2 | Parallelism as multiple of CPU cores | | `target_partition_size_mb` | int | 64 | Target partition size (MB) | | `window_size_for_joins` | string | "1H" | Time window for distributed joins | +| `num_gpus` | float | None | GPUs per worker task. Supported in all modes. See [Worker Resource Scheduling](../compute-engine/ray.md#worker-resource-scheduling). | +| `gpu_batch_format` | string | `"pandas"` | Batch format for `map_batches` when `num_gpus` is set (`"numpy"` or `"pyarrow"` for GPU-native libs). | +| `worker_task_options` | dict | None | Arbitrary Ray `.options()` kwargs (num_cpus, memory, accelerator_type, resources, runtime_env, …). See [Worker Resource Scheduling](../compute-engine/ray.md#worker-resource-scheduling) for the full reference. | #### Mode Detection Precedence @@ -542,6 +546,12 @@ python your_feast_script.py - Secure communication between client and Ray cluster - Automatic cluster discovery +### GPU Support + +The Ray offline store supports GPU scheduling via the `num_gpus` and `gpu_batch_format` config options. This works across all execution modes (local, remote, and KubeRay). + +For full configuration details, examples, and KubeRay GPU setup, see the [Ray Compute Engine GPU Support](../compute-engine/ray.md#gpu-support) section. + ### Data Source Validation The Ray offline store validates data sources to ensure compatibility: @@ -557,14 +567,45 @@ except Exception as e: print(f"Data source validation failed: {e}") ``` +## Data Sources + +[`RaySource`](../data-sources/ray.md) is the recommended data source for the +Ray offline store. It is a pure-metadata descriptor that tells Feast how to +load a Ray Dataset from any source Ray Data supports — Parquet, CSV, JSON, +HuggingFace datasets, MongoDB, binary files, images, TFRecords, WebDataset, +SQL, and more. + +```python +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import RaySource + +# Load directly from the HuggingFace Hub +cheque_source = RaySource( + name="cheque_images_hf", + reader_type="huggingface", + reader_options={ + "dataset_name": "cheques_sample_data", + "split": "train", + }, + timestamp_field="event_timestamp", +) +``` + +See the [RaySource reference](../data-sources/ray.md) for a full list of +`reader_type` values and configuration options. + +> **Note:** `FileSource` (Parquet) remains supported for backward compatibility +> but `RaySource(reader_type="parquet")` is preferred for new projects. + ## Limitations -The Ray offline store has the following limitations: +The Ray offline store has one known limitation: -1. **File Sources Only**: Currently supports only `FileSource` data sources -2. **No Direct SQL**: Does not support SQL query interfaces -3. **No Online Writes**: Cannot write directly to online stores -4. **No Complex Transformations**: The Ray offline store focuses on data I/O operations. For complex feature transformations (aggregations, joins, custom UDFs), use the [Ray Compute Engine](../compute-engine/ray.md) instead +* **`online_write_batch` not implemented**: The `OfflineStore.online_write_batch()` interface + is not supported by the Ray offline store. This does **not** affect materialization — + `feast materialize` writes to the online store correctly via the + [Ray Compute Engine](../compute-engine/ray.md). The restriction only applies to callers + that invoke `online_write_batch` on the offline store object directly, which is an + uncommon pattern outside of custom tooling. ## Integration with Ray Compute Engine diff --git a/docs/reference/online-stores/README.md b/docs/reference/online-stores/README.md index 2d962b2013f..6f31993f896 100644 --- a/docs/reference/online-stores/README.md +++ b/docs/reference/online-stores/README.md @@ -38,6 +38,10 @@ Please see [Online Store](../../getting-started/components/online-store.md) for [postgres.md](postgres.md) {% endcontent-ref %} +{% content-ref url="hbase.md" %} +[hbase.md](hbase.md) +{% endcontent-ref %} + {% content-ref url="cassandra.md" %} [cassandra.md](cassandra.md) {% endcontent-ref %} @@ -69,3 +73,23 @@ Please see [Online Store](../../getting-started/components/online-store.md) for {% content-ref url="singlestore.md" %} [singlestore.md](singlestore.md) {% endcontent-ref %} + +{% content-ref url="elasticsearch.md" %} +[elasticsearch.md](elasticsearch.md) +{% endcontent-ref %} + +{% content-ref url="qdrant.md" %} +[qdrant.md](qdrant.md) +{% endcontent-ref %} + +{% content-ref url="milvus.md" %} +[milvus.md](milvus.md) +{% endcontent-ref %} + +{% content-ref url="faiss.md" %} +[faiss.md](faiss.md) +{% endcontent-ref %} + +{% content-ref url="hybrid.md" %} +[hybrid.md](hybrid.md) +{% endcontent-ref %} diff --git a/docs/reference/online-stores/dynamodb.md b/docs/reference/online-stores/dynamodb.md index ec0104172fb..a7f6b7392c9 100644 --- a/docs/reference/online-stores/dynamodb.md +++ b/docs/reference/online-stores/dynamodb.md @@ -24,7 +24,7 @@ The full set of configuration options is available in [DynamoDBOnlineStoreConfig ## Configuration -Below is a example with performance tuning options: +Below is an example with performance tuning options: {% code title="feature_store.yaml" %} ```yaml @@ -69,7 +69,7 @@ Feast requires the following permissions in order to execute commands for Dynamo | **Command** | Permissions | Resources | | ----------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------- | -| **Apply** |

dynamodb:CreateTable

dynamodb:DescribeTable

dynamodb:DeleteTable

| arn:aws:dynamodb:\:\:table/\* | +| **Apply** |

dynamodb:CreateTable

dynamodb:DescribeTable

dynamodb:DeleteTable

dynamodb:TagResource

| arn:aws:dynamodb:\:\:table/\* | | **Materialize** | dynamodb.BatchWriteItem | arn:aws:dynamodb:\:\:table/\* | | **Get Online Features** | dynamodb.BatchGetItem | arn:aws:dynamodb:\:\:table/\* | @@ -83,6 +83,7 @@ The following inline policy can be used to grant Feast the necessary permissions "dynamodb:CreateTable", "dynamodb:DescribeTable", "dynamodb:DeleteTable", + "dynamodb:TagResource", "dynamodb:BatchWriteItem", "dynamodb:BatchGetItem" ], diff --git a/docs/reference/online-stores/faiss.md b/docs/reference/online-stores/faiss.md new file mode 100644 index 00000000000..32c9242dd60 --- /dev/null +++ b/docs/reference/online-stores/faiss.md @@ -0,0 +1,57 @@ +# Faiss online store + +## Description + +The [Faiss](https://github.com/facebookresearch/faiss) online store provides support for materializing feature values and performing vector similarity search using Facebook AI Similarity Search (Faiss). Faiss is a library for efficient similarity search and clustering of dense vectors, making it well-suited for use cases involving embeddings and nearest-neighbor lookups. + +## Getting started +In order to use this online store, you'll need to install the Faiss dependency. E.g. + +`pip install 'feast[faiss]'` + +## Example + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: feast.infra.online_stores.faiss_online_store.FaissOnlineStore + dimension: 128 + index_path: data/faiss_index + index_type: IVFFlat # optional, default: IVFFlat + nlist: 100 # optional, default: 100 +``` +{% endcode %} + +**Note:** Faiss is not registered as a named online store type. You must use the fully qualified class path as the `type` value. + +The full set of configuration options is available in [FaissOnlineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.online_stores.faiss_online_store.FaissOnlineStoreConfig). + +## Functionality Matrix + +The set of functionality supported by online stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the Faiss online store. + +| | Faiss | +|:----------------------------------------------------------|:------| +| write feature values to the online store | yes | +| read feature values from the online store | yes | +| update infrastructure (e.g. tables) in the online store | yes | +| teardown infrastructure (e.g. tables) in the online store | yes | +| generate a plan of infrastructure changes | no | +| support for on-demand transforms | yes | +| readable by Python SDK | yes | +| readable by Java | no | +| readable by Go | no | +| support for entityless feature views | yes | +| support for concurrent writing to the same key | no | +| support for ttl (time to live) at retrieval | no | +| support for deleting expired data | no | +| collocated by feature view | yes | +| collocated by feature service | no | +| collocated by entity key | no | +| vector similarity search | yes | + +To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/reference/online-stores/hbase.md b/docs/reference/online-stores/hbase.md new file mode 100644 index 00000000000..b53bfed5fe5 --- /dev/null +++ b/docs/reference/online-stores/hbase.md @@ -0,0 +1,56 @@ +# HBase online store + +## Description + +The [HBase](https://hbase.apache.org/) online store provides support for materializing feature values into an Apache HBase database for serving online features in real-time. + +* Each feature view is mapped to an HBase table +* Connects to HBase via the Thrift server using [happybase](https://happybase.readthedocs.io/) + +## Getting started +In order to use this online store, you'll need to run `pip install 'feast[hbase]'`. + +## Example + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: hbase + host: localhost + port: "9090" + connection_pool_size: 4 # optional + protocol: binary # optional + transport: buffered # optional +``` +{% endcode %} + +The full set of configuration options is available in [HbaseOnlineStoreConfig](https://rtd.feast.dev/en/master/#feast.infra.online_stores.hbase_online_store.hbase.HbaseOnlineStoreConfig). + +## Functionality Matrix + +The set of functionality supported by online stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the HBase online store. + +| | HBase | +| :-------------------------------------------------------- | :---- | +| write feature values to the online store | yes | +| read feature values from the online store | yes | +| update infrastructure (e.g. tables) in the online store | yes | +| teardown infrastructure (e.g. tables) in the online store | yes | +| generate a plan of infrastructure changes | no | +| support for on-demand transforms | yes | +| readable by Python SDK | yes | +| readable by Java | no | +| readable by Go | no | +| support for entityless feature views | yes | +| support for concurrent writing to the same key | no | +| support for ttl (time to live) at retrieval | no | +| support for deleting expired data | no | +| collocated by feature view | yes | +| collocated by feature service | no | +| collocated by entity key | no | + +To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/reference/online-stores/mongodb.md b/docs/reference/online-stores/mongodb.md index 969637b9e68..e5251747e77 100644 --- a/docs/reference/online-stores/mongodb.md +++ b/docs/reference/online-stores/mongodb.md @@ -1,13 +1,9 @@ -# MongoDB online store (Preview) +# MongoDB online store ## Description The [MongoDB](https://www.mongodb.com/) online store provides support for materializing feature values into MongoDB for serving online features. -{% hint style="warning" %} -The MongoDB online store is currently in **preview**. Some functionality may be unstable, and breaking changes may occur in future releases. -{% endhint %} - ## Features * Supports both synchronous and asynchronous operations for high-performance feature retrieval diff --git a/docs/reference/online-stores/postgres.md b/docs/reference/online-stores/postgres.md index fb2253d043e..10f3f871710 100644 --- a/docs/reference/online-stores/postgres.md +++ b/docs/reference/online-stores/postgres.md @@ -6,7 +6,7 @@ The PostgreSQL online store provides support for materializing feature values in * Only the latest feature values are persisted -* sslmode, sslkey_path, sslcert_path, and sslrootcert_path are optional +* `sslmode` defaults to `require`, which encrypts the connection without certificate verification. To disable SSL (e.g. for local development), set `sslmode: disable`. For certificate verification, set `sslmode` to `verify-ca` or `verify-full` and provide the corresponding `sslrootcert_path` (and optionally `sslcert_path` and `sslkey_path` for mutual TLS) ## Getting started In order to use this online store, you'll need to run `pip install 'feast[postgres]'`. You can get started by then running `feast init -t postgres`. diff --git a/docs/reference/online-stores/redis.md b/docs/reference/online-stores/redis.md index ae7f8b4c5ca..f212f03d943 100644 --- a/docs/reference/online-stores/redis.md +++ b/docs/reference/online-stores/redis.md @@ -7,7 +7,12 @@ The [Redis](https://redis.io) online store provides support for materializing fe * Both Redis and Redis Cluster are supported. * The data model used to store feature values in Redis is described in more detail [here](../../specs/online\_store\_format.md). +**Data model:** All feature views that share the same entity key are stored in a single Redis hash. The hash key is derived from the serialized entity key and the project name. Each feature's value is a hash field keyed by a murmur3 hash of `"feature_view_name:feature_name"`, and a separate `_ts:` field stores the event timestamp per feature view. + +This collocated-by-entity design enables an important performance optimization: `get_online_features()` requests that span multiple feature views for the same entity can issue all `HMGET` commands in a **single Redis pipeline execution**, regardless of how many feature views are requested. See [Performance characteristics](#performance-characteristics) below. + ## Getting started + In order to use this online store, you'll need to install the redis extra (along with the dependency needed for the offline store of choice). E.g. - `pip install 'feast[gcp, redis]'` - `pip install 'feast[snowflake, redis]'` @@ -60,22 +65,85 @@ online_store: ``` {% endcode %} -Additionally, the redis online store also supports automatically deleting data via a TTL mechanism. -The TTL is applied at the entity level, so feature values from any associated feature views for an entity are removed together. -This TTL can be set in the `feature_store.yaml`, using the `key_ttl_seconds` field in the online store. For example: +## TTL configuration + +The Redis online store supports two complementary TTL mechanisms: + +### Key-level TTL (`key_ttl_seconds`) + +Sets a Redis `EXPIRE` on the entire entity hash key. When the TTL elapses, Redis automatically deletes all feature values for that entity across **all** feature views that share the same key. Use this to bound memory usage and automatically evict stale entity data. -{% code title="feature_store.yaml" %} ```yaml -project: my_feature_repo -registry: data/registry.db -provider: local online_store: type: redis - key_ttl_seconds: 604800 + key_ttl_seconds: 604800 # 7 days connection_string: "localhost:6379" ``` -{% endcode %} +{% hint style="warning" %} +Because all feature views for the same entity share one Redis hash key, `key_ttl_seconds` uses the **entity** as the expiry unit, not the feature view. Writing any feature view for an entity resets the TTL for the whole hash. This means a frequently written feature view can keep a stale, infrequently written feature view alive beyond its intended TTL. +{% endhint %} + +{% hint style="info" %} +`FeatureView.ttl` defines the **offline retrieval window** (how far back in time point-in-time joins look in the offline store). It does **not** filter online store reads. To control online data expiry, use `key_ttl_seconds`. +{% endhint %} + +## Performance characteristics + +### Batched multi-feature-view reads + +Unlike most online stores, the Redis implementation overrides `get_online_features()` to issue a **single pipeline execution** for all feature views in the request. Because all feature views for the same entity live in the same Redis hash, all `HMGET` commands across every feature view are batched into one `pipeline.execute()` call. + +| Feature views in request | Redis round trips (before) | Redis round trips (after) | +| :---: | :---: | :---: | +| 1 | 1 | 1 | +| 5 | 5 | 1 | +| 10 | 10 | 1 | +| 20 | 20 | 1 | + +Benchmark results against Redis 8.6.2 (localhost, 50 entities, 3 features/FV, 300 rounds): + +| Feature views | Master (per-FV pipeline) | Improved (batched pipeline) | Speedup | +| :---: | ---: | ---: | :---: | +| 1 | 1.57 ms | 1.32 ms | 1.19× | +| 5 | 7.27 ms | 5.63 ms | 1.29× | +| 10 | 15.64 ms | 10.65 ms | 1.47× | +| 20 | 36.33 ms | 21.21 ms | **1.71×** | + +The speedup grows with the number of feature views and is most pronounced in production environments with non-trivial network RTT to Redis. + +### Write path: `skip_dedup` for bulk loads + +By default, `online_write_batch()` checks existing timestamps before writing (to avoid overwriting newer data with older data). This requires two pipeline round trips per batch: one to read existing timestamps, one to write new values. + +For initial bulk loads or append-only pipelines where out-of-order writes are not a concern, set `skip_dedup: true` to write in a **single pipeline round trip**: + +```yaml +online_store: + type: redis + connection_string: "localhost:6379" + skip_dedup: true +``` + +{% hint style="warning" %} +With `skip_dedup: true`, writes always overwrite existing data regardless of timestamp order. Under concurrent writers, an older record can overwrite a newer one. Use only for controlled bulk loads or pipelines that guarantee ordered delivery. +{% endhint %} + +### Async write support + +The Redis online store implements `online_write_batch_async()` using the async Redis client. This enables non-blocking batch writes in async serving frameworks. `skip_dedup` is also respected in the async path. + +## Configuration reference + +| Parameter | Default | Description | +| --- | --- | --- | +| `type` | `redis` | Online store type selector | +| `redis_type` | `redis` | Connection type: `redis`, `redis_cluster`, or `redis_sentinel` | +| `connection_string` | `localhost:6379` | Host:port and optional parameters. For cluster: `redis1:6379,redis2:6379,ssl=true,password=...` | +| `sentinel_master` | `mymaster` | Sentinel master name (only used when `redis_type: redis_sentinel`) | +| `key_ttl_seconds` | `null` | Redis `EXPIRE` TTL in seconds applied to the entity hash key after each write. Expires all feature views for that entity together. | +| `full_scan_for_deletion` | `true` | When `true`, deleting or renaming a feature view scans Redis to remove its hash fields. Set `false` to skip deletion scans (faster `feast apply`, but leaves orphaned data). | +| `skip_dedup` | `false` | When `true`, skips the existing-timestamp read before each write, halving write round trips. Suitable for initial bulk loads; may cause older values to overwrite newer ones under concurrent writers. | The full set of configuration options is available in [RedisOnlineStoreConfig](https://rtd.feast.dev/en/latest/#feast.infra.online_stores.redis.RedisOnlineStoreConfig). @@ -102,5 +170,7 @@ Below is a matrix indicating which functionality is supported by the Redis onlin | collocated by feature view | no | | collocated by feature service | no | | collocated by entity key | yes | +| async batch writes | yes | +| batched multi-feature-view reads (single pipeline) | yes | To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). diff --git a/docs/reference/openlineage.md b/docs/reference/openlineage.md index 01837c9936a..78438082d44 100644 --- a/docs/reference/openlineage.md +++ b/docs/reference/openlineage.md @@ -88,7 +88,7 @@ fs.materialize( | Option | Default | Description | |--------|---------|-------------| | `enabled` | `false` | Enable/disable OpenLineage integration | -| `transport_type` | `http` | Transport type: `http`, `file`, `kafka` | +| `transport_type` | `None` | Transport type: `http`, `console`, `file`, `kafka`. When unset, defers to OpenLineage SDK defaults. | | `transport_url` | - | URL for HTTP transport (required) | | `transport_endpoint` | `api/v1/lineage` | API endpoint for HTTP transport | | `api_key` | - | Optional API key for authentication | diff --git a/docs/reference/registries/metadata.md b/docs/reference/registries/metadata.md index 575f2a5c8b7..371be9b5289 100644 --- a/docs/reference/registries/metadata.md +++ b/docs/reference/registries/metadata.md @@ -20,6 +20,7 @@ The metadata info of Feast `feature_store.yaml` is: | registry.warehouse | N | string | snowflake warehouse name | | registry.database | N | string | snowflake db name | | registry.schema | N | string | snowflake schema name | +| registry.enable_online_feature_view_versioning | N | boolean | enable versioned online store tables and version-qualified reads (default: false). Version history tracking is always active. | | online_store | Y | | | | offline_store | Y | NA | | | | offline_store.type | Y | string | storage type | diff --git a/docs/reference/registries/remote.md b/docs/reference/registries/remote.md index a03e30ac85f..64055304283 100644 --- a/docs/reference/registries/remote.md +++ b/docs/reference/registries/remote.md @@ -18,7 +18,27 @@ registry: {% endcode %} The optional `cert` parameter can be configured as well, it should point to the public certificate path when the Registry Server starts in SSL mode. This may be needed if the Registry Server is started with a self-signed certificate, typically this file ends with *.crt, *.cer, or *.pem. -More info about the `cert` parameter can be found in [feast-client-connecting-to-remote-registry-sever-started-in-tls-mode](../../how-to-guides/starting-feast-servers-tls-mode.md#feast-client-connecting-to-remote-registry-sever-started-in-tls-mode) + +For **mutual TLS (mTLS)**, you can also configure: +* `client_cert` — Path to the client certificate presented to the server. Must be paired with `client_key`. Typically ends with `*.crt` or `*.pem`. +* `client_key` — Path to the client private key. Must be paired with `client_cert`. Typically ends with `*.key` or `*.pem`. + +When connecting through a tunnel or proxy where the connection address differs from the server hostname, set: +* `authority` — Overrides the gRPC `:authority` header so the server certificate is validated against the correct hostname. + +{% code title="feature_store.yaml" %} +```yaml +registry: + registry_type: remote + path: localhost:8443 + cert: /path/to/ca.crt + client_cert: /path/to/tls.crt + client_key: /path/to/tls.key + authority: feature-registry.example.com +``` +{% endcode %} + +More info about TLS configuration can be found in [feast-client-connecting-to-remote-registry-sever-started-in-tls-mode](../../how-to-guides/starting-feast-servers-tls-mode.md#feast-client-connecting-to-remote-registry-sever-started-in-tls-mode) ## How to configure the server diff --git a/docs/reference/type-system.md b/docs/reference/type-system.md index 9f36f6eeaff..97cc6036dc8 100644 --- a/docs/reference/type-system.md +++ b/docs/reference/type-system.md @@ -3,7 +3,7 @@ ## Motivation Feast uses an internal type system to provide guarantees on training and serving data. -Feast supports primitive types, array types, set types, and map types for feature values. +Feast supports primitive types, array types, set types, map types, JSON, and struct types for feature values. Null types are not supported, although the `UNIX_TIMESTAMP` type is nullable. The type system is controlled by [`Value.proto`](https://github.com/feast-dev/feast/blob/master/protos/feast/types/Value.proto) in protobuf and by [`types.py`](https://github.com/feast-dev/feast/blob/master/sdk/python/feast/types.py) in Python. Type conversion logic can be found in [`type_map.py`](https://github.com/feast-dev/feast/blob/master/sdk/python/feast/type_map.py). @@ -24,6 +24,23 @@ Feast supports the following data types: | `Bytes` | `bytes` | Binary data | | `Bool` | `bool` | Boolean value | | `UnixTimestamp` | `datetime` | Unix timestamp (nullable) | +| `ZonedTimestamp` | `datetime` | Timezone-aware datetime preserving its source zone (nullable) | +| `Uuid` | `uuid.UUID` | UUID (any version) | +| `TimeUuid` | `uuid.UUID` | Time-based UUID (version 1) | +| `Decimal` | `decimal.Decimal` | Arbitrary-precision decimal number | + +### Domain-Specific Primitive Types + +These types are semantic aliases over `Bytes` for domain-specific use cases (e.g., RAG pipelines, image processing). They are stored as `bytes` at the proto level. + +| Feast Type | Python Type | Description | +|------------|-------------|-------------| +| `PdfBytes` | `bytes` | PDF document binary data (used in RAG / document processing pipelines) | +| `ImageBytes` | `bytes` | Image binary data (used in image processing / multimodal pipelines) | + +{% hint style="warning" %} +`PdfBytes` and `ImageBytes` are not natively supported by any backend's type inference. You must explicitly declare them in your feature view schema. Backend storage treats them as raw `bytes`. +{% endhint %} ### Array Types @@ -39,10 +56,13 @@ All primitive types have corresponding array (list) types: | `Array(Bytes)` | `List[bytes]` | List of binary data | | `Array(Bool)` | `List[bool]` | List of booleans | | `Array(UnixTimestamp)` | `List[datetime]` | List of timestamps | +| `Array(Uuid)` | `List[uuid.UUID]` | List of UUIDs | +| `Array(TimeUuid)` | `List[uuid.UUID]` | List of time-based UUIDs | +| `Array(Decimal)` | `List[decimal.Decimal]` | List of arbitrary-precision decimals | ### Set Types -All primitive types (except Map) have corresponding set types for storing unique values: +All primitive types (except `Map` and `Json`) have corresponding set types for storing unique values: | Feast Type | Python Type | Description | |------------|-------------|-------------| @@ -54,19 +74,125 @@ All primitive types (except Map) have corresponding set types for storing unique | `Set(Bytes)` | `Set[bytes]` | Set of unique binary data | | `Set(Bool)` | `Set[bool]` | Set of unique booleans | | `Set(UnixTimestamp)` | `Set[datetime]` | Set of unique timestamps | +| `Set(Uuid)` | `Set[uuid.UUID]` | Set of unique UUIDs | +| `Set(TimeUuid)` | `Set[uuid.UUID]` | Set of unique time-based UUIDs | +| `Set(Decimal)` | `Set[decimal.Decimal]` | Set of unique arbitrary-precision decimals | **Note:** Set types automatically remove duplicate values. When converting from lists or other iterables to sets, duplicates are eliminated. +{% hint style="warning" %} +**Backend limitations for Set types:** + +- **No backend infers Set types from schema.** No offline store (BigQuery, Snowflake, Redshift, PostgreSQL, Spark, Athena, MSSQL) maps its native types to Feast Set types. You **must** explicitly declare Set types in your feature view schema. +- **No native PyArrow set type.** Feast converts Sets to `pyarrow.list_()` internally, but `feast_value_type_to_pa()` in `type_map.py` does not include Set mappings, which can cause errors in some code paths. +- **Online stores** that serialize proto bytes (e.g., SQLite, Redis, DynamoDB) handle Sets correctly. +- **Offline stores** may not handle Set types correctly during retrieval. For example, the Ray offline store only special-cases `_LIST` types, not `_SET`. +- Set types are best suited for **online serving** use cases where feature values are written as Python sets and retrieved via `get_online_features`. +{% endhint %} + +### Nested Collection Types + +Feast supports arbitrarily nested collections using a recursive `VALUE_LIST` / `VALUE_SET` design. The outer container determines the proto enum (`VALUE_LIST` for `Array(…)`, `VALUE_SET` for `Set(…)`), while the full inner type structure is persisted via a mandatory `feast:nested_inner_type` Field tag. + +| Feast Type | Python Type | ValueType | Description | +|------------|-------------|-----------|-------------| +| `Array(Array(T))` | `List[List[T]]` | `VALUE_LIST` | List of lists | +| `Array(Set(T))` | `List[List[T]]` | `VALUE_LIST` | List of sets | +| `Set(Array(T))` | `List[List[T]]` | `VALUE_SET` | Set of lists | +| `Set(Set(T))` | `List[List[T]]` | `VALUE_SET` | Set of sets | +| `Array(Array(Array(T)))` | `List[List[List[T]]]` | `VALUE_LIST` | 3-level nesting | + +Where `T` is any supported primitive type (Int32, Int64, Float32, Float64, String, Bytes, Bool, UnixTimestamp) or another nested collection type. + +**Notes:** +- Nesting depth is **unlimited**. `Array(Array(Array(T)))`, `Set(Array(Set(T)))`, etc. are all supported. +- Inner type information is preserved via Field tags (`feast:nested_inner_type`) and restored during deserialization. This tag is mandatory for nested collection types. +- Empty inner collections (`[]`) are stored as empty proto values and round-trip as `None`. For example, `[[1, 2], [], [3]]` becomes `[[1, 2], None, [3]]` after a write-read cycle. + ### Map Types Map types allow storing dictionary-like data structures: | Feast Type | Python Type | Description | |------------|-------------|-------------| -| `Map` | `Dict[str, Any]` | Dictionary with string keys and any supported Feast type as values (including nested maps) | +| `Map` | `Dict[str, Any]` | Dictionary with string keys and values of any supported Feast type (including nested maps) | | `Array(Map)` | `List[Dict[str, Any]]` | List of dictionaries | +| `ScalarMap` | `Dict[Any, Any]` | Dictionary with non-string scalar keys (int, float, bool, UUID, Decimal, bytes, datetime) and values of any supported Feast type | + +**Note:** `Map` keys must always be strings. `ScalarMap` supports non-string scalar keys — Feast infers `ScalarMap` automatically when the first key of a dict is not a string. Map values can be any supported Feast type, including primitives, arrays, or nested maps at the proto level. However, the PyArrow representation is `map`, which means backends that rely on PyArrow schemas (e.g., during materialization) treat Map as string-to-string. -**Note:** Map keys must always be strings. Map values can be any supported Feast type, including primitives, arrays, or nested maps. +{% hint style="warning" %} +`ScalarMap` is **not** inferred from any backend schema. You must declare it explicitly in your feature view schema. It is best suited for online serving use cases where the online store serializes proto bytes directly (e.g., Redis, DynamoDB, SQLite). +{% endhint %} + +**Backend support for Map:** + +| Backend | Native Type | Notes | +|---------|-------------|-------| +| PostgreSQL | `jsonb`, `jsonb[]` | `jsonb` → `Map`, `jsonb[]` → `Array(Map)` | +| Snowflake | `VARIANT`, `OBJECT` | Inferred as `Map` | +| Redshift | `SUPER` | Inferred as `Map` | +| Spark | `map` | `map<>` → `Map`, `array>` → `Array(Map)` | +| Athena | `map` | Inferred as `Map` | +| MSSQL | `nvarchar(max)` | Serialized as string | +| DynamoDB / Redis | Proto bytes | Full proto Map and ScalarMap support | + +### JSON Type + +The `Json` type represents opaque JSON data. Unlike `Map`, which is schema-free key-value storage, `Json` is stored as a string at the proto level but backends use native JSON types where available. + +| Feast Type | Python Type | Description | +|------------|-------------|-------------| +| `Json` | `str` (JSON-encoded) | JSON data stored as a string at the proto level | +| `Array(Json)` | `List[str]` | List of JSON strings | + +**Backend support for Json:** + +| Backend | Native Type | +|---------|-------------| +| PostgreSQL | `jsonb` | +| Snowflake | `JSON` / `VARIANT` | +| Redshift | `json` | +| BigQuery | `JSON` | +| Spark | Not natively distinguished from `String` | +| MSSQL | `nvarchar(max)` | + +{% hint style="info" %} +When a backend's native type is ambiguous (e.g., PostgreSQL `jsonb` could be `Map` or `Json`), **the schema-declared Feast type takes precedence**. The backend-to-Feast mappings are only used during schema inference when no explicit type is provided. +{% endhint %} + +### Struct Type + +The `Struct` type represents a schema-aware structured type with named, typed fields. Unlike `Map` (which is schema-free), a `Struct` declares its field names and their types, enabling schema validation. + +| Feast Type | Python Type | Description | +|------------|-------------|-------------| +| `Struct({"field": Type, ...})` | `Dict[str, Any]` | Named fields with typed values | +| `Array(Struct({"field": Type, ...}))` | `List[Dict[str, Any]]` | List of structs | + +**Example:** +```python +from feast.types import Struct, String, Int32, Array + +# Struct with named, typed fields +address_type = Struct({"street": String, "city": String, "zip": Int32}) +Field(name="address", dtype=address_type) + +# Array of structs +items_type = Array(Struct({"name": String, "quantity": Int32})) +Field(name="order_items", dtype=items_type) +``` + +**Backend support for Struct:** + +| Backend | Native Type | +|---------|-------------| +| BigQuery | `STRUCT` / `RECORD` | +| Spark | `struct<...>` / `array>` | +| PostgreSQL | `jsonb` (serialized) | +| Snowflake | `VARIANT` (serialized) | +| MSSQL | `nvarchar(max)` (serialized) | +| DynamoDB / Redis | Proto bytes | ## Complete Feature View Example @@ -77,7 +203,8 @@ from datetime import timedelta from feast import Entity, FeatureView, Field, FileSource from feast.types import ( Int32, Int64, Float32, Float64, String, Bytes, Bool, UnixTimestamp, - Array, Set, Map + Uuid, TimeUuid, Decimal, Array, Set, Map, ScalarMap, Json, Struct, + ZonedTimestamp ) # Define a data source @@ -107,7 +234,11 @@ user_features = FeatureView( Field(name="profile_picture", dtype=Bytes), Field(name="is_active", dtype=Bool), Field(name="last_login", dtype=UnixTimestamp), - + Field(name="event_time", dtype=ZonedTimestamp), + Field(name="session_id", dtype=Uuid), + Field(name="event_id", dtype=TimeUuid), + Field(name="price", dtype=Decimal), + # Array types Field(name="daily_steps", dtype=Array(Int32)), Field(name="transaction_history", dtype=Array(Int64)), @@ -117,17 +248,35 @@ user_features = FeatureView( Field(name="document_hashes", dtype=Array(Bytes)), Field(name="notification_settings", dtype=Array(Bool)), Field(name="login_timestamps", dtype=Array(UnixTimestamp)), - - # Set types (unique values only) + Field(name="related_session_ids", dtype=Array(Uuid)), + Field(name="event_chain", dtype=Array(TimeUuid)), + Field(name="historical_prices", dtype=Array(Decimal)), + + # Set types (unique values only — see backend caveats above) Field(name="visited_pages", dtype=Set(String)), Field(name="unique_categories", dtype=Set(Int32)), Field(name="tag_ids", dtype=Set(Int64)), Field(name="preferred_languages", dtype=Set(String)), - + Field(name="unique_device_ids", dtype=Set(Uuid)), + Field(name="unique_event_ids", dtype=Set(TimeUuid)), + Field(name="unique_prices", dtype=Set(Decimal)), + # Map types Field(name="user_preferences", dtype=Map), Field(name="metadata", dtype=Map), Field(name="activity_log", dtype=Array(Map)), + Field(name="event_counts", dtype=ScalarMap), # non-string keys, e.g. {1001: 5, 1002: 12} + + # Nested collection types + Field(name="weekly_scores", dtype=Array(Array(Float64))), + Field(name="unique_tags_per_category", dtype=Array(Set(String))), + + # JSON type + Field(name="raw_event", dtype=Json), + + # Struct type + Field(name="address", dtype=Struct({"street": String, "city": String, "zip": Int32})), + Field(name="order_items", dtype=Array(Struct({"name": String, "qty": Int32}))), ], source=user_features_source, ) @@ -151,12 +300,136 @@ tag_list = [100, 200, 300, 100, 200] tag_ids = set(tag_list) # {100, 200, 300} ``` +### UUID Type Usage Examples + +UUID types store universally unique identifiers natively, with support for both random UUIDs and time-based UUIDs: + +```python +import uuid + +# Random UUID (version 4) — use Uuid type +session_id = uuid.uuid4() # e.g., UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') + +# Time-based UUID (version 1) — use TimeUuid type +event_id = uuid.uuid1() # e.g., UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') + +# UUID values are returned as uuid.UUID objects from get_online_features() +response = store.get_online_features( + features=["user_features:session_id"], + entity_rows=[{"user_id": 1}], +) +result = response.to_dict() +# result["session_id"][0] is a uuid.UUID object + +# UUID lists +related_sessions = [uuid.uuid4(), uuid.uuid4(), uuid.uuid4()] + +# UUID sets (unique values) +unique_devices = {uuid.uuid4(), uuid.uuid4()} +``` + +### Decimal Type Usage Examples + +The `Decimal` type stores arbitrary-precision decimal numbers using Python's `decimal.Decimal`. +Values are stored as strings in the proto to preserve full precision — no floating-point rounding occurs. + +```python +import decimal + +# Scalar decimal — e.g., a financial price +price = decimal.Decimal("19.99") + +# High-precision value — all digits preserved +tax_rate = decimal.Decimal("0.08750000000000000000") + +# Decimal values are returned as decimal.Decimal objects from get_online_features() +response = store.get_online_features( + features=["product_features:price"], + entity_rows=[{"product_id": 42}], +) +result = response.to_dict() +# result["price"][0] is a decimal.Decimal object + +# Decimal lists — e.g., a history of prices +historical_prices = [ + decimal.Decimal("18.50"), + decimal.Decimal("19.00"), + decimal.Decimal("19.99"), +] + +# Decimal sets — unique price points seen +unique_prices = {decimal.Decimal("9.99"), decimal.Decimal("19.99"), decimal.Decimal("29.99")} +``` + +{% hint style="warning" %} +`Decimal` is **not** inferred from any backend schema. You must declare it explicitly in your feature view schema. The pandas dtype for `Decimal` columns is `object` (holding `decimal.Decimal` instances), not a numeric dtype. +{% endhint %} + +### ZonedTimestamp Type Usage Examples + +The `ZonedTimestamp` type stores a timezone-aware `datetime` as both the UTC instant +and its originating zone, so the original wall-clock zone round-trips losslessly. +By contrast, `UnixTimestamp` always decodes to UTC and discards the source zone. + +```python +from datetime import datetime, timezone +from zoneinfo import ZoneInfo + +# A datetime in a specific zone — both the instant and "America/Los_Angeles" are kept +event_time = datetime(2026, 6, 17, 9, 0, 0, tzinfo=ZoneInfo("America/Los_Angeles")) + +# ZonedTimestamp values are returned as tz-aware datetime objects, in their own zone +response = store.get_online_features( + features=["event_features:event_time"], + entity_rows=[{"user_id": 1001}], +) +result = response.to_dict() +# result["event_time"][0] == event_time (same instant AND same zone, e.g. 09:00-07:00) + +# Two values at the same instant but different zones stay distinct +la = datetime(2026, 6, 17, 9, 0, 0, tzinfo=ZoneInfo("America/Los_Angeles")) +utc = datetime(2026, 6, 17, 16, 0, 0, tzinfo=timezone.utc) # same instant as `la` + +# A naive (tz-less) datetime is interpreted as UTC +naive = datetime(2026, 6, 17, 12, 0, 0) # stored zone is empty, decoded as UTC +``` + +{% hint style="warning" %} +`ZonedTimestamp` is **not** inferred from any backend schema — you must declare it +explicitly in your feature view schema. It is not supported as an entity key. The +zone is stored as an IANA name (e.g. `America/Los_Angeles`) when available, falling +back to a fixed-offset string; offline stores that cannot natively carry a zone may +normalize to UTC on that backend. +{% endhint %} + +### Nested Collection Type Usage Examples + +```python +# List of lists — e.g., weekly score history per user +weekly_scores = [[85.0, 90.5, 78.0], [92.0, 88.5], [95.0, 91.0, 87.5]] + +# List of sets — e.g., unique tags assigned per category +unique_tags_per_category = [["python", "ml"], ["rust", "systems"], ["python", "web"]] + +# 3-level nesting — e.g., multi-dimensional matrices +Field(name="tensor", dtype=Array(Array(Array(Float64)))) + +# Mixed nesting +Field(name="grouped_tags", dtype=Array(Set(Array(String)))) +``` + +**Limitation:** Empty inner collections round-trip as `None`: +```python +# Input: [[1, 2], [], [3]] +# Output: [[1, 2], None, [3]] (empty [] becomes None after write-read cycle) +``` + ### Map Type Usage Examples Maps can store complex nested data structures: ```python -# Simple map +# Simple map (string keys) user_preferences = { "theme": "dark", "language": "en", @@ -184,6 +457,80 @@ activity_log = [ ] ``` +### ScalarMap Type Usage Examples + +`ScalarMap` supports non-string keys. Feast infers it automatically when the first dict key is not a string: + +```python +import uuid +import decimal + +# Integer keys — e.g., category ID → item count +event_counts = {1001: 5, 1002: 12, 1003: 0} + +# UUID keys — e.g., session ID → score +import uuid +session_scores = { + uuid.UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8"): 0.95, + uuid.UUID("a8098c1a-f86e-11da-bd1a-00112444be1e"): 0.87, +} + +# Decimal keys — e.g., price bucket → product name +price_tier = { + decimal.Decimal("9.99"): "budget", + decimal.Decimal("49.99"): "standard", + decimal.Decimal("99.99"): "premium", +} + +# Type inference: Feast automatically picks SCALAR_MAP when the key is non-string +from feast.type_map import python_type_to_feast_value_type +from feast.value_type import ValueType + +python_type_to_feast_value_type({1: "a"}) # → ValueType.SCALAR_MAP +python_type_to_feast_value_type({"a": 1}) # → ValueType.MAP +python_type_to_feast_value_type({}) # → ValueType.MAP (empty dict defaults to MAP) +``` + +{% hint style="warning" %} +`ScalarMap` must be **explicitly declared** in your feature view schema — it is never inferred from backend type schemas. It is best suited for online serving via stores that use proto byte serialization (e.g., Redis, DynamoDB, SQLite). Materialization paths that use PyArrow (e.g., BigQuery, Snowflake, Redshift, Spark) do not have native `ScalarMap` support. +{% endhint %} + +### JSON Type Usage Examples + +Feast's `Json` type stores values as JSON strings at the proto level. You can pass either a +pre-serialized JSON string or a Python dict/list — Feast will call `json.dumps()` automatically +when the value is not already a string: + +```python +import json + +# Option 1: pass a Python dict — Feast calls json.dumps() internally during proto conversion +raw_event = {"type": "click", "target": "button_1", "metadata": {"page": "home"}} + +# Option 2: pass an already-serialized JSON string — Feast validates it via json.loads() +raw_event = '{"type": "click", "target": "button_1", "metadata": {"page": "home"}}' + +# When building a DataFrame for store.push(), values must be strings since +# Pandas/PyArrow columns expect uniform types: +import pandas as pd +event_df = pd.DataFrame({ + "user_id": ["user_1"], + "event_timestamp": [datetime.now()], + "raw_event": [json.dumps({"type": "click", "target": "button_1"})], +}) +store.push("event_push_source", event_df) +``` + +### Struct Type Usage Examples + +```python +# Struct — schema-aware, fields and types are declared +from feast.types import Struct, String, Int32 + +address = Struct({"street": String, "city": String, "zip": Int32}) +# Value: {"street": "123 Main St", "city": "Springfield", "zip": 62704} +``` + ## Type System in Practice The sections below explain how Feast uses its type system in different contexts. @@ -195,7 +542,11 @@ For example, if the `schema` parameter is not specified for a feature view, Feas Each of these columns must be associated with a Feast type, which requires conversion from the data source type system to the Feast type system. * The feature inference logic calls `_infer_features_and_entities`. * `_infer_features_and_entities` calls `source_datatype_to_feast_value_type`. -* `source_datatype_to_feast_value_type` cals the appropriate method in `type_map.py`. For example, if a `SnowflakeSource` is being examined, `snowflake_python_type_to_feast_value_type` from `type_map.py` will be called. +* `source_datatype_to_feast_value_type` calls the appropriate method in `type_map.py`. For example, if a `SnowflakeSource` is being examined, `snowflake_python_type_to_feast_value_type` from `type_map.py` will be called. + +{% hint style="info" %} +**Types that cannot be inferred:** `Set`, `Json`, `Struct`, `Decimal`, `ScalarMap`, `PdfBytes`, and `ImageBytes` types are never inferred from backend schemas. If you use these types, you must declare them explicitly in your feature view schema. +{% endhint %} ### Materialization diff --git a/docs/roadmap.md b/docs/roadmap.md index eb517b6ae80..ab64289ba7b 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -17,32 +17,56 @@ The list below contains the functionality that contributors are planning to deve * [x] [Postgres (contrib plugin)](https://docs.feast.dev/reference/data-sources/postgres) * [x] [Spark (contrib plugin)](https://docs.feast.dev/reference/data-sources/spark) * [x] [Couchbase (contrib plugin)](https://docs.feast.dev/reference/data-sources/couchbase) + * [x] [Athena (contrib plugin)](https://docs.feast.dev/reference/data-sources/athena) + * [x] [Clickhouse (contrib plugin)](https://docs.feast.dev/reference/data-sources/clickhouse) + * [x] [Oracle (contrib plugin)](https://docs.feast.dev/reference/data-sources/oracle) + * [x] [MongoDB (contrib plugin)](https://docs.feast.dev/reference/data-sources/mongodb) + * [x] [Ray source (contrib plugin)](https://docs.feast.dev/reference/data-sources/ray) * [x] Kafka / Kinesis sources (via [push support into the online store](https://docs.feast.dev/reference/data-sources/push)) * **Offline Stores** * [x] [Snowflake](https://docs.feast.dev/reference/offline-stores/snowflake) * [x] [Redshift](https://docs.feast.dev/reference/offline-stores/redshift) * [x] [BigQuery](https://docs.feast.dev/reference/offline-stores/bigquery) - * [x] [Azure Synapse + Azure SQL (contrib plugin)](https://docs.feast.dev/reference/offline-stores/mssql.md) + * [x] [DuckDB](https://docs.feast.dev/reference/offline-stores/duckdb) + * [x] [Dask](https://docs.feast.dev/reference/offline-stores/dask) + * [x] [Remote](https://docs.feast.dev/reference/offline-stores/remote-offline-store) + * [x] [Azure Synapse + Azure SQL (contrib plugin)](https://docs.feast.dev/reference/offline-stores/mssql) * [x] [Hive (community plugin)](https://github.com/baineng/feast-hive) * [x] [Postgres (contrib plugin)](https://docs.feast.dev/reference/offline-stores/postgres) - * [x] [Trino (contrib plugin)](https://github.com/Shopify/feast-trino) + * [x] [Trino (contrib plugin)](https://docs.feast.dev/reference/offline-stores/trino) * [x] [Spark (contrib plugin)](https://docs.feast.dev/reference/offline-stores/spark) * [x] [Couchbase (contrib plugin)](https://docs.feast.dev/reference/offline-stores/couchbase) - * [x] [In-memory / Pandas](https://docs.feast.dev/reference/offline-stores/file) + * [x] [Athena (contrib plugin)](https://docs.feast.dev/reference/offline-stores/athena) + * [x] [Clickhouse (contrib plugin)](https://docs.feast.dev/reference/offline-stores/clickhouse) + * [x] [Ray (contrib plugin)](https://docs.feast.dev/reference/offline-stores/ray) + * [x] [Oracle (contrib plugin)](https://docs.feast.dev/reference/offline-stores/oracle) + * [x] [MongoDB (contrib plugin)](https://docs.feast.dev/reference/offline-stores/mongodb) + * [x] [Hybrid](https://docs.feast.dev/reference/offline-stores/hybrid) * [x] [Custom offline store support](https://docs.feast.dev/how-to-guides/customizing-feast/adding-a-new-offline-store) * **Online Stores** * [x] [Snowflake](https://docs.feast.dev/reference/online-stores/snowflake) * [x] [DynamoDB](https://docs.feast.dev/reference/online-stores/dynamodb) * [x] [Redis](https://docs.feast.dev/reference/online-stores/redis) + * [x] [Dragonfly](https://docs.feast.dev/reference/online-stores/dragonfly) * [x] [Datastore](https://docs.feast.dev/reference/online-stores/datastore) * [x] [Bigtable](https://docs.feast.dev/reference/online-stores/bigtable) * [x] [SQLite](https://docs.feast.dev/reference/online-stores/sqlite) - * [x] [Dragonfly](https://docs.feast.dev/reference/online-stores/dragonfly) + * [x] [Remote](https://docs.feast.dev/reference/online-stores/remote) + * [x] [Postgres](https://docs.feast.dev/reference/online-stores/postgres) + * [x] [HBase](https://docs.feast.dev/reference/online-stores/hbase) + * [x] [Cassandra / AstraDB](https://docs.feast.dev/reference/online-stores/cassandra) + * [x] [ScyllaDB](https://docs.feast.dev/reference/online-stores/scylladb) + * [x] [MySQL](https://docs.feast.dev/reference/online-stores/mysql) + * [x] [Hazelcast](https://docs.feast.dev/reference/online-stores/hazelcast) + * [x] [Elasticsearch](https://docs.feast.dev/reference/online-stores/elasticsearch) + * [x] [SingleStore](https://docs.feast.dev/reference/online-stores/singlestore) + * [x] [Couchbase](https://docs.feast.dev/reference/online-stores/couchbase) + * [x] [MongoDB](https://docs.feast.dev/reference/online-stores/mongodb) + * [x] [Qdrant (vector store)](https://docs.feast.dev/reference/online-stores/qdrant) + * [x] [Milvus (vector store)](https://docs.feast.dev/reference/online-stores/milvus) + * [x] [Faiss (vector store)](https://docs.feast.dev/reference/online-stores/faiss) + * [x] [Hybrid](https://docs.feast.dev/reference/online-stores/hybrid) * [x] [Azure Cache for Redis (community plugin)](https://github.com/Azure/feast-azure) - * [x] [Postgres (contrib plugin)](https://docs.feast.dev/reference/online-stores/postgres) - * [x] [Cassandra / AstraDB (contrib plugin)](https://docs.feast.dev/reference/online-stores/cassandra) - * [x] [ScyllaDB (contrib plugin)](https://docs.feast.dev/reference/online-stores/scylladb) - * [x] [Couchbase (contrib plugin)](https://docs.feast.dev/reference/online-stores/couchbase) * [x] [Custom online store support](https://docs.feast.dev/how-to-guides/customizing-feast/adding-support-for-a-new-online-store) * **Feature Engineering** * [x] On-demand Transformations (On Read) (Beta release. See [RFC](https://docs.google.com/document/d/1lgfIw0Drc65LpaxbUu49RCeJgMew547meSJttnUqz7c/edit#)) @@ -65,7 +89,8 @@ The list below contains the functionality that contributors are planning to deve * [x] [Offline Feature Server (alpha)](https://docs.feast.dev/reference/feature-servers/offline-feature-server) * [x] [Registry server (alpha)](https://github.com/feast-dev/feast/blob/master/docs/reference/feature-servers/registry-server.md) * **Data Quality Management (See [RFC](https://docs.google.com/document/d/110F72d4NTv80p35wDSONxhhPBqWRwbZXG4f9mNEMd98/edit))** - * [x] Data profiling and validation (Great Expectations) + * [x] ~~Data profiling and validation (Great Expectations)~~ (deprecated) + * [x] [Feature Quality Monitoring](https://docs.feast.dev/how-to-guides/feature-monitoring) — built-in metrics, drift detection, serving log monitoring, and UI dashboard * **Feature Discovery and Governance** * [x] Python SDK for browsing feature registry * [x] CLI for browsing feature registry diff --git a/docs/tutorials/demo-notebooks.md b/docs/tutorials/demo-notebooks.md new file mode 100644 index 00000000000..8c0ba059f81 --- /dev/null +++ b/docs/tutorials/demo-notebooks.md @@ -0,0 +1,114 @@ +# Demo Notebooks + +Feast can generate tailored Jupyter notebooks for any Feast project. The notebooks adapt to your `feature_store.yaml` configuration and provide a hands-on walkthrough of core Feast functionality. + +## What you get + +For each project discovered, Feast creates a directory with notebooks covering: + +| Notebook | Description | +|----------|-------------| +| **01 — Feature Store Overview** | Explore registered entities, feature views, feature services, and data sources. | +| **02 — Historical Feature Retrieval** | Build a training dataset with point-in-time correct joins using `get_historical_features`. | +| **03 — Online Feature Serving** | Materialize features to the online store and retrieve them at low latency with `get_online_features`. | + +The content adapts automatically based on: + +* **Online / offline store types** — descriptions reflect the actual backends configured. +* **Registry type** — local registries include `feast apply`; remote registries use `refresh_registry()`. +* **Authentication** — auth details from `feature_store.yaml` are surfaced when configured. +* **Vector search** — a vector/RAG retrieval section is included when embeddings are detected. + +## Prerequisites + +* Python 3.9+ +* Feast installed (`pip install feast`) +* A feature repository with a valid `feature_store.yaml` + +## Using the CLI + +Run the command from (or pointing to) a directory containing `feature_store.yaml`: + +```bash +feast demo-notebooks +``` + +This searches for `feature_store.yaml` in the current directory and every file inside the `feast-config/` directory. Each file in `feast-config/` is treated as a separate project config. For each project found, notebooks are written to `./feast-demo-notebooks//`. + +### Options + +| Option | Default | Description | +|--------|---------|-------------| +| `-o, --output-dir` | `./feast-demo-notebooks` | Root directory for generated notebooks | +| `--overwrite` | `false` | Overwrite if the output directory already exists | + +```bash +# Write to a custom directory +feast demo-notebooks -o ./my-notebooks + +# Overwrite existing notebooks +feast demo-notebooks --overwrite + +# Use --chdir to point at a different feature repo +feast -c /path/to/feature_repo demo-notebooks +``` + +## Using the Python SDK + +```python +from feast import copy_demo_notebooks + +copy_demo_notebooks() +``` + +### Parameters + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `output_dir` | `str` | `"./feast-demo-notebooks"` | Root directory for generated notebooks | +| `repo_path` | `str` | `"."` | Directory to search for `feature_store.yaml` files | +| `overwrite` | `bool` | `False` | Overwrite existing output directories | + +### Examples + +```python +from feast import copy_demo_notebooks + +# Default — searches current directory, writes to ./feast-demo-notebooks/ +copy_demo_notebooks() + +# Custom paths +copy_demo_notebooks( + output_dir="/home/user/notebooks", + repo_path="/home/user/feast-projects/my-repo/feature_repo", + overwrite=True, +) +``` + +## Multi-project repositories + +If your `feast-config/` directory contains multiple files, each is treated as a separate project and a dedicated notebook directory is created: + +``` +feast-demo-notebooks/ +├── project_alpha/ +│ ├── 01_feature_store_overview.ipynb +│ ├── 02_historical_features_training.ipynb +│ └── 03_online_features_serving.ipynb +└── project_beta/ + ├── 01_feature_store_overview.ipynb + ├── 02_historical_features_training.ipynb + └── 03_online_features_serving.ipynb +``` + +## Running the notebooks + +Open any generated notebook in Jupyter, JupyterLab, or VS Code and run cells from top to bottom. Each notebook: + +1. Configures the path to your `feature_store.yaml` automatically (no manual editing needed). +2. Connects to the feature store using the Feast Python SDK. +3. Walks through relevant operations with real data from your project. + +{% hint style="info" %} +The first notebook (**01 — Overview**) includes a prerequisites check and `feast apply` / registry sync step. Subsequent notebooks assume these have already been completed. +{% endhint %} diff --git a/docs/tutorials/rag-with-docling.md b/docs/tutorials/rag-with-docling.md index 88f2bd2aad7..6b85db4177c 100644 --- a/docs/tutorials/rag-with-docling.md +++ b/docs/tutorials/rag-with-docling.md @@ -409,6 +409,234 @@ response = client.chat.completions.create( print('\n'.join([c.message.content for c in response.choices])) ``` +## Alternative: Using DocEmbedder for Simplified Ingestion + +Instead of manually chunking, embedding, and writing documents as shown above, you can use Feast's `DocEmbedder` class to handle the entire pipeline in a single step. `DocEmbedder` automates chunking, embedding generation, FeatureView creation, and writing to the online store. + +### Install Dependencies + +```bash +pip install feast[milvus,rag] +``` + +### Set Up and Ingest with DocEmbedder + +```python +from feast import DocEmbedder +import pandas as pd + +# Prepare your documents as a DataFrame +df = pd.DataFrame({ + "id": ["doc1", "doc2", "doc3"], + "text": [ + "Aaron is a prophet, high priest, and the brother of Moses...", + "God at Sinai granted Aaron the priesthood for himself...", + "His rod turned into a snake. Then he stretched out...", + ], +}) + +# DocEmbedder handles everything: generates FeatureView, applies repo, +# chunks text, generates embeddings, and writes to the online store +embedder = DocEmbedder( + repo_path="feature_repo/", + feature_view_name="text_feature_view", +) + +result = embedder.embed_documents( + documents=df, + id_column="id", + source_column="text", + column_mapping=("text", "text_embedding"), +) +``` + +### Retrieve and Query + +Once documents are ingested, you can retrieve them the same way as shown in Step 5 above: + +```python +from feast import FeatureStore + +store = FeatureStore("feature_repo/") + +query_embedding = embed_text("Who are the authors of the paper?") +context_data = store.retrieve_online_documents_v2( + features=[ + "text_feature_view:embedding", + "text_feature_view:text", + "text_feature_view:source_id", + ], + query=query_embedding, + top_k=3, + distance_metric="COSINE", +).to_df() +``` + +### Customizing the Pipeline + +`DocEmbedder` is extensible at every stage. Below are examples of how to create custom components and wire them together. + +#### Custom Chunker + +Subclass `BaseChunker` to implement your own chunking strategy. The `load_parse_and_chunk` method receives each document and must return a list of chunk dictionaries. + +```python +from feast.chunker import BaseChunker, ChunkingConfig +from typing import Any, Optional + +class SentenceChunker(BaseChunker): + """Chunks text by sentences instead of word count.""" + + def load_parse_and_chunk( + self, + source: Any, + source_id: str, + source_column: str, + source_type: Optional[str] = None, + ) -> list[dict]: + import re + + text = str(source) + # Split on sentence boundaries + sentences = re.split(r'(?<=[.!?])\s+', text) + + chunks = [] + current_chunk = [] + chunk_index = 0 + + for sentence in sentences: + current_chunk.append(sentence) + combined = " ".join(current_chunk) + + if len(combined.split()) >= self.config.chunk_size: + chunks.append({ + "chunk_id": f"{source_id}_{chunk_index}", + "original_id": source_id, + source_column: combined, + "chunk_index": chunk_index, + }) + # Keep overlap by retaining the last sentence + current_chunk = [sentence] + chunk_index += 1 + + # Don't forget the last chunk + if current_chunk and len(" ".join(current_chunk).split()) >= self.config.min_chunk_size: + chunks.append({ + "chunk_id": f"{source_id}_{chunk_index}", + "original_id": source_id, + source_column: " ".join(current_chunk), + "chunk_index": chunk_index, + }) + + return chunks +``` + +Or simply configure the built-in `TextChunker`: + +```python +from feast import TextChunker, ChunkingConfig + +chunker = TextChunker(config=ChunkingConfig( + chunk_size=200, + chunk_overlap=50, + min_chunk_size=30, + max_chunk_chars=1000, +)) +``` + +#### Custom Embedder + +Subclass `BaseEmbedder` to use a different embedding model. Register modality handlers in `_register_default_modalities` and implement the `embed` method. + +```python +from feast.embedder import BaseEmbedder, EmbeddingConfig +from typing import Any, List, Optional +import numpy as np + +class OpenAIEmbedder(BaseEmbedder): + """Embedder that uses the OpenAI API for text embeddings.""" + + def __init__(self, model: str = "text-embedding-3-small", config: Optional[EmbeddingConfig] = None): + self.model = model + self._client = None + super().__init__(config) + + def _register_default_modalities(self) -> None: + self.register_modality("text", self._embed_text) + + @property + def client(self): + if self._client is None: + from openai import OpenAI + self._client = OpenAI() + return self._client + + def get_embedding_dim(self, modality: str) -> Optional[int]: + # text-embedding-3-small produces 1536-dim vectors + if modality == "text": + return 1536 + return None + + def embed(self, inputs: List[Any], modality: str) -> np.ndarray: + if modality not in self._modality_handlers: + raise ValueError(f"Unsupported modality: '{modality}'") + return self._modality_handlers[modality](inputs) + + def _embed_text(self, inputs: List[str]) -> np.ndarray: + response = self.client.embeddings.create(input=inputs, model=self.model) + return np.array([item.embedding for item in response.data]) +``` + +#### Custom Logical Layer Function + +The schema transform function transforms the chunked + embedded DataFrame into the exact schema your FeatureView expects. It must accept a `pd.DataFrame` and return a `pd.DataFrame`. + +```python +import pandas as pd +from datetime import datetime, timezone + +def my_schema_transform_fn(df: pd.DataFrame) -> pd.DataFrame: + """Map chunked + embedded columns to the FeatureView schema.""" + return pd.DataFrame({ + "passage_id": df["chunk_id"], + "text": df["text"], + "embedding": df["text_embedding"], + "event_timestamp": [datetime.now(timezone.utc)] * len(df), + "source_id": df["original_id"], + # Add any extra columns your FeatureView expects + "chunk_index": df["chunk_index"], + }) +``` + +#### Putting It All Together + +Pass your custom components to `DocEmbedder`: + +```python +from feast import DocEmbedder + +embedder = DocEmbedder( + repo_path="feature_repo/", + feature_view_name="text_feature_view", + chunker=SentenceChunker(config=ChunkingConfig(chunk_size=150, min_chunk_size=20)), + embedder=OpenAIEmbedder(model="text-embedding-3-small"), + schema_transform_fn=my_schema_transform_fn, + vector_length=1536, # Match the OpenAI embedding dimension +) + +# Embed and ingest +result = embedder.embed_documents( + documents=df, + id_column="id", + source_column="text", + column_mapping=("text", "text_embedding"), +) +``` + +> **Note:** When using a custom `schema_transform_fn`, ensure the returned DataFrame columns match your FeatureView schema. When using a custom embedder with a different output dimension, set `vector_length` accordingly (or let it auto-detect via `get_embedding_dim`). + +For a complete end-to-end example, see the [DocEmbedder notebook](https://github.com/feast-dev/feast/tree/master/examples/rag-retriever/rag_feast_docembedder.ipynb). + ## Why Feast for RAG? Feast makes it remarkably easy to set up and manage a RAG system by: diff --git a/docs/tutorials/validating-historical-features.md b/docs/tutorials/validating-historical-features.md index 1984adcdcf9..f2037f7c9c9 100644 --- a/docs/tutorials/validating-historical-features.md +++ b/docs/tutorials/validating-historical-features.md @@ -1,5 +1,9 @@ # Validating historical features with Great Expectations +{% hint style="warning" %} +**Deprecated:** This tutorial demonstrates the legacy Great Expectations-based validation which is deprecated. For new projects, use Feast's built-in [Feature Quality Monitoring](../how-to-guides/feature-monitoring.md) system which provides automatic metrics computation, drift detection, and a monitoring UI — with no external dependencies required. See also the [Monitoring Quickstart notebook](../../examples/monitoring/monitoring-quickstart.ipynb). +{% endhint %} + In this tutorial, we will use the public dataset of Chicago taxi trips to present data validation capabilities of Feast. - The original dataset is stored in BigQuery and consists of raw data for each taxi trip (one row per trip) since 2013. - We will generate several training datasets (aka historical features in Feast) for different periods and evaluate expectations made on one dataset against another. @@ -661,7 +665,7 @@ _ = job.to_df(validation_reference=validation_reference) 02/02/2022 02:43:53 PM INFO: Validating data_asset_name None with expectation_suite_name default -Validation successfully passed as no exception were raised. +Validation successfully passed as no exceptions were raised. ### 5. Validating new historical retrieval diff --git a/examples/agent_feature_store/README.md b/examples/agent_feature_store/README.md new file mode 100644 index 00000000000..039b580fd59 --- /dev/null +++ b/examples/agent_feature_store/README.md @@ -0,0 +1,420 @@ +# Feast-Powered AI Agent Example + +This example demonstrates an **AI agent with persistent memory** that uses **Feast as both a feature store and a context memory layer** through the **Model Context Protocol (MCP)**. This demo uses **Milvus** as the vector-capable online store, but Feast supports multiple vector backends -- including **Milvus, Elasticsearch, Qdrant, PGVector, and FAISS** -- swappable via configuration. + +## Why Feast for Agents? + +Agents need more than just access to data -- they need to **remember** what happened in prior interactions. Feast's online store is entity-keyed, low-latency, governed, and supports both reads and writes, making it a natural fit for agent context and memory. + +| Capability | How Feast Provides It | +|---|---| +| **Structured context** | Entity-keyed feature retrieval (customer profiles, account data) | +| **Document search** | Vector similarity search via pluggable backends (Milvus, Elasticsearch, Qdrant, PGVector, FAISS) | +| **Persistent memory** | Auto-checkpointed after each turn via `write_to_online_store` | +| **Governance** | RBAC, audit trails, and feature-level permissions | +| **TTL management** | Declarative expiration on feature views (memory auto-expires) | +| **Offline analysis** | Memory is queryable offline like any other feature | + +## Architecture + +```mermaid +%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#E3F2FD', 'primaryBorderColor': '#1565C0', 'primaryTextColor': '#0D47A1', 'lineColor': '#546E7A', 'secondaryColor': '#F3E5F5', 'tertiaryColor': '#E8F5E9'}}}%% +flowchart LR + User((("🧑 User"))):::userClass + + subgraph AgentLoop ["🤖 Agent Loop"] + LLM["LLM Engine\ntool-calling · reasoning"]:::agentClass + end + + subgraph Feast ["🏗️ Feast MCP Server"] + direction TB + ReadAPI["get_online_features\nretrieve_online_documents"]:::feastClass + WriteAPI["write_to_online_store"]:::feastClass + end + + subgraph VectorStore ["🗄️ Online Store"] + direction TB + Profiles[("👤 customer_profile\nplan · spend · tickets")]:::storageClass + Articles[("📚 knowledge_base\nvector embeddings")]:::storageClass + Memory[("🧠 agent_memory\ntopic · resolution · prefs")]:::memoryClass + end + + User -->|"query"| LLM + LLM -->|"MCP: recall_memory\nlookup_customer\nsearch_kb"| ReadAPI + LLM -->|"MCP: auto-checkpoint"| WriteAPI + ReadAPI --> Profiles + ReadAPI --> Articles + ReadAPI --> Memory + WriteAPI --> Memory + ReadAPI -.->|"results"| LLM + LLM -->|"answer"| User + + classDef userClass fill:#E8EAF6,stroke:#283593,color:#1A237E + classDef agentClass fill:#E3F2FD,stroke:#1565C0,color:#0D47A1 + classDef feastClass fill:#FFF3E0,stroke:#E65100,color:#BF360C + classDef storageClass fill:#E8F5E9,stroke:#2E7D32,color:#1B5E20 + classDef memoryClass fill:#F3E5F5,stroke:#6A1B9A,color:#4A148C +``` + +## Tools (backed by Feast) + +The agent has four tools. Feast is both the **read path** (context) and the **write path** (memory): + +| Tool | Direction | What it does | When the LLM calls it | +|---|---|---|---| +| `lookup_customer` | READ | Fetches customer profile features (plan, spend, tickets) | Questions about the customer's account | +| `search_knowledge_base` | READ | Retrieves support articles from the vector store | Questions needing product docs | +| `recall_memory` | READ | Reads past interaction context (last topic, open issues, preferences) | Start of every conversation | + +Memory is **auto-saved after each agent turn** (not as an LLM tool call). This follows the same pattern used by production frameworks -- see [Memory as Infrastructure](#memory-as-infrastructure) below. + +### Feast as Context Memory + +The `agent_memory` feature view stores per-customer interaction state: + +```python +agent_memory = FeatureView( + name="agent_memory", + entities=[customer], + schema=[ + Field(name="last_topic", dtype=String), + Field(name="last_resolution", dtype=String), + Field(name="interaction_count", dtype=Int64), + Field(name="preferences", dtype=String), + Field(name="open_issue", dtype=String), + ], + ttl=timedelta(days=30), +) +``` + +This gives agents **persistent, governed, entity-keyed memory** that survives across sessions, is versioned, and lives under the same RBAC as every other feature -- unlike an ad-hoc Redis cache or an in-process dict. + +### Memory as Infrastructure + +Production agent frameworks treat memory as **infrastructure, not an LLM decision**. The framework auto-saves state after each step - the LLM never needs to "decide" to persist: + +| Framework | Memory mechanism | How it works | +|---|---|---| +| **LangGraph** | Checkpointers (`MemorySaver`, `PostgresSaver`) | Every graph step is checkpointed automatically by `thread_id` | +| **CrewAI** | Built-in memory (`memory=True`) | Short-term, long-term, and entity memory auto-persist after each task | +| **AutoGen** | Teachable agents | Post-conversation hooks extract and store learnings in a vector DB | +| **OpenAI Agents SDK** | Application-level | Serialize `RunResult` between turns; framework manages state | + +This demo follows the same pattern: the agent's three read tools (`recall_memory`, `lookup_customer`, `search_knowledge_base`) are exposed to the LLM for reasoning, while **memory persistence is handled by the framework after each turn** via `_auto_save_memory`. This ensures consistent, reliable memory regardless of LLM behaviour - no risk of the LLM forgetting to save, double-saving, or writing inconsistent state. + +Feast is a natural fit for this checkpoint layer because it already provides: +- **Entity-keyed storage**: memory is keyed by customer ID (or any entity) +- **TTL management**: memory auto-expires via declarative feature view TTL +- **Schema enforcement**: typed fields prevent corrupt memory writes +- **RBAC and audit trails**: memory reads/writes are governed like any other feature +- **Offline queryability**: agent memory can be analysed in batch pipelines + +## Prerequisites + +- Python 3.10+ +- Feast with MCP and Milvus support +- OpenAI API key (for live tool-calling; demo mode works without it) + +## Quickstart + +### One command + +```bash +cd examples/agent_feature_store +./run_demo.sh + +# Or with live LLM tool-calling: +OPENAI_API_KEY=sk-... ./run_demo.sh +``` + +The script installs dependencies, generates sample data, starts the Feast server, runs the agent, and cleans up on exit. + +### Step by step + +### 1. Install dependencies + +```bash +pip install "feast[mcp,milvus]" +``` + +### 2. Generate sample data and apply the registry + +```bash +cd examples/agent_feature_store +python setup_data.py +``` + +This creates: +- **3 customer profiles** with attributes like plan tier, spend, and satisfaction score +- **6 knowledge-base articles** with 384-dimensional vector embeddings +- **Empty agent memory scaffold** (populated as the agent runs) + +### 3. Start the Feast MCP Feature Server + +```bash +cd feature_repo +feast serve --host 0.0.0.0 --port 6566 --workers 1 +``` + +### 4. Run the agent + +In a new terminal: + +```bash +# Without API key: runs in demo mode (simulated tool selection) +python agent.py +``` + +To run with a real LLM, set the API key and (optionally) the base URL: + +```bash +# OpenAI +export OPENAI_API_KEY="sk-..." #pragma: allowlist secret +python agent.py + +# Ollama (free, local -- no API key needed) +ollama pull llama3.1:8b +export OPENAI_API_KEY="ollama" #pragma: allowlist secret +export OPENAI_BASE_URL="http://localhost:11434/v1" +export LLM_MODEL="llama3.1:8b" +python agent.py + +# Any OpenAI-compatible provider (Azure, vLLM, LiteLLM, etc.) +export OPENAI_API_KEY="your-key" #pragma: allowlist secret +export OPENAI_BASE_URL="https://your-endpoint/v1" +export LLM_MODEL="your-model" +python agent.py +``` + +### Demo mode output + +Without an API key, the agent simulates the decision-making process with memory: + +``` +================================================================= + Scene 1: Enterprise customer (C1001) asks about SSO + Customer: C1001 | Query: "How do I set up SSO for my team?" +================================================================= + [Demo mode] Simulating agent reasoning + + Round 1 | recall_memory(customer_id=C1001) + -> No prior interactions found + + Round 1 | lookup_customer(customer_id=C1001) + -> Alice Johnson | enterprise plan | $24,500 spend | 1 open tickets + + Round 1 | search_knowledge_base(query="How do I set up SSO for my team?...") + -> Best match: "Configuring single sign-on (SSO)" + + Round 2 | Generating personalised response... + + ───────────────────────────────────────────────────────────── + Agent Response: + ───────────────────────────────────────────────────────────── + Hi Alice! + Since you're on our Enterprise plan, SSO is available for your + team. Go to Settings > Security > SSO and enter your Identity + Provider metadata URL. We support SAML 2.0 and OIDC... + + [Checkpoint] Memory saved: topic="SSO setup" + +================================================================= + Scene 4: C1001 returns -- does the agent remember Scene 1? + Customer: C1001 | Query: "I'm back about my SSO question from earlier." +================================================================= + [Demo mode] Simulating agent reasoning + + Round 1 | recall_memory(customer_id=C1001) + -> Previous topic: SSO setup + -> Open issue: none + -> Interaction count: 1 + + Round 1 | lookup_customer(customer_id=C1001) + -> Alice Johnson | enterprise plan | $24,500 spend | 1 open tickets + + Round 2 | Generating personalised response... + + ───────────────────────────────────────────────────────────── + Agent Response: + ───────────────────────────────────────────────────────────── + Welcome back, Alice! I can see from our records that we last + discussed "SSO setup". How can I help you today? + + [Checkpoint] Memory saved: topic="SSO setup" +``` + +Scene 4 demonstrates memory continuity -- the agent recalls the SSO conversation from Scene 1 without the customer re-explaining. + +### Live mode output (with API key) + +With an API key, the LLM autonomously decides which tools to use: + +``` +================================================================= + Scene 1: Enterprise customer (C1001) asks about SSO + Customer: C1001 | Query: "How do I set up SSO for my team?" +================================================================= + [Round 1] Tool call: recall_memory({'customer_id': 'C1001'}) + [Round 1] Tool call: lookup_customer({'customer_id': 'C1001'}) + [Round 1] Tool call: search_knowledge_base({'query': 'SSO setup'}) + Agent finished after 2 round(s) + + ───────────────────────────────────────────────────────────── + Agent Response: + ───────────────────────────────────────────────────────────── + Hi Alice! Since you're on our Enterprise plan, SSO is available + for your team. Go to Settings > Security > SSO and enter your + Identity Provider metadata URL. We support SAML 2.0 and OIDC... + + [Checkpoint] Memory saved: topic="SSO setup" +``` + +## How It Works + +> **Why a raw loop?** This example builds the agent from scratch using the OpenAI tool-calling API and the MCP Python SDK to keep dependencies minimal and make every Feast call visible. All Feast interactions go through the MCP protocol -- the agent connects to Feast's MCP endpoint, discovers tools dynamically, and invokes them via `session.call_tool()`. In production, you would use a framework like LangChain/LangGraph, LlamaIndex, CrewAI, or AutoGen -- Feast's MCP endpoint lets any of them auto-discover the tools with zero custom wiring (see [MCP Integration](#mcp-integration) below). + +### The Agent Loop (`agent.py`) + +```python +from mcp import ClientSession +from mcp.client.streamable_http import streamablehttp_client + +async with streamablehttp_client("http://localhost:6566/mcp") as (r, w, _): + async with ClientSession(r, w) as session: + await session.initialize() + tools = await session.list_tools() # discover Feast tools + + for round in range(MAX_ROUNDS): + # 1. Send messages + read tools to LLM + response = call_llm(messages, tools=[...]) + + # 2. If LLM says "stop" -> return the answer + if response.finish_reason == "stop": + break + + # 3. Execute tool calls via MCP + for tool_call in response.tool_calls: + result = await session.call_tool(name, args) + messages.append(tool_result(result)) + + # 4. Framework-style checkpoint: auto-save via MCP + await session.call_tool("write_to_online_store", {...}) +``` + +The LLM sees the tool definitions (JSON Schema) and decides: +- **Which tools to call** (can call zero, one, or multiple per round) +- **What arguments to pass** (e.g., which customer ID to look up) +- **When to stop** (once it has enough information to answer) + +All Feast calls go through **MCP** (`session.call_tool()`), not direct REST. Memory is saved **automatically after each turn** by the framework, not by the LLM. This mirrors how production frameworks handle persistence (see [Memory as Infrastructure](#memory-as-infrastructure)). + +### Feature Definitions (`feature_repo/features.py`) + +- **`customer_profile`**: Structured data (name, plan, spend, tickets, satisfaction) +- **`knowledge_base`**: Support articles with 384-dim vector embeddings (Milvus in this demo; swappable to Elasticsearch, Qdrant, PGVector, or FAISS) +- **`agent_memory`**: Per-customer interaction history (last topic, resolution, preferences, open issues) + +### MCP Integration + +The Feast Feature Server exposes all endpoints as MCP tools at `http://localhost:6566/mcp`. +Any MCP-compatible framework can connect: + +```python +# LangChain / LangGraph +from langchain_mcp_adapters.client import MultiServerMCPClient +from langgraph.prebuilt import create_react_agent + +async with MultiServerMCPClient( + {"feast": {"url": "http://localhost:6566/mcp", "transport": "streamable_http"}} +) as client: + tools = client.get_tools() + agent = create_react_agent(llm, tools) + result = await agent.ainvoke({"messages": "How do I set up SSO?"}) +``` + +```python +# LlamaIndex +from llama_index.tools.mcp import aget_tools_from_mcp_url +from llama_index.core.agent.function_calling import FunctionCallingAgent +from llama_index.llms.openai import OpenAI + +tools = await aget_tools_from_mcp_url("http://localhost:6566/mcp") +agent = FunctionCallingAgent.from_tools(tools, llm=OpenAI(model="gpt-4o-mini")) +response = await agent.achat("How do I set up SSO?") +``` + +```json +// Claude Desktop / Cursor +{ + "mcpServers": { + "feast": { + "url": "http://localhost:6566/mcp", + "transport": "streamable_http" + } + } +} +``` + +> **Building the same agent with a framework:** The examples above show the Feast-specific part -- connecting to the MCP endpoint and getting the tools. Once you have the tools, building the agent follows each framework's standard patterns. The key difference from this demo's raw loop: frameworks handle the tool-calling loop, message threading, and (with LangGraph checkpointers or CrewAI `memory=True`) automatic state persistence natively. Feast's MCP endpoint means zero custom integration code -- the tools are discovered and callable immediately. + +**Adapting to your use case:** The demo's system prompt, tool wrappers (`lookup_customer`, `recall_memory`), and feature views are all specific to customer support. For your own agent, you define your feature views in Feast (e.g., `product_catalog`, `order_history`, `fraud_signals`), run `feast apply`, and start the server. The same three generic MCP tools -- `get_online_features`, `retrieve_online_documents`, and `write_to_online_store` -- serve any domain. With a framework like LangChain or LlamaIndex, you don't even need custom tool wrappers -- the LLM calls the generic Feast tools directly with your feature view names and entities. + +## Production Deployment + +For production, Feast fits into a layered platform architecture: + +```mermaid +%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#E3F2FD', 'primaryBorderColor': '#1565C0', 'lineColor': '#546E7A'}}}%% +flowchart TB + Agent(("🤖 AI Agent")):::agentClass + + subgraph Platform ["🛡️ Production Platform"] + direction TB + Gateway["🔐 MCP Gateway\nJWT auth · tool filtering"]:::platformClass + Sandbox["📦 Sandboxed Container\nkernel-level isolation"]:::platformClass + Guardrails["🛑 Guardrails Orchestrator\ninput/output screening"]:::platformClass + end + + subgraph Observability ["📊 Observability + Lifecycle"] + direction LR + OTel["OpenTelemetry + MLflow\ntraces · metrics · audit"]:::obsClass + Kagenti["Kagenti Operator\nAgentCard CRDs · discovery"]:::lifecycleClass + end + + subgraph FeastSvc ["🏗️ Feast MCP Server"] + FS["/mcp · /get-online-features · /write-to-online-store"]:::feastClass + end + + subgraph Store ["🗄️ Online Store"] + direction LR + P[("👤 Profiles")]:::storageClass + K[("📚 Knowledge Base")]:::storageClass + M[("🧠 Agent Memory")]:::memoryClass + end + + Agent --> Gateway + Gateway --> Sandbox + Sandbox --> Guardrails + Guardrails --> FS + FS --> P + FS --> K + FS <--> M + OTel -.->|"traces"| FS + Kagenti -.->|"discover"| FS + + classDef agentClass fill:#E3F2FD,stroke:#1565C0,color:#0D47A1 + classDef platformClass fill:#FFEBEE,stroke:#C62828,color:#B71C1C + classDef obsClass fill:#FFF8E1,stroke:#F57F17,color:#E65100 + classDef lifecycleClass fill:#E0F2F1,stroke:#00695C,color:#004D40 + classDef feastClass fill:#FFF3E0,stroke:#E65100,color:#BF360C + classDef storageClass fill:#E8F5E9,stroke:#2E7D32,color:#1B5E20 + classDef memoryClass fill:#F3E5F5,stroke:#6A1B9A,color:#4A148C +``` + +This demo uses Milvus Lite (embedded). For production, swap to any supported vector-capable backend by updating `feature_store.yaml`: + +- **Milvus cluster**: Deploy via the [Milvus Operator](https://milvus.io/docs/install_cluster-milvusoperator.md) and set `host`/`port` instead of `path`. +- **Elasticsearch**: Set `online_store: type: elasticsearch` with your cluster URL. +- **Qdrant**: Set `online_store: type: qdrant` with your Qdrant endpoint. +- **PGVector**: Set `online_store: type: postgres` with `pgvector_enabled: true`. +- **FAISS**: Set `online_store: type: faiss` for in-process vector search. diff --git a/examples/agent_feature_store/agent.py b/examples/agent_feature_store/agent.py new file mode 100644 index 00000000000..3297cbe393e --- /dev/null +++ b/examples/agent_feature_store/agent.py @@ -0,0 +1,816 @@ +""" +Customer-support AI agent powered by Feast features and memory via MCP. + +The LLM decides which tools to call, when to call them, and what to do +with the results. Feast acts as both the **context provider** (read) and +the **memory store** (write). + +All Feast interactions use the **Model Context Protocol (MCP)**: the agent +connects to the Feast MCP server, discovers available tools dynamically, +and invokes them through the standard protocol -- exactly how production +frameworks like LangChain, LlamaIndex, and CrewAI integrate with MCP +tool servers. + +The agent has three Feast-backed read tools: + + - lookup_customer: Retrieve customer profile features. + - search_knowledge_base: Retrieve support articles. + - recall_memory: Read past interaction context for this customer. + +Memory is automatically saved after every agent turn (framework-style +checkpointing), not as an explicit LLM tool call. This mirrors how +production frameworks like LangGraph, CrewAI, and AutoGen handle +persistence -- as infrastructure, not an LLM decision. + +Memory is entity-keyed (per customer), TTL-managed, versioned, and governed +by the same RBAC as every other feature -- unlike an ad-hoc Redis cache or +an in-process dict. + +Prerequisites: + 1. Run `python setup_data.py` to populate sample data. + 2. Start the Feast server: `cd feature_repo && feast serve --host 0.0.0.0 --port 6566 --workers 1` + 3. Set OPENAI_API_KEY (required for tool-calling). + +Usage: + python agent.py +""" + +import asyncio +import json +import os +import sys +from typing import Any + +import requests + +from mcp import ClientSession +from mcp.client.streamable_http import streamablehttp_client + +FEAST_SERVER = os.getenv("FEAST_SERVER_URL", "http://localhost:6566") +FEAST_MCP_URL = os.getenv("FEAST_MCP_URL", f"{FEAST_SERVER}/mcp") +OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "") +OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1") +LLM_MODEL = os.getenv("LLM_MODEL", "gpt-4o-mini") +MAX_TOOL_ROUNDS = 5 + +# Module-level MCP session (initialised in main) +_mcp_session: ClientSession | None = None +# Maps Feast MCP tool names discovered at startup +_feast_tools: dict[str, str] = {} + + +async def _call_feast_tool(tool_name: str, arguments: dict) -> dict: + """Call a Feast MCP tool and parse the JSON response.""" + assert _mcp_session is not None, "MCP session not initialised" + mcp_tool = _feast_tools.get(tool_name) + if not mcp_tool: + raise ValueError( + f"Feast MCP tool '{tool_name}' not found. " + f"Available: {list(_feast_tools.keys())}" + ) + result = await _mcp_session.call_tool(mcp_tool, arguments) + text = result.content[0].text if result.content else "{}" + return json.loads(text) + + +async def _discover_feast_tools() -> dict[str, str]: + """List MCP tools and build a lookup mapping logical names to MCP names.""" + assert _mcp_session is not None + tools_result = await _mcp_session.list_tools() + tool_map: dict[str, str] = {} + for tool in tools_result.tools: + name = tool.name + if "get_online_features" in name: + tool_map["get_online_features"] = name + elif "retrieve_online_documents" in name: + tool_map["retrieve_online_documents"] = name + elif "write_to_online_store" in name: + tool_map["write_to_online_store"] = name + return tool_map + + +# --------------------------------------------------------------------------- +# Tools: each wraps a Feast MCP call +# --------------------------------------------------------------------------- +# These tool specs are domain-specific wrappers for the customer-support demo. +# With a framework (LangChain, LlamaIndex), you can skip these entirely -- +# the LLM calls Feast's generic MCP tools (get_online_features, etc.) directly. + +TOOLS_SPEC = [ + { + "type": "function", + "function": { + "name": "lookup_customer", + "description": ( + "Look up a customer's profile from the feature store. Returns " + "name, email, plan tier, account age, total spend, open support " + "tickets, and satisfaction score." + ), + "parameters": { + "type": "object", + "properties": { + "customer_id": { + "type": "string", + "description": "The customer ID, e.g. 'C1001'", + } + }, + "required": ["customer_id"], + }, + }, + }, + { + "type": "function", + "function": { + "name": "search_knowledge_base", + "description": ( + "Search the support knowledge base for articles relevant to " + "the user's question. Returns article titles, content, and " + "categories. Use this when you need product documentation or " + "how-to information." + ), + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The search query describing what the user needs help with", + } + }, + "required": ["query"], + }, + }, + }, + { + "type": "function", + "function": { + "name": "recall_memory", + "description": ( + "Recall past interaction context for a customer from the memory " + "store. Returns the last topic discussed, how it was resolved, " + "interaction count, stated preferences, and any open issue. " + "Call this at the start of a conversation to personalise your " + "response based on history." + ), + "parameters": { + "type": "object", + "properties": { + "customer_id": { + "type": "string", + "description": "The customer ID to recall memory for", + } + }, + "required": ["customer_id"], + }, + }, + }, +] + + +def _parse_online_features(data: dict) -> dict[str, Any]: + """Parse the response from get-online-features into a flat dict.""" + results = data.get("results", []) + feature_names = data.get("metadata", {}).get("feature_names", []) + features: dict[str, Any] = {} + for i, name in enumerate(feature_names): + values = results[i].get("values", []) + val = values[0] if values else None + if val is not None: + features[name] = val + return features + + +async def tool_lookup_customer(customer_id: str) -> dict[str, Any]: + """Fetch customer profile features from Feast via MCP.""" + data = await _call_feast_tool( + "get_online_features", + { + "features": [ + "customer_profile:name", + "customer_profile:email", + "customer_profile:plan_tier", + "customer_profile:account_age_days", + "customer_profile:total_spend", + "customer_profile:open_tickets", + "customer_profile:satisfaction_score", + ], + "entities": {"customer_id": [customer_id]}, + }, + ) + return _parse_online_features(data) + + +async def tool_search_knowledge_base(query: str) -> list[dict[str, Any]]: + """Search knowledge-base articles from Feast via MCP.""" + data = await _call_feast_tool( + "retrieve_online_documents", + { + "features": [ + "knowledge_base:title", + "knowledge_base:content", + "knowledge_base:category", + ], + "query_string": query, + "top_k": 3, + "api_version": 2, + }, + ) + results = data.get("results", []) + feature_names = data.get("metadata", {}).get("feature_names", []) + + num_docs = len(results[0]["values"]) if results else 0 + docs = [] + for doc_idx in range(num_docs): + doc = {} + for feat_idx, name in enumerate(feature_names): + doc[name] = results[feat_idx]["values"][doc_idx] + if doc.get("title"): + docs.append(doc) + return docs + + +async def tool_recall_memory(customer_id: str) -> dict[str, Any]: + """Read the agent's memory for a customer from Feast via MCP.""" + data = await _call_feast_tool( + "get_online_features", + { + "features": [ + "agent_memory:last_topic", + "agent_memory:last_resolution", + "agent_memory:interaction_count", + "agent_memory:preferences", + "agent_memory:open_issue", + ], + "entities": {"customer_id": [customer_id]}, + }, + ) + memory = _parse_online_features(data) + has_memory = any(v is not None for k, v in memory.items() if k != "customer_id") + if not has_memory: + return {"status": "no_previous_interactions", "customer_id": customer_id} + return memory + + +async def tool_save_memory( + customer_id: str, + topic: str, + resolution: str, + open_issue: str = "", + preferences: str = "", +) -> dict[str, str]: + """Write interaction memory back to Feast via MCP.""" + from datetime import datetime, timezone + + existing = await tool_recall_memory(customer_id) + prev_count = existing.get("interaction_count", 0) + prev_preferences = existing.get("preferences", "") + prev_open_issue = existing.get("open_issue", "") + + now = datetime.now(timezone.utc).isoformat() + await _call_feast_tool( + "write_to_online_store", + { + "feature_view_name": "agent_memory", + "df": { + "customer_id": [customer_id], + "last_topic": [topic], + "last_resolution": [resolution], + "interaction_count": [prev_count + 1], + "preferences": [preferences or prev_preferences], + "open_issue": [open_issue or prev_open_issue], + "event_timestamp": [now], + }, + "allow_registry_cache": True, + }, + ) + return {"status": "saved", "customer_id": customer_id, "topic": topic} + + +TOOL_REGISTRY: dict[str, Any] = { + "lookup_customer": lambda args: tool_lookup_customer( + args.get("customer_id") or next(iter(args.values())) + ), + "search_knowledge_base": lambda args: tool_search_knowledge_base( + args.get("query") or args.get("search_query") or next(iter(args.values())) + ), + "recall_memory": lambda args: tool_recall_memory( + args.get("customer_id") or next(iter(args.values())) + ), +} + + +# --------------------------------------------------------------------------- +# Agent loop +# --------------------------------------------------------------------------- + +# Demo-specific prompt: replace with your own domain instructions and tool +# names when adapting this example to a different use case. +SYSTEM_PROMPT = """\ +You are a customer-support agent. You MUST follow these steps in order: + +1. ALWAYS call BOTH recall_memory AND lookup_customer in your first round. + Call them together in the same round. You MUST call lookup_customer even if + recall_memory returns no history -- you need the customer's name and plan. +2. If the question is about a product feature (SSO, API, invoices, passwords, + upgrades, etc.), also call search_knowledge_base with a short keyword. +3. Once you have the tool results, write a helpful, personalised answer. + Use the customer's name and plan tier. Enterprise customers get full access; + starter/pro customers may need to upgrade for certain features. + +Memory is saved automatically -- do NOT try to save it yourself. + +Rules: +- Never call the same tool twice with the same arguments. +- After you have tool results, WRITE your answer immediately. Do not call more tools. +""" + + +def _call_llm(messages: list, use_tools: bool = True) -> dict: + """Make a single LLM API call, returning the parsed choice dict.""" + url = f"{OPENAI_BASE_URL}/chat/completions" + payload: dict[str, Any] = { + "model": LLM_MODEL, + "messages": messages, + "temperature": 0.3, + } + if use_tools: + payload["tools"] = TOOLS_SPEC + resp = requests.post( + url, + headers={ + "Authorization": f"Bearer {OPENAI_API_KEY}", + "Content-Type": "application/json", + }, + json=payload, + ) + if not resp.ok: + print(f"\n ERROR {resp.status_code} from {url}") + print(f" Response: {resp.text[:300]}") + print( + "\n Hint: set OPENAI_BASE_URL to an OpenAI-compatible endpoint.\n" + " Examples:\n" + " OpenAI: export OPENAI_BASE_URL=https://api.openai.com/v1\n" + " Ollama: export OPENAI_BASE_URL=http://localhost:11434/v1\n" + ) + resp.raise_for_status() + return resp.json()["choices"][0] + + +async def run_agent(customer_id: str, user_message: str) -> str: + """ + Agentic loop: the LLM decides which tools to call (if any), executes + them, feeds results back, and repeats until it produces a final answer. + Memory is auto-saved after every turn -- framework-style checkpointing, + not an LLM decision. + """ + if not OPENAI_API_KEY: + response = await _run_agent_demo_mode(customer_id, user_message) + else: + response = await _run_agent_llm(customer_id, user_message) + + await _auto_save_memory(customer_id, user_message, response) + return response + + +async def _auto_save_memory(customer_id: str, user_message: str, response: str) -> None: + """ + Framework-style memory checkpoint: automatically persist interaction + context after every agent turn. + + Production agent frameworks (LangGraph checkpointers, CrewAI memory, + AutoGen teachable agents) all treat memory as infrastructure -- the + framework saves state after each step, rather than relying on the LLM + to decide when to persist. This ensures consistent, reliable memory + regardless of LLM behaviour. + """ + topic = _extract_topic(user_message) + resolution = response[:120] if response else "Answered query" + try: + await tool_save_memory( + customer_id=customer_id, + topic=topic, + resolution=resolution, + ) + print(f' [Checkpoint] Memory saved: topic="{topic}"') + except Exception as e: + print(f" [Checkpoint] Failed to save memory: {e}") + + +async def _run_agent_llm(customer_id: str, user_message: str) -> str: + """Core LLM agent loop. Returns the response text.""" + messages = [ + {"role": "system", "content": SYSTEM_PROMPT}, + { + "role": "user", + "content": f"[Customer ID: {customer_id}]\n\n{user_message}", + }, + ] + + seen_calls: set[str] = set() + collected_context: dict[str, Any] = {} + + for round_num in range(1, MAX_TOOL_ROUNDS + 1): + choice = _call_llm(messages) + assistant_msg = choice["message"] + messages.append(assistant_msg) + + content = assistant_msg.get("content") or "" + if choice["finish_reason"] == "stop": + if content: + print(f" ✓ Agent finished after {round_num} round(s)") + return content + break # empty stop -- fall through to forced response + + tool_calls = assistant_msg.get("tool_calls", []) + if not tool_calls: + if content: + return content + break + + tool_names = [tc["function"]["name"] for tc in tool_calls] + print(f" 🔧 Round {round_num}: LLM chose tool(s): {', '.join(tool_names)}") + + for tc in tool_calls: + fn_name = tc["function"]["name"] + fn_args = json.loads(tc["function"]["arguments"]) + call_key = f"{fn_name}:{json.dumps(fn_args, sort_keys=True)}" + + if call_key in seen_calls: + print(f" [Round {round_num}] Skipping duplicate: {fn_name}({fn_args})") + messages.append( + { + "role": "tool", + "tool_call_id": tc["id"], + "content": json.dumps( + { + "note": "Already called. Use the results you have and respond." + } + ), + } + ) + continue + + seen_calls.add(call_key) + print(f" [Round {round_num}] ➜ {fn_name}({fn_args})") + + handler = TOOL_REGISTRY.get(fn_name) + if handler: + result = await handler(fn_args) + result_str = json.dumps(result, default=str) + collected_context[fn_name] = result + else: + result_str = json.dumps({"error": f"Unknown tool: {fn_name}"}) + + messages.append( + { + "role": "tool", + "tool_call_id": tc["id"], + "content": result_str, + } + ) + + # If the LLM never produced a response, force one last call without tools + print(" ⏳ Forcing final response...") + messages.append( + { + "role": "user", + "content": "You have all the information. Write your answer to the customer now.", + } + ) + choice = _call_llm(messages, use_tools=False) + content = choice["message"].get("content") or "" + if content: + return content + + # Last resort: build a response from collected tool results + return _fallback_response(collected_context, customer_id, user_message) + + +def _fallback_response(context: dict, customer_id: str, user_message: str) -> str: + """Build a basic response from collected tool results when the LLM fails.""" + profile = context.get("lookup_customer", {}) + name = profile.get("name", customer_id) + plan = profile.get("plan_tier", "your") + memory = context.get("recall_memory", {}) + + parts = [] + if memory and memory.get("last_topic"): + parts.append( + f'Welcome back, {name}! I see we last discussed "{memory["last_topic"]}".' + ) + else: + parts.append(f"Hi {name}!") + + parts.append( + f"You're on the {plan} plan. I've noted your question about " + f'"{user_message[:50]}" and will follow up.' + ) + return " ".join(parts) + + +async def _run_agent_demo_mode(customer_id: str, user_message: str) -> str: + """ + Demo mode: simulates the agentic tool-calling flow and generates a + personalised response that shows how Feast context shapes the answer. + """ + print(" [Demo mode] Simulating agent reasoning\n") + + # ── Round 1: recall memory ────────────────────────────────────────── + print(f" Round 1 | recall_memory(customer_id={customer_id})") + memory = await tool_recall_memory(customer_id) + has_memory = memory.get("status") != "no_previous_interactions" + if has_memory: + print(f" -> Previous topic: {memory.get('last_topic')}") + print(f" -> Open issue: {memory.get('open_issue') or 'none'}") + print(f" -> Interaction count: {memory.get('interaction_count')}") + else: + print(" -> No prior interactions found") + + # ── Round 1: lookup customer ──────────────────────────────────────── + print(f"\n Round 1 | lookup_customer(customer_id={customer_id})") + profile = await tool_lookup_customer(customer_id) + name = profile.get("name", "Customer") + plan = profile.get("plan_tier", "unknown") + spend = profile.get("total_spend", 0) + tickets = profile.get("open_tickets", 0) + print( + f" -> {name} | {plan} plan | ${spend:,.0f} spend | {tickets} open tickets" + ) + + # ── Round 1: search knowledge base (if question needs docs) ───────── + needs_kb = any( + kw in user_message.lower() + for kw in [ + "how", + "what", + "set up", + "configure", + "reset", + "help", + "sso", + "api", + "invoice", + "upgrade", + "password", + ] + ) + kb_article = None + if needs_kb: + print(f'\n Round 1 | search_knowledge_base(query="{user_message[:50]}...")') + docs = await tool_search_knowledge_base(user_message) + if docs: + kb_article = _pick_best_article(user_message, docs) + print(f' -> Best match: "{kb_article.get("title")}"') + + # ── Round 2: generate response (simulated LLM reasoning) ──────────── + print("\n Round 2 | Generating personalised response...") + response = _build_demo_response( + name=name, + plan=plan, + profile=profile, + memory=memory if has_memory else None, + kb_article=kb_article, + user_message=user_message, + ) + + return response + + +def _pick_best_article(query: str, docs: list) -> dict: + """Simple keyword matching to select the most relevant article.""" + query_lower = query.lower() + keywords_to_category = { + "sso": "Configuring single sign-on", + "single sign": "Configuring single sign-on", + "password": "How to reset your password", # pragma: allowlist secret + "reset": "How to reset your password", + "invoice": "Understanding your invoice", + "billing": "Understanding your invoice", + "upgrade": "Upgrading your subscription", + "plan": "Upgrading your subscription", + "api": "Setting up API access", + "rate limit": "Setting up API access", + "support": "Contacting support", + "contact": "Contacting support", + } + for keyword, title_prefix in keywords_to_category.items(): + if keyword in query_lower: + for doc in docs: + if doc.get("title", "").startswith(title_prefix): + return doc + return docs[0] + + +def _extract_topic(message: str) -> str: + """Extract a short topic label from the user message.""" + topic_map = { + "sso": "SSO setup", + "invoice": "Invoice help", + "upgrade": "Plan upgrade", + "api": "API access", + "password": "Password reset", # pragma: allowlist secret + "reset": "Password reset", + } + lower = message.lower() + for keyword, topic in topic_map.items(): + if keyword in lower: + return topic + return message[:40] + + +def _build_demo_response( + name: str, + plan: str, + profile: dict, + memory: dict | None, + kb_article: dict | None, + user_message: str, +) -> str: + """Build a realistic personalised response based on Feast context.""" + parts = [] + + # Acknowledge returning customer if we have memory + if memory and memory.get("last_topic"): + parts.append( + f"Welcome back, {name}! I can see from our records that we last " + f'discussed "{memory["last_topic"]}".' + ) + if memory.get("open_issue"): + parts.append( + f"I also notice you have an open issue: {memory['open_issue']}. " + "Let me know if you'd like to follow up on that." + ) + else: + parts.append(f"Hi {name}!") + + # Role-based response logic + lower = user_message.lower() + + if "sso" in lower: + if plan == "enterprise": + parts.append( + "Since you're on our Enterprise plan, SSO is available for your " + "team. Go to Settings > Security > SSO and enter your Identity " + "Provider metadata URL. We support SAML 2.0 and OIDC. Once " + "configured, all team members will authenticate through your IdP." + ) + parts.append( + "As an Enterprise customer, you also have a dedicated Slack " + "channel and account manager if you need hands-on help." + ) + elif plan == "pro": + parts.append( + "SSO is only available on our Enterprise plan. You're currently " + "on the Pro plan. Would you like to learn about upgrading? The " + "Enterprise plan includes SSO, priority support, and a dedicated " + "account manager." + ) + else: + parts.append( + "SSO is an Enterprise-only feature. You're currently on the " + f"Starter plan (${profile.get('total_spend', 0):,.0f} total spend). " + "You'd need to upgrade to Enterprise to access SSO. I can walk " + "you through the upgrade options if you're interested." + ) + + elif "invoice" in lower: + parts.append( + "Invoices are generated on the first of each month and sent to " + f"{profile.get('email', 'your billing email')}." + ) + if plan == "enterprise": + parts.append( + "As an Enterprise customer, your invoice includes base plan " + "charges, any overage fees, and applied credits. You can also " + "reach your dedicated account manager for a detailed breakdown." + ) + else: + parts.append( + "You can download past invoices from Billing > Invoices. Each " + "invoice shows base charges and any overages." + ) + if profile.get("open_tickets", 0) > 0: + parts.append( + f"I also see you have {profile['open_tickets']} open support " + "ticket(s) -- let me know if any are billing-related." + ) + + elif "upgrade" in lower or "api" in lower: + if plan == "starter": + parts.append( + "Great question! You're on the Starter plan. Upgrading to Pro " + "gives you API access with 1,000 requests/minute. Enterprise " + "gets you 5,000 req/min plus priority support. The price " + "difference is prorated for your current billing cycle." + ) + elif plan == "pro": + parts.append( + "You're on the Pro plan with 1,000 API requests/minute. " + "Upgrading to Enterprise would give you 5,000 req/min, SSO, " + f"and a dedicated account manager. Given your ${profile.get('total_spend', 0):,.0f} " + "total spend, I can check if there are any loyalty discounts available." + ) + else: + parts.append( + "You're already on our Enterprise plan with the highest rate " + "limits (5,000 req/min). If you need even higher throughput, " + "I can connect you with your account manager to discuss custom limits." + ) + + elif memory and memory.get("last_topic"): + parts.append( + f"Yes, I have the full context from our previous conversation about " + f'"{memory["last_topic"]}". ' + f"We've now had {memory.get('interaction_count', 1)} interaction(s). " + "How can I help you today?" + ) + + else: + parts.append("How can I help you today?") + + return "\n".join(parts) + + +# --------------------------------------------------------------------------- +# Demo queries +# --------------------------------------------------------------------------- + +DEMO_QUERIES = [ + # Scene 1: Enterprise customer asks about SSO -- should get full access instructions + ("C1001", "How do I set up SSO for my team?"), + # Scene 2: Starter customer asks the SAME question -- should be told it's Enterprise-only + ("C1003", "How do I set up SSO for my team?"), + # Scene 3: Pro customer asks about invoices -- response uses their email/ticket context + ("C1002", "I need help understanding my last invoice."), + # Scene 4: C1001 returns -- agent should recall the SSO conversation from Scene 1 + ("C1001", "I'm back about my SSO question from earlier."), +] + + +async def main(): + global _mcp_session, _feast_tools + + print("=" * 65) + print(" Feast-Powered AI Agent Demo: Context + Memory via MCP") + print("=" * 65) + print() + print(" This demo shows two key capabilities:") + print(" 1. ROLE-BASED RESPONSES: Same question, different answer per plan tier") + print(" 2. PERSISTENT MEMORY: Agent recalls prior conversations via Feast") + print() + print(" Tools: recall_memory | lookup_customer | search_knowledge_base") + print(" Memory: auto-saved after each turn (framework-style checkpoint)") + print(f" Protocol: MCP ({FEAST_MCP_URL})") + print() + + try: + resp = requests.get(f"{FEAST_SERVER}/health") + resp.raise_for_status() + print(f"Feast server: healthy at {FEAST_SERVER}") + except (requests.ConnectionError, requests.HTTPError) as exc: + print(f"ERROR: Cannot reach Feast server at {FEAST_SERVER} ({exc})") + print( + "Start it with: cd feature_repo && feast serve --host 0.0.0.0 --port 6566 --workers 1" + ) + sys.exit(1) + + async with streamablehttp_client(FEAST_MCP_URL) as (read_stream, write_stream, _): + async with ClientSession(read_stream, write_stream) as session: + _mcp_session = session + await session.initialize() + + _feast_tools = await _discover_feast_tools() + print(f"MCP tools discovered: {', '.join(_feast_tools.values())}") + + if not OPENAI_API_KEY: + print( + "OPENAI_API_KEY not set -- running in demo mode (simulated reasoning)\n" + ) + else: + print(f"Using LLM: {LLM_MODEL} via {OPENAI_BASE_URL}\n") + + scene_labels = [ + "Scene 1: Enterprise customer (C1001) asks about SSO", + "Scene 2: Starter customer (C1003) asks the SAME SSO question", + "Scene 3: Pro customer (C1002) asks about invoices", + "Scene 4: C1001 returns -- does the agent remember Scene 1?", + ] + + for i, (customer_id, query) in enumerate(DEMO_QUERIES): + label = scene_labels[i] if i < len(scene_labels) else "" + print(f"\n{'=' * 65}") + print(f" {label}") + print(f' Customer: {customer_id} | Query: "{query}"') + print(f"{'=' * 65}") + + response = await run_agent(customer_id, query) + + print(f"\n {'─' * 61}") + print(" Agent Response:") + print(f" {'─' * 61}") + for line in response.split("\n"): + print(f" {line}") + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/agent_feature_store/feature_repo/feature_store.yaml b/examples/agent_feature_store/feature_repo/feature_store.yaml new file mode 100644 index 00000000000..7cc89d536c8 --- /dev/null +++ b/examples/agent_feature_store/feature_repo/feature_store.yaml @@ -0,0 +1,30 @@ +project: feast_agent +provider: local +registry: data/registry.db + +online_store: + type: milvus + path: data/online_store.db + vector_enabled: true + embedding_dim: 384 + index_type: "IVF_FLAT" + metric_type: "COSINE" + nlist: 128 + +offline_store: + type: file + +entity_key_serialization_version: 3 + +feature_server: + type: mcp + enabled: true + mcp_enabled: true + mcp_transport: http + mcp_server_name: "feast-agent-demo" + mcp_server_version: "1.0.0" + feature_logging: + enabled: false + +auth: + type: no_auth diff --git a/examples/agent_feature_store/feature_repo/features.py b/examples/agent_feature_store/feature_repo/features.py new file mode 100644 index 00000000000..935b9cb03c0 --- /dev/null +++ b/examples/agent_feature_store/feature_repo/features.py @@ -0,0 +1,83 @@ +from datetime import timedelta + +from feast import Entity, FeatureView, Field, FileSource +from feast.data_format import ParquetFormat +from feast.types import Array, Float32, Float64, Int64, String, ValueType + +customer = Entity( + name="customer_id", + description="Unique customer identifier", + value_type=ValueType.STRING, +) + +document = Entity( + name="doc_id", + description="Knowledge-base document chunk identifier", + value_type=ValueType.INT64, +) + +customer_profile_source = FileSource( + file_format=ParquetFormat(), + path="data/customer_profiles.parquet", + timestamp_field="event_timestamp", +) + +knowledge_base_source = FileSource( + file_format=ParquetFormat(), + path="data/knowledge_base.parquet", + timestamp_field="event_timestamp", +) + +agent_memory_source = FileSource( + file_format=ParquetFormat(), + path="data/agent_memory.parquet", + timestamp_field="event_timestamp", +) + +customer_profile = FeatureView( + name="customer_profile", + entities=[customer], + schema=[ + Field(name="name", dtype=String), + Field(name="email", dtype=String), + Field(name="plan_tier", dtype=String), + Field(name="account_age_days", dtype=Int64), + Field(name="total_spend", dtype=Float64), + Field(name="open_tickets", dtype=Int64), + Field(name="satisfaction_score", dtype=Float64), + ], + source=customer_profile_source, + ttl=timedelta(days=1), +) + +knowledge_base = FeatureView( + name="knowledge_base", + entities=[document], + schema=[ + Field( + name="vector", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="title", dtype=String), + Field(name="content", dtype=String), + Field(name="category", dtype=String), + ], + source=knowledge_base_source, + ttl=timedelta(days=7), +) + +agent_memory = FeatureView( + name="agent_memory", + entities=[customer], + schema=[ + Field(name="last_topic", dtype=String), + Field(name="last_resolution", dtype=String), + Field(name="interaction_count", dtype=Int64), + Field(name="preferences", dtype=String), + Field(name="open_issue", dtype=String), + ], + source=agent_memory_source, + ttl=timedelta(days=30), +) diff --git a/examples/agent_feature_store/run_demo.sh b/examples/agent_feature_store/run_demo.sh new file mode 100755 index 00000000000..487ed4a7c6e --- /dev/null +++ b/examples/agent_feature_store/run_demo.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# +# One-command setup and demo for the Feast-powered AI agent example. +# +# Usage: +# cd examples/agent_feature_store +# ./run_demo.sh # demo mode (no API key needed) +# OPENAI_API_KEY=sk-... ./run_demo.sh # live LLM tool-calling +# + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +PYTHON="${PYTHON:-$(command -v python3 || command -v python || true)}" +if [[ -z "$PYTHON" ]]; then + echo "ERROR: python3 or python not found on PATH." + exit 1 +fi +PIP="${PIP:-$(command -v pip3 || command -v pip || true)}" +if [[ -z "$PIP" ]]; then + echo "ERROR: pip3 or pip not found on PATH." + exit 1 +fi + +SERVER_PORT=6566 +SERVER_PID="" + +cleanup() { + if [[ -n "$SERVER_PID" ]]; then + echo "" + echo "Stopping Feast server (pid $SERVER_PID)..." + kill "$SERVER_PID" 2>/dev/null || true + wait "$SERVER_PID" 2>/dev/null || true + fi +} +trap cleanup EXIT + +# ── 1. Install dependencies ───────────────────────────────────────────────── +echo "==> Step 1/4: Installing dependencies..." +$PIP install -q "feast[mcp,milvus]" + +# ── 2. Generate data and apply registry ────────────────────────────────────── +echo "" +echo "==> Step 2/4: Generating sample data and applying Feast registry..." +$PYTHON setup_data.py + +# ── 3. Start the Feast MCP server in the background ───────────────────────── +echo "" +echo "==> Step 3/4: Starting Feast MCP feature server on port $SERVER_PORT..." +cd feature_repo +feast serve --host 0.0.0.0 --port "$SERVER_PORT" --workers 1 & +SERVER_PID=$! +cd "$SCRIPT_DIR" + +echo " Waiting for server to become healthy..." +for i in $(seq 1 30); do + if curl -sf "http://localhost:${SERVER_PORT}/health" > /dev/null 2>&1; then + echo " Server is ready." + break + fi + if ! kill -0 "$SERVER_PID" 2>/dev/null; then + echo "ERROR: Server process exited unexpectedly." + exit 1 + fi + sleep 1 +done + +if ! curl -sf "http://localhost:${SERVER_PORT}/health" > /dev/null 2>&1; then + echo "ERROR: Server did not become healthy within 30 seconds." + exit 1 +fi + +# ── 4. Run the agent ──────────────────────────────────────────────────────── +echo "" +echo "==> Step 4/4: Running the agent..." +echo "" +$PYTHON agent.py + +echo "" +echo "Demo complete." diff --git a/examples/agent_feature_store/setup_data.py b/examples/agent_feature_store/setup_data.py new file mode 100644 index 00000000000..cd88e008af4 --- /dev/null +++ b/examples/agent_feature_store/setup_data.py @@ -0,0 +1,201 @@ +""" +Generates sample data, applies the Feast registry, and materializes features +into the online store so the agent demo is ready to run. + +Usage: + cd examples/agent_feature_store + python setup_data.py +""" + +import os +import sys + +import numpy as np +import pandas as pd + +REPO_DIR = os.path.join(os.path.dirname(__file__), "feature_repo") +DATA_DIR = os.path.join(REPO_DIR, "data") +os.makedirs(DATA_DIR, exist_ok=True) + +EMBEDDING_DIM = 384 +NOW = pd.Timestamp.now() + + +def generate_customer_profiles() -> pd.DataFrame: + customers = [ + { + "customer_id": "C1001", + "name": "Alice Johnson", + "email": "alice@example.com", + "plan_tier": "enterprise", + "account_age_days": 730, + "total_spend": 24500.00, + "open_tickets": 1, + "satisfaction_score": 4.5, + }, + { + "customer_id": "C1002", + "name": "Bob Smith", + "email": "bob@example.com", + "plan_tier": "pro", + "account_age_days": 365, + "total_spend": 8400.00, + "open_tickets": 3, + "satisfaction_score": 3.2, + }, + { + "customer_id": "C1003", + "name": "Carol Lee", + "email": "carol@example.com", + "plan_tier": "starter", + "account_age_days": 90, + "total_spend": 990.00, + "open_tickets": 0, + "satisfaction_score": 4.8, + }, + ] + df = pd.DataFrame(customers) + df["event_timestamp"] = NOW + return df + + +def generate_knowledge_base() -> pd.DataFrame: + articles = [ + { + "doc_id": 1, + "title": "How to reset your password", + "content": ( + "To reset your password, go to Settings > Security > Reset Password. " + "Enter your current password, then choose a new one that is at least " + "12 characters long. Click Save. If you forgot your current password, " + "click 'Forgot Password' on the login page to receive a reset link " + "via email." + ), + "category": "account", + }, + { + "doc_id": 2, + "title": "Upgrading your subscription plan", + "content": ( + "You can upgrade your plan from Starter to Pro or Enterprise at any " + "time. Navigate to Billing > Plans and select the plan you want. " + "The price difference is prorated for the current billing cycle. " + "Enterprise plans include priority support, custom integrations, " + "and a dedicated account manager." + ), + "category": "billing", + }, + { + "doc_id": 3, + "title": "Setting up API access", + "content": ( + "To generate an API key, go to Settings > Developer > API Keys and " + "click 'Create New Key'. Choose the appropriate scopes for your use " + "case. API keys are tied to your account and inherit your permissions. " + "Rate limits are 1000 requests/minute for Pro and 5000 for Enterprise." + ), + "category": "developer", + }, + { + "doc_id": 4, + "title": "Understanding your invoice", + "content": ( + "Invoices are generated on the first of each month and sent to the " + "billing email on file. Each invoice includes a breakdown of base plan " + "charges, overage fees, and any credits applied. You can download past " + "invoices from Billing > Invoices." + ), + "category": "billing", + }, + { + "doc_id": 5, + "title": "Configuring single sign-on (SSO)", + "content": ( + "SSO is available on Enterprise plans. To configure SSO, go to " + "Settings > Security > SSO and provide your Identity Provider (IdP) " + "metadata URL. We support SAML 2.0 and OIDC. Once configured, all " + "team members will authenticate through your IdP." + ), + "category": "account", + }, + { + "doc_id": 6, + "title": "Contacting support", + "content": ( + "You can reach our support team via the in-app chat widget, by " + "emailing support@example.com, or by opening a ticket at " + "https://support.example.com. Enterprise customers have access to " + "a dedicated Slack channel and a named account manager with a " + "guaranteed 1-hour response time." + ), + "category": "support", + }, + ] + + np.random.seed(42) + df = pd.DataFrame(articles) + df["vector"] = [ + np.random.randn(EMBEDDING_DIM).astype(np.float32).tolist() + for _ in range(len(df)) + ] + df["event_timestamp"] = NOW + return df + + +def main(): + print("Generating customer profile data...") + customers_df = generate_customer_profiles() + customers_path = os.path.join(DATA_DIR, "customer_profiles.parquet") + customers_df.to_parquet(customers_path, index=False) + print(f" Saved {len(customers_df)} customer profiles to {customers_path}") + + print("Generating knowledge-base data...") + kb_df = generate_knowledge_base() + kb_path = os.path.join(DATA_DIR, "knowledge_base.parquet") + kb_df.to_parquet(kb_path, index=False) + print(f" Saved {len(kb_df)} knowledge-base articles to {kb_path}") + + print("Generating empty agent memory scaffold...") + memory_df = pd.DataFrame( + { + "customer_id": pd.Series(dtype="str"), + "last_topic": pd.Series(dtype="str"), + "last_resolution": pd.Series(dtype="str"), + "interaction_count": pd.Series(dtype="int64"), + "preferences": pd.Series(dtype="str"), + "open_issue": pd.Series(dtype="str"), + "event_timestamp": pd.Series(dtype="datetime64[ns]"), + } + ) + memory_path = os.path.join(DATA_DIR, "agent_memory.parquet") + memory_df.to_parquet(memory_path, index=False) + print(f" Saved empty memory scaffold to {memory_path}") + + print("Applying Feast registry...") + sys.path.insert(0, REPO_DIR) + from feast import FeatureStore + from features import ( + agent_memory, + customer, + customer_profile, + document, + knowledge_base, + ) + + store = FeatureStore(repo_path=REPO_DIR) + store.apply([customer, document, customer_profile, knowledge_base, agent_memory]) + + print("Materializing customer profiles to the online store...") + store.write_to_online_store(feature_view_name="customer_profile", df=customers_df) + print(" Done.") + + print("Materializing knowledge-base to the online store...") + store.write_to_online_store(feature_view_name="knowledge_base", df=kb_df) + print(" Done.") + + print("\nSetup complete! Start the feature server with:") + print(" cd feature_repo && feast serve --host 0.0.0.0 --port 6566") + + +if __name__ == "__main__": + main() diff --git a/examples/mcp_feature_store/feature_store.yaml b/examples/mcp_feature_store/feature_store.yaml index 305be159956..82029eb111f 100644 --- a/examples/mcp_feature_store/feature_store.yaml +++ b/examples/mcp_feature_store/feature_store.yaml @@ -14,9 +14,10 @@ feature_server: type: mcp enabled: true mcp_enabled: true # Enable MCP support - defaults to false + mcp_transport: http mcp_server_name: "feast-feature-store" mcp_server_version: "1.0.0" feature_logging: enabled: false -entity_key_serialization_version: 3 \ No newline at end of file +entity_key_serialization_version: 3 diff --git a/examples/monitoring/monitoring-quickstart.ipynb b/examples/monitoring/monitoring-quickstart.ipynb new file mode 100644 index 00000000000..77101ffff51 --- /dev/null +++ b/examples/monitoring/monitoring-quickstart.ipynb @@ -0,0 +1,1256 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Feature Quality Monitoring — Quickstart\n", + "\n", + "This notebook walks you through Feast's data quality monitoring end-to-end:\n", + "\n", + "1. Set up a feature store with a PostgreSQL offline store\n", + "2. Register features and trigger baseline computation\n", + "3. Compute metrics across multiple granularities\n", + "4. Read metrics via the Python SDK and REST API\n", + "5. Set up serving log monitoring\n", + "6. Use on-demand exploration for custom date ranges\n", + "\n", + "**Prerequisites:** A running PostgreSQL instance and `feast[postgres]` installed." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 1: Install Feast" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "!uv pip install -q 'feast[postgres]'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 2: Configure the Feature Store\n", + "\n", + "Create a minimal `feature_store.yaml` with a PostgreSQL offline store." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Working directory: /var/folders/cn/z7vz24yj25d8fjqdrs9jbsh00000gn/T/feast_monitoring_demo_kze7m3sk\n" + ] + } + ], + "source": [ + "import os\n", + "import tempfile\n", + "\n", + "REPO_DIR = tempfile.mkdtemp(prefix=\"feast_monitoring_demo_\")\n", + "os.makedirs(REPO_DIR, exist_ok=True)\n", + "print(f\"Working directory: {REPO_DIR}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "feature_store.yaml written.\n" + ] + } + ], + "source": [ + "# Adjust these to match your PostgreSQL instance\n", + "PG_HOST = os.environ.get(\"FEAST_PG_HOST\", \"localhost\")\n", + "PG_PORT = os.environ.get(\"FEAST_PG_PORT\", \"5432\")\n", + "PG_DB = os.environ.get(\"FEAST_PG_DB\", \"feast\")\n", + "PG_USER = os.environ.get(\"FEAST_PG_USER\", \"feast\")\n", + "PG_PASS = os.environ.get(\"FEAST_PG_PASS\", \"feast\")\n", + "\n", + "PG_SSLMODE = os.environ.get(\"FEAST_PG_SSLMODE\", \"disable\")\n", + "\n", + "feature_store_yaml = f\"\"\"\n", + "project: monitoring_demo\n", + "registry:\n", + " registry_type: sql\n", + " path: postgresql://{PG_USER}:{PG_PASS}@{PG_HOST}:{PG_PORT}/{PG_DB}?sslmode={PG_SSLMODE}\n", + "provider: local\n", + "offline_store:\n", + " type: postgres\n", + " host: {PG_HOST}\n", + " port: {PG_PORT}\n", + " database: {PG_DB}\n", + " user: {PG_USER}\n", + " password: {PG_PASS}\n", + " sslmode: {PG_SSLMODE}\n", + "online_store:\n", + " type: sqlite\n", + " path: {REPO_DIR}/online_store.db\n", + "entity_key_serialization_version: 3\n", + "\"\"\"\n", + "\n", + "with open(os.path.join(REPO_DIR, \"feature_store.yaml\"), \"w\") as f:\n", + " f.write(feature_store_yaml)\n", + "\n", + "print(\"feature_store.yaml written.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Create Sample Data and Feature Definitions" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sample data: 5000 rows, 60 days\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
driver_idevent_timestampconv_rateacc_rateavg_daily_tripsvehicle_typecreated
011482025-02-080.3483070.79439014compact2025-02-08
115392025-02-210.3059450.74904625van2025-02-21
214872025-01-290.7916410.78449217sedan2025-01-29
318212025-01-150.2673080.72622617sedan2025-01-15
414372025-02-120.5446180.72956811suv2025-02-12
\n", + "
" + ], + "text/plain": [ + " driver_id event_timestamp conv_rate acc_rate avg_daily_trips \\\n", + "0 1148 2025-02-08 0.348307 0.794390 14 \n", + "1 1539 2025-02-21 0.305945 0.749046 25 \n", + "2 1487 2025-01-29 0.791641 0.784492 17 \n", + "3 1821 2025-01-15 0.267308 0.726226 17 \n", + "4 1437 2025-02-12 0.544618 0.729568 11 \n", + "\n", + " vehicle_type created \n", + "0 compact 2025-02-08 \n", + "1 van 2025-02-21 \n", + "2 sedan 2025-01-29 \n", + "3 sedan 2025-01-15 \n", + "4 suv 2025-02-12 " + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from datetime import datetime, timedelta\n", + "\n", + "np.random.seed(42)\n", + "\n", + "N_ROWS = 5000\n", + "N_DAYS = 60\n", + "\n", + "base_date = datetime(2025, 1, 1)\n", + "timestamps = [base_date + timedelta(days=int(d)) for d in np.random.randint(0, N_DAYS, N_ROWS)]\n", + "\n", + "df = pd.DataFrame({\n", + " \"driver_id\": np.random.randint(1000, 2000, N_ROWS),\n", + " \"event_timestamp\": timestamps,\n", + " \"conv_rate\": np.clip(np.random.normal(0.5, 0.2, N_ROWS), 0, 1),\n", + " \"acc_rate\": np.clip(np.random.normal(0.7, 0.15, N_ROWS), 0, 1),\n", + " \"avg_daily_trips\": np.random.poisson(20, N_ROWS).astype(\"int32\"),\n", + " \"vehicle_type\": np.random.choice([\"sedan\", \"suv\", \"truck\", \"van\", \"compact\"], N_ROWS),\n", + " \"created\": timestamps,\n", + "})\n", + "\n", + "print(f\"Sample data: {len(df)} rows, {N_DAYS} days\")\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "!uv pip install -q 'psycopg2'" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded sample data into PostgreSQL table 'driver_stats_source'.\n" + ] + } + ], + "source": [ + "# Load sample data into PostgreSQL'\n", + "from sqlalchemy import create_engine\n", + "\n", + "engine = create_engine(f\"postgresql://{PG_USER}:{PG_PASS}@{PG_HOST}:{PG_PORT}/{PG_DB}\")\n", + "df.to_sql(\"driver_stats_source\", engine, if_exists=\"replace\", index=False)\n", + "print(\"Loaded sample data into PostgreSQL table 'driver_stats_source'.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Feature definitions written.\n" + ] + } + ], + "source": [ + "# Write feature definitions\n", + "definitions = '''\n", + "from datetime import timedelta\n", + "from feast import Entity, FeatureView, FeatureService, Field\n", + "from feast.types import Float32, Int32, String\n", + "from feast.infra.offline_stores.contrib.postgres_offline_store.postgres_source import (\n", + " PostgreSQLSource,\n", + ")\n", + "\n", + "driver = Entity(name=\"driver\", join_keys=[\"driver_id\"])\n", + "\n", + "driver_stats_source = PostgreSQLSource(\n", + " name=\"driver_stats_source\",\n", + " query=\"SELECT * FROM driver_stats_source\",\n", + " timestamp_field=\"event_timestamp\",\n", + " created_timestamp_column=\"created\",\n", + ")\n", + "\n", + "driver_stats_fv = FeatureView(\n", + " name=\"driver_stats\",\n", + " entities=[driver],\n", + " ttl=timedelta(days=365),\n", + " schema=[\n", + " Field(name=\"conv_rate\", dtype=Float32),\n", + " Field(name=\"acc_rate\", dtype=Float32),\n", + " Field(name=\"avg_daily_trips\", dtype=Int32),\n", + " Field(name=\"vehicle_type\", dtype=String),\n", + " ],\n", + " source=driver_stats_source,\n", + ")\n", + "\n", + "driver_service = FeatureService(\n", + " name=\"driver_service\",\n", + " features=[driver_stats_fv],\n", + ")\n", + "'''\n", + "\n", + "with open(os.path.join(REPO_DIR, \"definitions.py\"), \"w\") as f:\n", + " f.write(definitions)\n", + "\n", + "print(\"Feature definitions written.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 4: Apply — Registers Features & Triggers Baseline\n", + "\n", + "Running `feast apply` registers the feature definitions and automatically queues baseline metric computation." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/var/folders/cn/z7vz24yj25d8fjqdrs9jbsh00000gn/T/feast_monitoring_demo_kze7m3sk/definitions.py:9: DeprecationWarning: Entity value_type will be mandatory in the next release. Please specify a value_type for entity 'driver'.\n", + " driver = Entity(name=\"driver\", join_keys=[\"driver_id\"])\n", + "The `path` of the `RegistryConfig` starts with a plain `postgresql` string. We are updating this to `postgresql+psycopg` to ensure that the `psycopg3` driver is used by `sqlalchemy`. If you want to use `psycopg2` pass `postgresql+psycopg2` explicitely to `path`. To silence this warning, pass `postgresql+psycopg` explicitely to `path`.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Features registered. Baseline computation queued.\n" + ] + } + ], + "source": [ + "import sys\n", + "from feast import FeatureStore\n", + "\n", + "sys.path.insert(0, REPO_DIR)\n", + "from definitions import driver, driver_stats_source, driver_stats_fv, driver_service\n", + "\n", + "store = FeatureStore(repo_path=REPO_DIR)\n", + "store.apply([driver, driver_stats_source, driver_stats_fv, driver_service])\n", + "print(\"Features registered. Baseline computation queued.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 5: Compute Batch Metrics\n", + "\n", + "### 5a. Auto-compute (recommended for production)\n", + "\n", + "Auto-compute detects the latest event timestamp and generates metrics for all 5 granularities: `daily`, `weekly`, `biweekly`, `monthly`, and `quarterly`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computed metrics for 20 features\n", + "Granularities: ['biweekly', 'daily', 'monthly', 'quarterly', 'weekly']\n" + ] + } + ], + "source": [ + "from feast.monitoring.monitoring_service import MonitoringService\n", + "\n", + "monitoring = MonitoringService(store)\n", + "\n", + "result = monitoring.auto_compute(\n", + " project=\"monitoring_demo\",\n", + ")\n", + "\n", + "print(f\"Computed metrics for {result.get('computed_features', 'N/A')} features\")\n", + "print(f\"Granularities: {result.get('granularities', [])}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5b. Targeted compute (specific date range)\n", + "\n", + "Compute `weekly` metrics for a specific window." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'status': 'completed', 'granularity': 'weekly', 'computed_features': 4, 'computed_feature_views': 1, 'computed_feature_services': 1, 'metric_dates': ['2025-01-01'], 'duration_ms': 43}\n" + ] + } + ], + "source": [ + "from datetime import date\n", + "\n", + "result = monitoring.compute_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " start_date=date(2025, 1, 1),\n", + " end_date=date(2025, 1, 7),\n", + " granularity=\"weekly\",\n", + ")\n", + "\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5c. Set a manual baseline\n", + "\n", + "Use `set_baseline=True` to mark the computed metrics as the reference distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline set.\n" + ] + } + ], + "source": [ + "result = monitoring.compute_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " start_date=date(2025, 1, 1),\n", + " end_date=date(2025, 2, 28),\n", + " granularity=\"daily\",\n", + " set_baseline=True,\n", + ")\n", + "\n", + "print(\"Baseline set.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 6: Read Metrics\n", + "\n", + "### Per-feature metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Date: 2025-01-01 Mean: 0.4989 Null rate: 0.0000 Rows: 4922\n", + "Date: 2025-02-28 Mean: 0.5201 Null rate: 0.0000 Rows: 104\n" + ] + } + ], + "source": [ + "metrics = monitoring.get_feature_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " feature_name=\"conv_rate\",\n", + " data_source_type=\"batch\",\n", + " granularity=\"daily\",\n", + ")\n", + "\n", + "for m in metrics[:3]:\n", + " print(f\"Date: {m['metric_date']} Mean: {m['mean']:.4f} Null rate: {m['null_rate']:.4f} Rows: {m['row_count']}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Categorical feature metrics\n", + "\n", + "Categorical features (like `vehicle_type`) produce value-count histograms instead of numeric statistics." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Date: 2025-01-01 Type: categorical Rows: 4922 Null rate: 0.0000\n", + " Unique values: 5 Other count: 0\n", + " van: 1051\n", + " suv: 1028\n", + " sedan: 970\n", + " truck: 954\n", + " compact: 919\n", + "Date: 2025-02-28 Type: categorical Rows: 104 Null rate: 0.0000\n", + " Unique values: 5 Other count: 0\n", + " compact: 26\n", + " truck: 24\n", + " sedan: 19\n", + " van: 18\n", + " suv: 17\n" + ] + } + ], + "source": [ + "cat_metrics = monitoring.get_feature_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " feature_name=\"vehicle_type\",\n", + " data_source_type=\"batch\",\n", + " granularity=\"daily\",\n", + ")\n", + "\n", + "for m in cat_metrics[:3]:\n", + " print(f\"Date: {m['metric_date']} Type: {m['feature_type']} \"\n", + " f\"Rows: {m['row_count']} Null rate: {m['null_rate']:.4f}\")\n", + " if m.get(\"histogram\"):\n", + " hist = m[\"histogram\"]\n", + " print(f\" Unique values: {hist['unique_count']} Other count: {hist['other_count']}\")\n", + " for entry in hist[\"values\"]:\n", + " print(f\" {entry['value']}: {entry['count']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAGGCAYAAADmRxfNAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAANlNJREFUeJzt3QmcjeX///HPjDFjmca+G7ufnYTKUrLvhUhSiEqRkqTUD1HiS5SQoujrG/mWolWSXWTJvmdrpiKyjK0sM/f/8bl+//t0zmxmXMOZmfN6Ph7HmPvc576v+77PzFzv+1pOkOM4jgAAAACAhWCbFwMAAACAIlgAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gA8IsPPvhAgoKCZOPGjVdd96677jKP1NLtv/zyy9dYwsxNz4ueH2+lSpWSnj17Xvd9Hz582Oxb3wMu3W94eLjcKLw3ACDtESwA4Bq8/fbbPhXjQPXNN9+k2wp6ei5bWvvss8+kS5cuUqZMGcmRI4dUqFBBnn32WTl9+nSi63/xxRdyyy23SLZs2aREiRIyfPhwuXLlis86S5YskV69esn//M//mG3qth955BE5cuRIgu1p8NewFv/RsmXLFB+DlvWxxx6TAgUKSM6cOaVRo0ayadOmBOv997//lQcffFDKly9v9nEtNx1u5L6AQBLi7wIAwNV89913kh6DRf78+W/IHf4bZe/evRIcHJzqyvuUKVNSVYEvWbKk/PXXX5I1a9ZrKGXalE33HxKSef4EaiW5aNGiphKsQWH79u0yefJkcw60wpw9e3bPugsXLpT27dubSvKkSZPMuq+++qocO3ZMpk6d6lnv+eefl5MnT0rnzp1NxfrgwYNmm1999ZVs2bJFChcu7FOG4sWLy+jRo32WaZlSIi4uTtq0aSNbt26V5557zvxs6c+YlvGnn34y+3dpGXVZnTp15MSJE6k+VzdyX0CgyTy/VQFkWqGhof4uQkAICwu7rtvXO+JaqdPrqXfK/cnf+09r8+bNS3A3vVatWtKjRw+ZPXu2aWlwDRo0SKpXr24CuxuuIiIi5LXXXpOnn35aKlasaJZNmDBBGjRo4BM2tQWiYcOGJmBoGPGWK1cuE2yutfxr1qyRTz75RDp16mSW3Xfffaa1RFtT5syZ41n3P//5jxQrVsyUq2rVqul6X0CgoSsUgBT9IdZuACtWrEjw3Lvvvmue27Fjh2fZnj17zB/svHnzmgpc7dq1TdeLxFy8eFEGDhzo6ZLQoUMHOX78+FXHWPz999/mTrRWBnQfRYoUkY4dO8qBAweSPZbffvvNdO8oVKiQqUhXqVJFZsyYkarzoWMRdu7cac6H2+VDy6d3dPX/b7zxRoLXaEVGn/voo498xjjoudJKjVbs8uXLZyp2emzxffjhh6aiqHee9bzef//9Eh0dnaLyrl692txx1fNUtmxZc82SOi7vFpjLly/LiBEjzB1cfa2WTyuaixcvNs/rutoioLy7v3iPo3j99dflzTffNPvV871r165Ex1i49By2aNHCvBf0bvfIkSPFcRzP88uXLzev1a/e4m8zubK5y+K3ZGzevFlatWplroWO92jSpIn8+OOPiY4N+uGHH676vr2REuuio2VSu3fv9izT868PbeHwbrHp27evOc/6s+668847E7Rg6TJ9/3lvM354PHfuXKrLr/vVn0n9GXbpudWfjc8//9z8nnBFRkamumXNX/sCAg0tFgCuSrsNaEXr448/Nncr4/dB1sq5ezdPK9z169c3d/leeOEFU+nS12nXi08//dRT2XH1799f8uTJY+4UauVQK6FPPvmk2W5SYmNjpW3btqYPuFawtTJ+9uxZU+HVgKOV2MT88ccfcvvtt5uKoe5DKxPaLaR3795y5swZGTBgQIrOh5ZRy63n5KWXXjLLtKKifdD12PUO8TPPPOPzGl120003yT333OOzXCszWqHXLiRaiX3rrbfk1KlTMmvWLM86o0aNkqFDh5p19c6zVmC1C4tW8rQynDt37iTLqt1cmjdvbo5VK9Ja8dNzreW9Gl1fy6X7vPXWW8050sH22rWmWbNm0qdPH/n999/Nedc7u4mZOXOmCUpakdVgoZVSbbVI6rrqHXG9RmPHjpVvv/3W0/dfA0ZqpKRs3vR9e8cdd5hQMXjwYNNNSwOYVtg1QN52223W79sb7ejRo+ardvVx6ftFadj3piFOuzK5zydFQ4M+vLfp2rdvn/l5v3Tpknl/PfroozJs2LAUdXnT/eqYj/iVeH3fTZs2zWy7WrVqkhZu5L6AgOMAQAp07drVKViwoHPlyhXPsiNHjjjBwcHOyJEjPcuaNGniVKtWzfn77789y+Li4px69eo55cuX9yybOXOm3oZ2mjZtap53PfPMM06WLFmc06dPe5Y1bNjQPFwzZswwr50wYUKCcnpvS9cZPny45/vevXs7RYoUcf7880+f19x///1Orly5nAsXLqT4fFSpUsWnTK53333X7Hf37t2eZZcuXXLy58/v9OjRw7NMy6Xr3X333T6v79u3r1m+detW8/3hw4fN+Rg1apTPetu3b3dCQkISLI+vffv2TrZs2ZxffvnFs2zXrl1mm/H/BJQsWdKnjDVq1HDatGmT7Pb79euXYDvq0KFDZnlERIRz7NixRJ/T94BL96vL+vfv73Mtdf+hoaHO8ePHzbJly5aZ9fTr1baZVNkSe2/oedL9HDhwwLPs999/d2666SbnzjvvvKb3rb/p+13LtG/fPs+ycePGmfJHRUUlWL9OnTrO7bffnuw2X3nlFfP6JUuW+Czv1auX8/LLLzuffvqpM2vWLPO+1vXuu+++FJU1Z86cZhvxff3112Y73377bap+DtPLvoBAQ/segBTRGWd0cKd3FxTtUqB3n/U5pQM9ly5dau6sawvCn3/+aR466FG7t/z888+mK5I3vZPt3UVF7xrrnetffvklybJoy4feMdW7xvHFn0LVpXVJfV27du3M/92y6UPLFhMTk+isMKmlx67dhrSFwrVo0SKzn8T6n/fr18/ne/eYdNCtO9uPnmPdrneZdeCsdlFatmxZkmXR86j71tYiHdDrqlSpkjnmq9GWEL2Tr9ftWt17772mtSSl9K6/y21Z0jvg33//vVwvep50vIGeJ211cmn3ugceeMB0JdPWGtv37Y2k4wTef/99MzOU92BkHbSe1Hgafd+6zydm5cqVpmucvhcbN27s85zuS1tvtHvRQw89ZLoUaYuFtlbG706WGN1vUmXyLndauJH7AgINXaEApIh2UdHBmdrVQ/ueK/3/zTffbMY5qP3795tKu3bb0UdiNJxoNymXd4VXafcSpd2BkqLjKHQ6zdTM6qPdh3SKSe3qoI+kymZLK+MaXrRi98orr5hlGjL0mONXxpR3pU9pNy7toqHda5RW6vWcxl/PlVw3Ez1mrSQl9lo9f254SYp2P9KuW3p9taubvge00qgDf1OqdOnSKV5Xj9u7Yq/c95Z7Pq4HPU8XLlww5yQ+DWEa7HQ8i3b5s3nf6rXQAHstdGyN/vylxKpVq0z3Pg2P2o0u/naU9zgCl3ZZ8549ypuOBdJujPo+eO+991JUDg0106dPN6FQu7dpQNSbD940dGbJksXsN6kyeZc7pW7kvgD8g2ABIEX0Dp/e0Z0/f76ZmlHHK+gAVp1JxuX2nddZZ5K6I16uXDmf7/UPfWK8B+ymBbds2mqgM+UkJjUV5uR0797dzDijA7a1r7YOXNfBsSkZBBq/xUXLrct0LEhi5+p6fqicjuHQEKd3n/WOvlYodWD6O++84zPLUHLSupKWVIuUthbcSNfyvtUg/vDDD1/T/vQ9m5LPTdEpVO+++24TALRFMX741lYYpZ9FoQOTvekyHWcQn4YqHaejwUbDqI4VSgl3+24FX38e9PMivB06dMiMMdJyJfb5GO6ylE5b67qR+wLwD4IFgBTTLk///ve/zaBpnRVGK1FuNyjl3m3Wu+hNmza9buXQu/rr1q0zsxal9LMQ9G6lVoi0ApoWZUuqgqv0zr7uT1sqdNCv3g3XO/2J0RYJ77v62uqjYUIrQO6x6nnWddy79ymlZdCKfWJdmfQzK1JCB1trZVgfOmhXw4YO6naDRXLnIbX0uHVWKO/j1IG0yj0fbstA/A9+S6wLUkrLpudJPwAusXOid+o1EMavhF8LDdvujFqplZLKroZAfe8VLFjQBIDEQqe2MCodhO8dInSg+6+//mq6eHnTbowaKvQOv/7cu8EkJfRaKrcrXI0aNRIcv/tZGFoubWnR94B3ANefc702qX3v38h9AfgHwQJAimmFXCuaeudVg4VWTLwrxVqh0Vl0dDYdHSsQvxKiXU5S098+uX77X3/9tZlLP/7sS1oJT6xCqXeY9XXaRUlnjoo/J31qy6az3yT1qcZ6l7hr165mX3qetNUiqdYQnRJVK24une1J6bSnSvusDxkyxPRt1ylnvY9Nj1XvBus0sInRY9bK7IIFCyQqKsrTfUfLpGMvrkYrld7b1oqqtjh5T3Or50HpuUhudqqU0muqM2O5x6ffa3h0u9/ph+vpcWl/f21Bc2krWnwpLZtuT6+Btsxolys3xGirnF5DnWJXZ4uypT8PqamYp3YGKD0GrSjrtU3qvazdufRzKrQ7oM6c5ba86AfB6XvL/VwHdf78eWndurUZF6VjeZLqjqfjT7RF03vcgl4793Mu3NZLDYVJhXrdr7aw6Jgitww6lkhb/rRrYWo/Y+VG7gvAPwgWAFJMK3ha0Z07d66pdOhnFCRWUdaKmFamdfCmtmJoBW3t2rXmjqh21UiLrkY6Hat+jsD69evNwFktj/bl1i5H8ad0dY0ZM8ZUkLQVQctWuXJlUzHXQdv62vh9spOjnymhlTGtPGllW0OV9xgKLaNWkHV///rXv5LcjnbP0K4reqdZz5GGBx0wrHdc3RYL3YeGC630amVaW170ddotTe8wa9ezpGgg0Wlb9RzpudGpWzW8aAVz27ZtyR6jnh8NinqsGij1LrdWyLwHWOtz6qmnnjIVSK2o6hTA10IHz2pZtduPXiPt/qUB8sUXX/RUlLU7jn4StB6DVoT1/OgnQSc2PiY1ZdNzrHe49b2r50nDoQZkvVOvU9+md/r+0RYCnSpXB5vrw6VTv+r0wK5x48aZ95wGET0fGrQ1wGkrlI4pcXXr1s38fOnnvmgY9f7sCg2ZbrDTnx8N0vrQnwUdS6LvTe0qqe9Pndr1arSCr+MwtGVMP2fD/TRsbWHU97A3DZX6cG8I6M++G2K0RU0f6WVfQMDx97RUADKWxYsXmykZg4KCnOjo6ETX0Sk7u3fv7hQuXNjJmjWrU6xYMadt27bOvHnzEkzbuWHDBp/XJjadaPzpZpVODfvSSy85pUuXNvvQfXXq1MlnutD4U4qqP/74w0xDGhkZ6XmdTpE7bdq0VJ2Ho0ePmqlQdTpS3U9i01Dq9JQ6He+vv/6a4Dl3ulmd+lXLrdvJkyeP8+STTzp//fVXgvV1Gs8GDRqYqTL1UbFiRXMce/fuvWpZV6xY4dSqVctMp1qmTBnnnXfe8ew/uelmX331VefWW291cufO7WTPnt3sU6e31elzXTr9sE4RW6BAAfOecLfpTv+q05vGl9R0s3pcev2aN2/u5MiRwylUqJApZ2xsrM/rderZe++916yj56xPnz7Ojh07EmwzqbIl9d7YtGmT06JFCyc8PNxsu1GjRs6aNWt81knN+/ZG0n0n9UjsvTl//nzn5ptvdsLCwpzixYs7//u//+tzXd33Q1Lb1OdcBw8edDp37uyUKlXKTG2s507fb/o+856S92pOnjxppsjNly+f2YaWO/55Vu57N7FH/GuaHvYFBJIg/cff4QYAMqOaNWuaO/3aNz0+Haegd0f1LmhiHzYGAEBGw+dYAMB1oN2GtmzZYrpEAQAQCBhjAQBetAUhualLQ0NDTStEUrS/+k8//STjx483A3W9Z80CACAzI1gAgJc6deok++nJDRs29Pn08fh0cLN+sJx+2NpHH33k+TRfAAAyO8ZYAIAXnclGZ7VJbhpLd7YhAADwD4IFAAAAAGsM3gYAAABgjTEWFuLi4uT33383H1aV2Cf9AgAAABmZdm46e/asFC1aVIKDk2+TIFhY0FARGRnp72IAAAAA11V0dLQUL1482XUIFha0pcI90REREf4uDgAAAJCmzpw5Y26ku/Xe5BAsLLjdnzRUECwAAACQWaWk2z+DtwEAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAIA0Exvn+LsI8JMQf+04M5nw5VY5fsHfpQAAAPCvyPzh8kKHmv4uBvyEYJEGfjtxXqJiYv1dDAAAAMBv6AoFAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWDx/wUFBcmCBQv8XQwAAAAgQyJYAAAAALjxwSIuLk7Gjh0r5cqVk7CwMClRooSMGjXKPLd9+3Zp3LixZM+eXfLlyyePPfaYnDt3zvPanj17Svv27eW1116TQoUKSe7cuWXkyJFy5coVee655yRv3rxSvHhxmTlzpuc1hw8fNq0Jc+fOlXr16km2bNmkatWqsmLFCs86sbGx0rt3byldurTZd4UKFWTixIkJyj5jxgypUqWKKXeRIkXkySefNMtLlSplvnbo0MHsy/0eAAAAwHUKFkOGDJExY8bI0KFDZdeuXTJnzhwTEs6fPy8tWrSQPHnyyIYNG+STTz6R77//3lN5dy1dulR+//13WblypUyYMEGGDx8ubdu2Na9bt26dPP7449KnTx/59ddffV6nwePZZ5+VzZs3S926daVdu3Zy4sQJT9jRQKL71DINGzZMXnzxRfn44489r586dar069fPhB0NQF988YUJR0rLqzTQHDlyxPN9fBcvXpQzZ874PAAAAACIBDmO46R05bNnz0qBAgVk8uTJ8sgjj/g8N336dHn++eclOjpacubMaZZ98803JgBokNDwoS0Wy5cvl4MHD0pw8P9lmooVK0rBggVN0HBbH3LlyiXvvfee3H///abFQlsiNMzo9pW2cOiy/v37y+DBgxMtqwaao0ePyrx588z3xYoVk4cfflheffXVxE9EUJDMnz/ftKgk5eWXX5YRI0YkWP7IxIUSFRObwrMIAACQOZUrHCFTHr3D38VAGtIb6Vo3j4mJkYiIiLRrsdi9e7e5a9+kSZNEn6tRo4YnVKj69eub1oS9e/d6lmlXJDdUKA0c1apV83yfJUsW043q2LFjPtvXVgpXSEiI1K5d2+zTNWXKFKlVq5YJPuHh4TJt2jSJiooyz+m2NNwkVu7UttboSXUfGqIAAAAAiISkZmUdv2Ara9asCVoKElumgSSldPzFoEGDZPz48SaA3HTTTTJu3DjTtSqtyq10bIY+AAAAAFi0WJQvX95U0pcsWZLguUqVKsnWrVvNWAvXDz/8YFondDC1rR9//NHzf+0K9dNPP5l9uvvRgd19+/aVmjVrmrETBw4c8KyvQUMHZCdWbpeGG+2GBQAAAOA6BwudkUnHOei4hlmzZpnKu1b433//fenWrZt5vkePHrJjxw5ZtmyZGQPx0EMPme5OtrSrk46B2LNnjxmEferUKenVq5cn8GzcuFEWLVok+/btMwPL4w/A1vER2qLx1ltvyc8//yybNm2SSZMmeZ53g4eOy9BtAwAAALiOs0JppV1nZ9KZl7TFoEuXLmYMQ44cOUzF/uTJk1KnTh3p1KmTGdOgA73Tgg7e1oeO41i9erWZ1Sl//vzmOZ1FqmPHjqYst912m5ktSlsvvGngefPNN+Xtt9824zx0JioNGC4NHYsXL5bIyEjT6gEAAADgOs0K5Q/urFA6zezNN98s6XGUPLNCAQAAMCtUZnTdZoUCAAAAgMQQLAAAAADc2Olm/UEHVafz3loAAABAwKPFAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACshdhvAsXy5ZTQ7P4uBQAAgH9F5g/3dxHgRwSLNDCwXQ2JiIjwdzEAAAD8LjbOkSzBQf4uBvyArlAAAABIM4SKwEWwAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAA6V5snOPvIuAqQq62Aq5uwpdb5fgFf5cCAAAgc4rMHy4vdKjp72LgKggWaeC3E+clKibW38UAAAAA/IauUAAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIC1gA0Whw8flqCgINmyZYu/iwIAAABkeOkuWNx1110yYMAAfxcDAAAAQEYOFlfjOI5cuXLF38UAAAAAkF6DRc+ePWXFihUyceJE001JHx988IH5unDhQqlVq5aEhYXJ6tWrzbrt27f3eb22dGiLhysuLk7Gjh0r5cqVM68rUaKEjBo1KtF9x8bGSq9evaRixYoSFRV13Y8VAAAAyExCJB3RQLFv3z6pWrWqjBw50izbuXOn+frCCy/I66+/LmXKlJE8efKkaHtDhgyR6dOnyxtvvCENGjSQI0eOyJ49exKsd/HiRenatasZd7Fq1SopUKBAGh8ZAAAAkLmlq2CRK1cuCQ0NlRw5ckjhwoXNMjcIaNBo1qxZird19uxZE1QmT54sPXr0MMvKli1rAoa3c+fOSZs2bUy4WLZsmSlDUnQdfbjOnDmT6mMEAAAAMqN01RUqObVr107V+rt37zYhoEmTJsmupy0V58+fl++++y7ZUKFGjx5t1nEfkZGRqSoTAAAAkFllmGCRM2dOn++Dg4PNQG5vly9f9vw/e/bsKdpu69atZdu2bbJ27doUda2KiYnxPKKjo1NcfgAAACAzS3fBQrtC6UDqq9FxEDpmwpv3Z1KUL1/ehIslS5Yku50nnnhCxowZI3fffbcZOJ4cHQAeERHh8wAAAACQzsZYqFKlSsm6devMQOrw8HAzs1NiGjduLOPGjZNZs2ZJ3bp15cMPP5QdO3ZIzZo1zfPZsmWT559/XgYPHmzCSv369eX48eNmMHjv3r19ttW/f38TZtq2bWtmn4o/DgMAAABABmuxGDRokGTJkkUqV65sWiWSmvq1RYsWMnToUBMc6tSpYwZrd+/e3Wcdff7ZZ5+VYcOGSaVKlaRLly5y7NixRLenU9WOGDHCdI1as2bNdTk2AAAAILMKcuIPVECK6axQOoj7kYkLJSrm6t23AAAAkHrlCkfIlEfv8HcxArq+GxMTc9VhAOmuxQIAAABAxkOwAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYC7HfBIrlyymh2f1dCgAAgMwpMn+4v4uAFCBYpIGB7WpIRESEv4sBAACQacXGOZIlOMjfxUAy6AoFAACAdI9Qkf4RLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAg04iNc/xdhIAV4u8CZAYTvtwqxy/4uxQAAACBLTJ/uLzQoaa/ixGwCBZp4LcT5yUqJtbfxQAAAAD8hq5QAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrmSJYHD58WIKCgmTLli3+LgoAAAAQkDJFsAAAAADgXwQLAAAAABk3WMybN0+qVasm2bNnl3z58knTpk3l/Pnz5rn33ntPKlWqJNmyZZOKFSvK22+/7fPa9evXS82aNc3ztWvXls2bN/s8HxsbK71795bSpUub7VeoUEEmTpzos07Pnj2lffv28vrrr0uRIkVMGfr16yeXL1++AUcPAAAAZC4h/tjpkSNHpGvXrjJ27Fjp0KGDnD17VlatWiWO48js2bNl2LBhMnnyZBMeNDQ8+uijkjNnTunRo4ecO3dO2rZtK82aNZMPP/xQDh06JE8//bTP9uPi4qR48eLyySefmMCwZs0aeeyxx0yAuO+++zzrLVu2zCzTr/v375cuXbrIzTffbPYHAAAAIAMEiytXrkjHjh2lZMmSZpm2Xqjhw4fL+PHjzXNKWx127dol7777rgkWc+bMMcHh/fffNy0WVapUkV9//VWeeOIJz/azZs0qI0aM8Hyv21i7dq18/PHHPsEiT548JsBkyZLFtIy0adNGlixZkmSwuHjxonm4zpw5cx3ODgAAAJDx+CVY1KhRQ5o0aWLCRIsWLaR58+bSqVMnCQ0NlQMHDphuTN6Vew0huXLlMv/fvXu3VK9e3YQKV926dRPsY8qUKTJjxgyJioqSv/76Sy5dumRaI7xpKNFQ4dLWi+3btydZ7tGjR/sEFgAAAAB+HGOhlfnFixfLwoULpXLlyjJp0iQzDmLHjh3m+enTp5upY92HLv/xxx9TvP25c+fKoEGDTED57rvvzDYefvhhEy68acuGN52yVltDkjJkyBCJiYnxPKKjo1N97AAAAEBm5JcWC7cSX79+ffPQMRXaJeqHH36QokWLysGDB6Vbt26Jvk4Hdf/nP/+Rv//+29NqET906Hbq1asnffv29SzTlhBbYWFh5gEAAAAgHQSLdevWmbEM2gWqYMGC5vvjx4+b0KBdjZ566inT9ally5ZmTMPGjRvl1KlTMnDgQHnggQfkpZdeMl2ltAVBPxxPZ3byVr58eZk1a5YsWrTIjK/QILJhwwbzfwAAAACZJFhERETIypUr5c033zQDoLW1Qgdst2rVyjyfI0cOGTdunDz33HNmNigdizFgwADzXHh4uHz55Zfy+OOPm1mjtCvVv/71L7n33ns92+/Tp4+ZTUpnedKWEZ2BSlsvtOsVAAAAgLQX5Ogcr7gmGoq0ZeWRiQslKibW38UBAAAIaOUKR8iUR+/wdzEyZX1Xxxdr40By+ORtAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAayH2m0CxfDklNLu/SwEAABDYIvOH+7sIAY1gkQYGtqshERER/i4GAABAwIuNcyRLcJC/ixGQ6AoFAACATINQ4T8ECwAAAADWCBYAAAAArBEsAAAAAFgjWAAAAACwRrAAAAAAYI1gAQAAAMAawQIAAACANYIFAAAAAGsECwAAAADWCBYAAADAdRQb50ggCPF3ATKDCV9uleMX/F0KAAAApDeR+cPlhQ41JRAQLNLAbyfOS1RMrL+LAQAAAPgNXaEAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALBGsAAAAABgjWABAAAAwBrBAgAAAIA1ggUAAAAAawQLAAAAANYIFgAAAACsESwAAAAAWCNYAAAAALCW4YPFvHnzpFq1apI9e3bJly+fNG3aVM6fPy933XWXDBgwwGfd9u3bS8+ePc3/X3zxRbntttsSbK9GjRoycuTIG1Z+AAAAIDPI0MHiyJEj0rVrV+nVq5fs3r1bli9fLh07dhTHca762m7dusn69evlwIEDnmU7d+6Ubdu2yQMPPJDoay5evChnzpzxeQAAAADIBMHiypUrJkyUKlXKtFz07dtXwsPDr/raKlWqmNaJOXPmeJbNnj3btGKUK1cu0deMHj1acuXK5XlERkam6fEAAAAAGVWGDhYaDJo0aWICRefOnWX69Oly6tSpFL9eWy3cYKGtHB999JFZlpQhQ4ZITEyM5xEdHZ0mxwEAAABkdBk6WGTJkkUWL14sCxculMqVK8ukSZOkQoUKcujQIQkODk7QJery5cs+32s3qr1798qmTZtkzZo1Jih06dIlyf2FhYVJRESEzwMAAABABg8WKigoSOrXry8jRoyQzZs3S2hoqMyfP18KFChgukq5YmNjZceOHT6vLV68uDRs2NB0gdJHs2bNpGDBgn44CgAAACBjC5EMbN26dbJkyRJp3ry5CQT6/fHjx6VSpUqSM2dOGThwoHz99ddStmxZmTBhgpw+fTrBNrTr0/Dhw+XSpUvyxhtv+OU4AAAAgIwuQwcL7Yq0cuVKefPNN80MTSVLlpTx48dLq1atTLenrVu3Svfu3SUkJESeeeYZadSoUYJtdOrUSZ588knTrUqnowUAAACQekFOSuZmRaI0zOjsUI9MXChRMbH+Lg4AAADSmXKFI2TKo3dIRq/v6sRFVxtfnOHHWAAAAADwP4IFAAAAAGsECwAAAADWCBYAAAAArBEsAAAAAFgjWAAAAACwRrAAAAAAYI1gAQAAAMAawQIAAACANYIFAAAAAGsECwAAAADWCBYAAAAArBEsAAAAAFgjWAAAAACwRrAAAAAAYC3EfhMoli+nhGb3dykAAACQ3kTmD5dAQbBIAwPb1ZCIiAh/FwMAAADpUGycI1mCgySzoysUAAAAcB1lCYBQoQgWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAA6VRsnCMZRYi/C5AZTPhyqxy/4O9SAAAAIDOJzB8uL3SoKRkFwSIN/HbivETFxPq7GAAAAIDf0BUKAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAQGAGi2nTpknRokUlLi7OZ/k999wjvXr1kgMHDpj/FypUSMLDw6VOnTry/fff+6xbqlQpee2118z6N910k5QoUcJsFwAAAECABIvOnTvLiRMnZNmyZZ5lJ0+elG+//Va6desm586dk9atW8uSJUtk8+bN0rJlS2nXrp1ERUX5bGf8+PFSu3Zts07fvn3liSeekL179/rhiAAAAICMLUMGizx58kirVq1kzpw5nmXz5s2T/PnzS6NGjaRGjRrSp08fqVq1qpQvX15eeeUVKVu2rHzxxRc+29HwoYGiXLly8vzzz5vXe4eV+C5evChnzpzxeQAAAADIoMFCacvEp59+air7avbs2XL//fdLcHCwabEYNGiQVKpUSXLnzm26Q+3evTtBi0X16tU9/w8KCpLChQvLsWPHktzn6NGjJVeuXJ5HZGTkdTxCAAAAIOPIsMFCuzY5jiNff/21REdHy6pVq0zYUBoq5s+fb8ZQ6PItW7ZItWrV5NKlSz7byJo1q8/3Gi7ij9vwNmTIEImJifE8dL8AAAAAREIkg8qWLZt07NjRtFTs379fKlSoILfccot57ocffpCePXtKhw4dzPfagnH48GHrfYaFhZkHAAAAgEwSLJS2ULRt21Z27twpDz74oGe5jqv47LPPTKuGtkIMHTo02ZYIAAAAAAHaFUo1btxY8ubNa2ZyeuCBBzzLJ0yYYAZ416tXz4SLFi1aeFozAAAAAKS9DN1ioQO1f//99wTL9TMqli5d6rOsX79+Pt8n1jVKx2IAAAAACLAWCwAAAADpA8ECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGAtxH4TKJYvp4Rm93cpAAAAkJlE5g+XjIRgkQYGtqshERER/i4GAAAAMpnYOEeyBAdJRkBXKAAAACCdypJBQoUiWAAAAACwRrAAAAAAYI1gAQAAAMAawQIAAACANYIFAAAAAGsECwAAAADWCBYAAAAArBEsAAAAAFgjWAAAAACwRrAAAAAAYI1gAQAAAMBaiP0mApfjOObrmTNn/F0UAAAAIM259Vy33pscgoWFEydOmK+RkZH+LgoAAABw3Zw9e1Zy5cqV7DoECwt58+Y1X6Oioq56opH50rsGyujoaImIiPB3cXADce0DF9c+MHHdAxfXXjwtFRoqihYtKldDsLAQHPx/Q1Q0VATyGy6Q6XXn2gcmrn3g4toHJq574OLaS4pvoDN4GwAAAIA1ggUAAAAAawQLC2FhYTJ8+HDzFYGFax+4uPaBi2sfmLjugYtrn3pBTkrmjgIAAACAZNBiAQAAAMAawQIAAACANYIFAAAAAGsEi2s0ZcoUKVWqlGTLlk1uu+02Wb9+vb+LBEujR4+WOnXqyE033SQFCxaU9u3by969e33W+fvvv6Vfv36SL18+CQ8Pl3vvvVf++OMPn3X0AxPbtGkjOXLkMNt57rnn5MqVKzf4aHCtxowZI0FBQTJgwADPMq575vXbb7/Jgw8+aK5t9uzZpVq1arJx40bP8zoMcdiwYVKkSBHzfNOmTeXnn3/22cbJkyelW7duZp773LlzS+/eveXcuXN+OBqkVGxsrAwdOlRKly5trmvZsmXllVdeMdfbxbXPHFauXCnt2rUzH+6mv9sXLFjg83xaXedt27bJHXfcYeqF+qF6Y8eOlYCkg7eROnPnznVCQ0OdGTNmODt37nQeffRRJ3fu3M4ff/zh76LBQosWLZyZM2c6O3bscLZs2eK0bt3aKVGihHPu3DnPOo8//rgTGRnpLFmyxNm4caNz++23O/Xq1fM8f+XKFadq1apO06ZNnc2bNzvffPONkz9/fmfIkCF+Oiqkxvr1651SpUo51atXd55++mnPcq575nTy5EmnZMmSTs+ePZ1169Y5Bw8edBYtWuTs37/fs86YMWOcXLlyOQsWLHC2bt3q3H333U7p0qWdv/76y7NOy5YtnRo1ajg//vijs2rVKqdcuXJO165d/XRUSIlRo0Y5+fLlc7766ivn0KFDzieffOKEh4c7EydO9KzDtc8c9PfxSy+95Hz22WeaGp358+f7PJ8W1zkmJsYpVKiQ061bN1OH+Oijj5zs2bM77777rhNoCBbX4NZbb3X69evn+T42NtYpWrSoM3r0aL+WC2nr2LFj5pfQihUrzPenT592smbNav4AuXbv3m3WWbt2recXWHBwsHP06FHPOlOnTnUiIiKcixcv+uEokFJnz551ypcv7yxevNhp2LChJ1hw3TOv559/3mnQoEGSz8fFxTmFCxd2xo0b51mm74ewsDBTcVC7du0y74UNGzZ41lm4cKETFBTk/Pbbb9f5CHCt2rRp4/Tq1ctnWceOHU3FUHHtM6f4wSKtrvPbb7/t5MmTx+f3vf5+qVChghNo6AqVSpcuXZKffvrJNJW5goODzfdr1671a9mQtmJiYszXvHnzmq963S9fvuxz7StWrCglSpTwXHv9ql0pChUq5FmnRYsWcubMGdm5c+cNPwaknHZ10q5M3tdXcd0zry+++EJq164tnTt3Nt3XatasKdOnT/c8f+jQITl69KjPtc+VK5fp/up97bVrhG7Hpevr34V169bd4CNCStWrV0+WLFki+/btM99v3bpVVq9eLa1atTLfc+0DQ1pdZ13nzjvvlNDQUJ+/Adqd+tSpUxJIQvxdgIzmzz//NH0zvSsQSr/fs2eP38qFtBUXF2f62NevX1+qVq1qlukvH/2lob9g4l97fc5dJ7H3hvsc0qe5c+fKpk2bZMOGDQme47pnXgcPHpSpU6fKwIED5cUXXzTX/6mnnjLXu0ePHp5rl9i19b72Gkq8hYSEmBsSXPv064UXXjDBX28SZMmSxfxdHzVqlOlHr7j2gSGtrrN+1fE6Sf0NyJMnjwQKggWQxN3rHTt2mDtYyNyio6Pl6aeflsWLF5tBdwisGwh6F/K1114z32uLhf7cv/POOyZYIPP6+OOPZfbs2TJnzhypUqWKbNmyxdxM0gG+XHvg2tEVKpXy589v7m7EnxFGvy9cuLDfyoW08+STT8pXX30ly5Ytk+LFi3uW6/XVrnCnT59O8trr18TeG+5zSH+0q9OxY8fklltuMXeh9LFixQp56623zP/1rhPXPXPSWWAqV67ss6xSpUpmhi/va5fc73v9qu8fbzobmM4iw7VPv3TWNm21uP/++003xoceekieeeYZMzug4toHhrS6zvwN+AfBIpW0ibxWrVqmb6b3XS/9vm7dun4tG+zouC4NFfPnz5elS5cmaNbU6541a1afa6/9J7US4l57/bp9+3afX0J6J1ynqItfgUH60KRJE3PN9I6l+9C72Nolwv0/1z1z0q6O8aeU1j73JUuWNP/X3wFaKfC+9tp9RvtVe197DZ0aUF36+0P/Lmg/baRPFy5cMH3kvelNQ71uimsfGNLqOus6Oq3t5cuXff4GVKhQIaC6QRn+Hj2eUaeb1RkDPvjgAzNbwGOPPWamm/WeEQYZzxNPPGGmnFu+fLlz5MgRz+PChQs+047qFLRLly41047WrVvXPOJPO9q8eXMzZe23337rFChQgGlHMxjvWaEU1z3zTi8cEhJiph79+eefndmzZzs5cuRwPvzwQ5+pKPX3++eff+5s27bNueeeexKdirJmzZpmytrVq1eb2cWYcjR969Gjh1OsWDHPdLM6FalOET148GDPOlz7zDPjn04Drg+t9k6YMMH8/5dffkmz66wzSel0sw899JCZblbrifq7hOlmkWKTJk0yFQ39PAudflbnNkbGpr9wEnvoZ1u49BdN3759zbRy+kujQ4cOJnx4O3z4sNOqVSszh7X+oXr22Wedy5cv++GIkFbBguueeX355ZcmFOrNoooVKzrTpk3zeV6noxw6dKipNOg6TZo0cfbu3euzzokTJ0wlQz8HQacYfvjhh01lBunXmTNnzM+4/h3Pli2bU6ZMGfNZB97ThXLtM4dly5Yl+rddw2VaXmf9DIwGDRqYbWho1cASiIL0H3+3mgAAAADI2BhjAQAAAMAawQIAAACANYIFAAAAAGsECwAAAADWCBYAAAAArBEsAAAAAFgjWAAAAACwRrAAAAAAYI1gAQAAAMAawQIAcEMcPXpU+vfvL2XKlJGwsDCJjIyUdu3ayZIlS25oOYKCgmTBggU3dJ8AEAhC/F0AAEDmd/jwYalfv77kzp1bxo0bJ9WqVZPLly/LokWLpF+/frJnzx5/FxEAYCnIcRzHdiMAACSndevWsm3bNtm7d6/kzJnT57nTp0+bwBEVFWVaNLQFIzg4WFq2bCmTJk2SQoUKmfV69uxp1vVubRgwYIBs2bJFli9fbr6/6667pHr16pItWzZ57733JDQ0VB5//HF5+eWXzfOlSpWSX375xfP6kiVLmtADALBHVygAwHV18uRJ+fbbb03LRPxQoTRUxMXFyT333GPWXbFihSxevFgOHjwoXbp0SfX+/v3vf5v9rFu3TsaOHSsjR44021MbNmwwX2fOnClHjhzxfA8AsEdXKADAdbV//37RxvGKFSsmuY62Umzfvl0OHTpkxl6oWbNmSZUqVUzlv06dOinen7ZYDB8+3Py/fPnyMnnyZLP9Zs2aSYECBTxhpnDhwtbHBgD4By0WAIDrKiU9bnfv3m0ChRsqVOXKlU0A0OdSQ4OFtyJFisixY8dStQ0AQOoRLAAA15W2GuhMTLYDtHXcRfyQogPA48uaNavP97pv7WoFALi+CBYAgOsqb9680qJFC5kyZYqcP38+wfM6ILtSpUoSHR1tHq5du3aZ57TlQmk3Jh0X4U0HbqeWBo/Y2NhrOhYAQNIIFgCA605DhVbmb731Vvn000/l559/Nl2c3nrrLalbt640bdrUTEHbrVs32bRpk6xfv166d+8uDRs2lNq1a5ttNG7cWDZu3GjGXujrdRzFjh07Ul0WnRlKx1zo52qcOnXqOhwtAAQmggUA4LrTD8XTwNCoUSN59tlnpWrVqmYwtVbwp06darorff7555InTx658847TdDQ1/z3v//1bENbPYYOHSqDBw82g7nPnj1rwkdqjR8/3swSpeM5atasmcZHCgCBi8+xAAAAAGCNFgsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAsEawAAAAAGCNYAEAAADAGsECAAAAgDWCBQAAAABrBAsAAAAA1ggWAAAAAKwRLAAAAABYI1gAAAAAEFv/D/X0w0X7J7aHAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "try:\n", + " import matplotlib.pyplot as plt\n", + "\n", + " latest_cat = cat_metrics[0] if cat_metrics else None\n", + " if latest_cat and latest_cat.get(\"histogram\"):\n", + " hist = latest_cat[\"histogram\"]\n", + " labels = [e[\"value\"] for e in hist[\"values\"]]\n", + " counts = [e[\"count\"] for e in hist[\"values\"]]\n", + " if hist[\"other_count\"] > 0:\n", + " labels.append(\"(other)\")\n", + " counts.append(hist[\"other_count\"])\n", + "\n", + " fig, ax = plt.subplots(figsize=(8, 4))\n", + " ax.barh(labels, counts, color=\"steelblue\", edgecolor=\"white\")\n", + " ax.set_title(f\"vehicle_type distribution — {latest_cat['metric_date']}\")\n", + " ax.set_xlabel(\"Count\")\n", + " plt.tight_layout()\n", + " plt.show() # pragma: allowlist secret\n", + " else:\n", + " print(\"No categorical histogram data available.\")\n", + "except ImportError:\n", + " print(\"Install matplotlib to visualize: pip install matplotlib\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Feature view aggregates" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Date: 2024-12-01 Total rows: 5000 Features w/ nulls: 0 Max null rate: 0.0\n", + "Date: 2025-01-01 Total rows: 4922 Features w/ nulls: 0 Max null rate: 0.0\n", + "Date: 2025-01-01 Total rows: 576 Features w/ nulls: 0 Max null rate: 0.0\n" + ] + } + ], + "source": [ + "view_metrics = monitoring.get_feature_view_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " data_source_type=\"batch\",\n", + ")\n", + "\n", + "for m in view_metrics[:3]:\n", + " print(f\"Date: {m['metric_date']} Total rows: {m['total_row_count']} \"\n", + " f\"Features w/ nulls: {m['features_with_nulls']} Max null rate: {m.get('max_null_rate', 'N/A')}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Feature service aggregates" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Date: 2025-01-01 Total features: 4 Avg null rate: 0.0\n", + "Date: 2025-01-01 Total features: 4 Avg null rate: 0.0\n", + "Date: 2025-02-28 Total features: 4 Avg null rate: 0.0\n" + ] + } + ], + "source": [ + "svc_metrics = monitoring.get_feature_service_metrics(\n", + " project=\"monitoring_demo\",\n", + " feature_service_name=\"driver_service\",\n", + " data_source_type=\"batch\",\n", + ")\n", + "\n", + "for m in svc_metrics[:3]:\n", + " print(f\"Date: {m['metric_date']} Total features: {m['total_features']} \"\n", + " f\"Avg null rate: {m.get('avg_null_rate', 'N/A')}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Baseline metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline mean: 0.4989\n", + "Baseline stddev: 0.1975\n", + "Baseline null_rate: 0.0000\n" + ] + } + ], + "source": [ + "baseline = monitoring.get_baseline(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " feature_name=\"conv_rate\",\n", + " data_source_type=\"batch\",\n", + ")\n", + "\n", + "if baseline:\n", + " print(f\"Baseline mean: {baseline[0]['mean']:.4f}\")\n", + " print(f\"Baseline stddev: {baseline[0]['stddev']:.4f}\")\n", + " print(f\"Baseline null_rate: {baseline[0]['null_rate']:.4f}\")\n", + "else:\n", + " print(\"No baseline found.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 7: Visualize a Feature Distribution\n", + "\n", + "Use the histogram stored in the metrics to plot a distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/opt/homebrew/Cellar/python@3.12/3.12.11/Frameworks/Python.framework/Versions/3.12/lib/python3.12/pty.py:95: DeprecationWarning: This process (pid=12140) is multi-threaded, use of forkpty() may lead to deadlocks in the child.\n", + " pid, fd = os.forkpty()\n" + ] + } + ], + "source": [ + "!uv pip install -q 'matplotlib'" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAARL1JREFUeJzt3Qd4FOXa//E7Cb2F3kNRkd4EBDwoUgQRUYr1KKIiKgIqqJQjCIIIBxVQATk2sCHKK6hU6eARUGlKURSlRCEUEQIoLZn3up/3P/vfDQmEMJOZ3f1+rmuNmV12752dze5vnhZjWZYlAAAAAADAcbHO3yUAAAAAAFCEbgAAAAAAXELoBgAAAADAJYRuAAAAAABcQugGAAAAAMAlhG4AAAAAAFxC6AYAAAAAwCWEbgAAAAAAXELoBgAAAADAJYRuAACyYNiwYRITExOyrVKlSnLvvfe6/tg7d+40jz116tTANn3cAgUKSHbRx9d9AAAAzo3QDQCICKtWrTIh8PDhwxJO5s2b59vw6ufanDZz5ky5/fbb5ZJLLpF8+fJJ1apV5YknnsjwePr888/liiuukDx58kiFChVk6NChcubMmZDbLFmyRO6//365/PLLzX3qfT/wwAOyd+/es+7v2muvNScy0l6uv/76TD8HrfXBBx+UEiVKSP78+aVFixayfv36s2730Ucfyd133y1VqlQxj6GPfaGy87EAINzl8LoAAACcCt3PPvusafEtXLiwJzVs27ZNYmNjLzjYTpw48YLCbcWKFeXvv/+WnDlzZqFKZ2rTx8+RI3K+RmiALFu2rAmIGqI3bdokEyZMMPtAw2TevHkDt50/f7507NjRBMhXX33V3Pa5556T/fv3y2uvvRa43YABA+TQoUNy6623mtD566+/mvucM2eObNy4UUqXLh1SQ/ny5WXUqFEh27SmzEhNTZX27dvLd999J0899ZQUL15cJk2aZGpct26deXyb1qjbGjVqJH/88ccF76vsfCwAiASR82kJAIgox48fNy1o4SR37tyu3r+2pGrgyZUrl2lh9ZLXj++0//mf/zmrFbZBgwbSrVs3+eCDD0wLte3JJ5+UOnXqyMKFCwMnHgoVKiTPP/+8PPbYY1KtWjWzbezYsdKsWbOQEzHact28eXMTvjWoB4uPjzehP6v164mnGTNmyC233GK23XbbbaaVXVvhp02bFrjte++9J+XKlTN11apVy9ePBQCRgO7lABAhfv/9d+nevbtpGdPwV7lyZenZs6ecOnUqcBttadNWt6JFi5rurk2aNJG5c+eG3M/y5ctNN9CPP/5YRo4caVrfNGC1atVKtm/fHrhd7969zRjiv/7666xa7rzzTtOKl5KSckHjo7du3Sr//Oc/pUiRIiasqO+//960XmvXXK1D71e77Aa3mum/1xY3pc/b7pqrY59t77//vglR2mKpz/+OO+6QxMTETNX33//+17TU6eNfeuml8p///Cfd26Ud03369GnT+q4tf/pvixUrZp7XokWLzPV6W21JVsFdioPHbb/44osyfvx487j6uuo+Sm9Md/Br3LZtW3PCQo+F4cOHi2VZZ72++jNY2vs8V232trQt4Bs2bJB27dqZAKrHhh4za9asCbmN3r/+26+++kr69esX6J7cqVMnOXDggHglvW7PWpP64YcfAtt0/+tFW8aDW/ofeeQRs581kNquueaas3o+6DY9/oLvM+2JlWPHjl1w/fq4pUqVks6dOwe26b7VMPzZZ5/JyZMnA9sTEhIuuEeGV48FAJGAlm4AiAB79uyRK6+8MjDOUlvaNITrl2MNxdoyum/fPrnqqqvM748++qgJgO+8847cdNNN5nZ2wLCNHj3afFnWVr0jR47ImDFj5K677pKvv/7aXK/jXzWUaWjXIG/T+589e7YJbXFxcRf0POxuuNpiaAdFDagaJO+77z4TuLds2SKvv/66+amBTgOcfvn/6aef5MMPP5Rx48aZ7q52EFB68mDIkCEmFGiLpYY77RasAUiD4rm6o2vX4TZt2pj70pCpoUhb8zR0nI/eXrsL62Pq65OcnCxr16413ZWvu+46eeihh8xrp89RWwTTM2XKFDlx4oR5XTV0a2DT1u706EkObUnVkyn6ei1YsCAw1ljD94XITG3B9PW4+uqrTeDu37+/6fquJyc0zK5YsUIaN24ccvs+ffqYkytanwZ+PbGgJ3J0DLBfJCUlmZ/28aT0eFENGzYMua2e4NATVPb1GdFArZfg+7TpMawnIPREmR5fPXr0kGeeeSZTwwj0cXWMedqAq8edvl/0vmvXri1OyM7HAoCIYAEAwt4999xjxcbGWt9+++1Z16Wmppqfjz/+uKZY68svvwxcd/ToUaty5cpWpUqVrJSUFLNt2bJl5nbVq1e3Tp48Gbjtyy+/bLZv2rQpcL/lypWzunTpEvJ4H3/8sbndypUrM13/0KFDzb+58847z7rur7/+Omvbhx9+eNZjvPDCC2bbjh07Qm67c+dOKy4uzho5cmTIdn0eOXLkOGt7Wh07drTy5Mlj7dq1K7Bt69at5j7TfoxWrFjR6tatW+D3unXrWu3btz/n/ffq1eus+1H6PHR7oUKFrP3796d73ZQpUwLb9HF1W58+fQLb9DXSx8+VK5d14MCBkNdXf57vPjOqTel2fd2C95M+zi+//BLYtmfPHqtgwYLWNddcE9im96//tnXr1oFjU/Xt29fs08OHD1t+0b17d1PTTz/9dNZxtnv37rNu36hRI6tJkybnvM8RI0aYf79kyZKQ7ffff781bNgw65NPPrHeffdd66abbjK3u+222zJVa/78+c19pDV37lxzPwsWLEj339WsWdNq3rx5ph7Di8cCgEhAfx8ACHPa6vnpp59Khw4dzmp9U3aXYJ0QSlui7G7bSrsAawuqtjRql9lg2rKsLeQ2bcVU2ups36+2TOv9BneH1ZZKHcMZ/DiZ9fDDD5+1LXgCK23xPXjwoGnJVenNlpzerNS6j7SVW/+tfdFWc21VX7ZsWYb/VluOv/jiCzNplk6uZatevbrpwn0+2oKuLcA///yzZFWXLl0CLfaZoa3FNn2N9HdtOV28eLG4RfeTjm/W/aTDAGxlypQxwwW0e7628gfT4y64u7oeX3o/u3btEj/QcclvvfWWmcE8eGIwnUAuo/H7OoTAvj49K1euNMMN9Fhs2bJlyHX6WNrqr702unbtarppa0u3DvNI20U/Pfq4GdUUXLcTsvOxACASELoBIMxpV2kNNOebpEjDjC6DlJYGSPv6YMEhU2lXYPXnn38GtmkXc/2CrcsnKQ3fGsI1jKddwzozdDx2Wjr7s05Opd1tNYBrALVvp93ez0cDrzbManDSfxt80XG1OuP0ufatPr/g0GVLb1+mpV26tcu/TjCl3W113LmOUb/YfZIR7e4bHHqVPrYKHt/uNN1POqwgo+NLT3qkHT+fmeMrLX0ttMt3Vi6ZOVZsX375pZkfQU+s6NCE9E4CBY9bDj4pFHySKNiPP/5ohnDo+/TNN9/MVB0a+JV9wkRPnqR9Xva8Cfq4GdUUXHdmZedjAUCkY0w3ACBdGY3HDp6US1ucdfIwbY3TFk0dy63BSMN4VqT3ZV1bBXWmZA2s9erVM63zGuJ07HJGY5uD6W30BIAu85Tec9L7c4uOGf/ll19Mq6W2BGvY0jHnkydPDpkN+1ycDjAZnQzJ7KR32Xl8paW9KLQHRlboLOTpTTyXli6DpfMcaDjWuQ7SLoumrfdK19rWScKC6TbtTZKWnnDQeQF0dnI9KVWwYMFM1Wzfv554Uvo+0PWwg+3YscO8B7Wu9Nb/trdldukxW3Y+FgBEOkI3AIQ5bbHVyas2b9583rWddR3p9Frg7OuzQkPxyy+/bFrbNRTpl3K7+/fF0lbPJUuWmC65OqGULb3u2hmFSZ31W4Octhjbrb4Xsm819Kb3eOnty/ToxGcaFPWiPQE0iOsEa3bozkqPgHOdYNDu/8HPUye1Uvq6BLcoawt8sPS6dWe2Nt1POht+RseXtsCnDahZoS3P9szvFyozQVBPkOjJnJIlS5pwnN4JGT3xo3RCvOCArZPO/fbbb6bbfDCdZV8Dt7YM67Fsh/bMsIdy2MML6tate9bzt9f61rq0hV6PgeAJznTiQ31tLvTYz87HAoBIR+gGgDCnX3p1LK0uiaVBIO24bg2cGp5uuOEGM0P06tWrpWnTpoG1sHW2YQ1kNWrUyNLja6u2zpStM6HrbNnaFdzp1tC0rZ/6PNKy1/ROGyZ1jOygQYNMcNd9FBwk9X61FVFncs/o8TXo6Zj53bt3B7pEa7d0Het9Phq4gu9bQ9xll10W0tU6uO5zzaKeWbr+8yuvvBJ4fvq7zn6ty3fZJ1f0een4Yj1ubJMmTTrrvjJbm96fBktt0ddu7HbA1xnzdWy0ju/XE0MXSwPrhYTWC6Hdp/U56PtJX9uMxtHXrFnTrA6g7xud4d0+Rl977TVzbNnrVtvvL33f6UoCOndAesMUlJ6w0jHSweOk9bWz1/G25w/QEyatW7dO9z70cbVlXucwsGvQuQt0LW2d7+FC15DPzscCgEhH6AaACKBLbGn35ebNm5uWNh1Hq1099UuwTmKlgWngwIFmSS1dR1mXDNMWWA3K2mX0k08+yfJaurp0kAbJp59+2rTmZbVreXo0qGnLsIZ6XfNaJ2jT56k1p6VrcCutQ9fg1qCpAUBbujW8aPDWQKhBU7v36n3MmjXL7C9dFi0jGtb1ZIJO9KVrMevyW7rcmIav843P1hMZumSW1qb7W0+KaFgJnuzMrltfEw1XGuK0/qzQiay0Vu1KrUt0aZd6XdLtX//6VyBEahdnHXOvz0FDou6fOXPmpDu2/UJq032sLaMasHU/abdsXTJMjwl9/fxOW7i1ZVmXO9P3jF5sOp+ALvFme+GFF0wXdA3puj+0l4me3NDeC/YcCUqX2Pvmm2/MuvJ6oiZ4bW49AWOf9NAJAXVte73oe0mHaOixqWuZ6/Gp77Hz0fCrPUy0R4VOiqhLkumJFB02oMdwMD3hohd7PL6eHLADvr7f9OKXxwKAiOD19OkAAGfokla6dFiJEiWs3LlzW5dccolZ8il42S9dzumWW26xChcubJbBuvLKK605c+aE3I+9pNSMGTPOu6SU7emnnzbXXXbZZVmq3V4yzF7WKthvv/1mderUydQcHx9v3XrrrWYpqrRLVtnLMekyZrp8Wtrlw3QppmbNmpnljvRSrVo1s3+2bdt23vpWrFhhNWjQwCyJpft18uTJgZrPtWTYc889Z/ax1p43b17zmLpE2alTpwK3OXPmjFnmS1+3mJiYwH3a+1uXqEoroyXD9Hnpa9ymTRsrX758VqlSpUyd9nJwNt3PutSb3qZIkSLWQw89ZG3evPms+8yoNpXe/l+/fr3Vtm1bq0CBAua+W7RoYa1atSrkNvaSYWmXt8toKbPsoo+d0SW9Za5mzZpl1atXz7zXypcvbw0ePDjkdbWPh4zuU6+z/frrr+a41qX79H2p+06PNz3OgpdVO59Dhw6ZZc6KFStm7kPrTm8ZQfvYTe+S9jX1w2MBQLiL0f94HfwBAAAAAIhELBkGAAAAAIBLGNMNAHCNztatl3PRscYZLR8FAAAQ7gjdAADXvPjii2dNrJSWvfYvAABAJGJMNwDANTobtL3WcEZ0tmuddRsAACASEboBAAAAAHAJE6kBAAAAAOASxnSLSGpqquzZs0cKFiwoMTExXpcDAAAAAPA57TR+9OhRKVu2rMTGZtyeTegWMYE7ISHB6zIAAAAAAGEmMTFRypcvn+H1hG4R08Jt76xChQp5XQ4AAAAAwOeSk5NN462dJzNC6NbZ5P5fl3IN3IRuAAAAAEBmnW+IMhOpAQAAAADgEkI3AAAAAAAuIXQDAAAAAOASQjcAAAAAAC4hdAMAAAAA4BJCNwAAAAAALiF0AwAAAADgEkI3AAAAAAAuIXQDAAAAABCJoXvYsGESExMTcqlWrVrg+hMnTkivXr2kWLFiUqBAAenSpYvs27cv5D52794t7du3l3z58knJkiXlqaeekjNnznjwbAAAAAAACJVDPFazZk1ZvHhx4PccOf5/SX379pW5c+fKjBkzJD4+Xnr37i2dO3eWr776ylyfkpJiAnfp0qVl1apVsnfvXrnnnnskZ86c8vzzz3vyfAAAAAAA8E3o1pCtoTmtI0eOyFtvvSXTpk2Tli1bmm1TpkyR6tWry5o1a6RJkyaycOFC2bp1qwntpUqVknr16smIESNkwIABphU9V65cHjwjAAAiW0qqJXGxMV6X4Zs6AADwdej++eefpWzZspInTx5p2rSpjBo1SipUqCDr1q2T06dPS+vWrQO31a7net3q1atN6NaftWvXNoHb1rZtW+nZs6ds2bJF6tev79GzAgAgcmnQHT1rgyQePOZZDQnFC8jATnzOAwD8z9PQ3bhxY5k6dapUrVrVdA1/9tln5eqrr5bNmzdLUlKSaakuXLhwyL/RgK3XKf0ZHLjt6+3rMnLy5ElzsSUnJzv8zAAAiGwauLcn8fkJAICvQ3e7du0C/1+nTh0TwitWrCgff/yx5M2b17XH1dZ0DfgAAAAAAETNkmHaqn355ZfL9u3bzTjvU6dOyeHDh0Nuo7OX22PA9Wfa2czt39MbJ24bNGiQGTNuXxITE115PgAAAACA6Oar0H3s2DH55ZdfpEyZMtKgQQMzC/mSJUsC12/bts0sEaZjv5X+3LRpk+zfvz9wm0WLFkmhQoWkRo0aGT5O7ty5zW2CLwAAAAAARFT38ieffFI6dOhgupTv2bNHhg4dKnFxcXLnnXeaJcK6d+8u/fr1k6JFi5pg3KdPHxO0dRI11aZNGxOuu3btKmPGjDHjuAcPHmzW9tZgDQBAOPHLbNx+qQMAgEjgaej+7bffTMD+448/pESJEtKsWTOzHJj+vxo3bpzExsZKly5dzMRnOjP5pEmTAv9eA/qcOXPMbOUaxvPnzy/dunWT4cOHe/isAADIGmYFBwAg8ngauqdPn37O63UZsYkTJ5pLRrSVfN68eS5UBwBA9mNWcAAAIouvxnQDAAAAABBJCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAIh4KamW+IFf6gAAANknRzY+FgAAnoiLjZHRszZI4sFjntWQULyADOxU37PHBwAA3iB0AwCiggbu7UnJXpcBAACiDN3LAQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAQETyyxJtfqkDAOANZi8HAAARiaXiAAB+QOgGAAARi6XiAABeo3s5AAAAAAAuIXQDAAAAAOASQjcAAICH/DLRml/qAIBI45sx3aNHj5ZBgwbJY489JuPHjzfbTpw4IU888YRMnz5dTp48KW3btpVJkyZJqVKlAv9u9+7d0rNnT1m2bJkUKFBAunXrJqNGjZIcOXzz1AAAADLEhG8AENl8kUy//fZb+c9//iN16tQJ2d63b1+ZO3euzJgxQ+Lj46V3797SuXNn+eqrr8z1KSkp0r59eyldurSsWrVK9u7dK/fcc4/kzJlTnn/+eY+eDQAAwIVhwjcAiFyedy8/duyY3HXXXfLGG29IkSJFAtuPHDkib731lowdO1ZatmwpDRo0kClTpphwvWbNGnObhQsXytatW+X999+XevXqSbt27WTEiBEyceJEOXXqlIfPCgAAAAAAH4TuXr16mdbq1q1bh2xft26dnD59OmR7tWrVpEKFCrJ69Wrzu/6sXbt2SHdz7YKenJwsW7ZsycZnAQAAAACAz7qX61jt9evXm+7laSUlJUmuXLmkcOHCIds1YOt19m2CA7d9vX1dRnR8uF5sGtIBAAAAAIiYlu7ExEQzadoHH3wgefLkydbH1onWdIy4fUlISMjWxweASOGX2Y79UgcAAIBvWrq1+/j+/fvliiuuCGzTidFWrlwpEyZMkC+++MKMyz58+HBIa/e+ffvMxGlKf37zzTch96vX29dlRGdJ79evX0hLN8EbAC4csy4DAAD4NHS3atVKNm3aFLLtvvvuM+O2BwwYYEKwzkK+ZMkS6dKli7l+27ZtZomwpk2bmt/158iRI014L1mypNm2aNEiKVSokNSoUSPDx86dO7e5AAAuHrMuAwAA+DB0FyxYUGrVqhWyLX/+/FKsWLHA9u7du5sW6aJFi5og3adPHxO0mzRpYq5v06aNCdddu3aVMWPGmHHcgwcPNpOzEaoBAAAAAF7zxTrdGRk3bpzExsaalm6d+ExnJp80aVLg+ri4OJkzZ4707NnThHEN7d26dZPhw4d7WjcAAAAAAL4L3cuXLw/5XSdY0zW39ZKRihUryrx587KhOgAAAAAAwmydbgAAAAAAIhWhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAAAAAcAmhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAAAAAcAmhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugHAh1JSLfEDv9QBAAAQrnJ4XQAA4GxxsTEyetYGSTx4zLMaEooXkIGd6nv2+AAAAJGA0A0APqWBe3tSstdlAAAA4CLQvRwAAAAAAJcQugEAAAAAcAmhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAAAAAcAmhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAABwXimplviBX+oAgMzKkelbAgAAIGrFxcbI6FkbJPHgMc9qSCheQAZ2qu/Z4wNAVhC6AQAAkCkauLcnJXtdBgCEFbqXAwAAAADgEkI3AAAAAAAuIXQDAAAAAOASQjcAAAAAAC4hdAMAAAAA4BJCNwAAAAAALiF0AwAAAADgEkI3AAAAAACRGLpfe+01qVOnjhQqVMhcmjZtKvPnzw9cf+LECenVq5cUK1ZMChQoIF26dJF9+/aF3Mfu3bulffv2ki9fPilZsqQ89dRTcubMGQ+eDQAAAAAAPgrd5cuXl9GjR8u6detk7dq10rJlS7n55ptly5Yt5vq+ffvK7NmzZcaMGbJixQrZs2ePdO7cOfDvU1JSTOA+deqUrFq1St555x2ZOnWqPPPMMx4+KwAAAAAA/k8O8VCHDh1Cfh85cqRp/V6zZo0J5G+99ZZMmzbNhHE1ZcoUqV69urm+SZMmsnDhQtm6dassXrxYSpUqJfXq1ZMRI0bIgAEDZNiwYZIrVy6PnhkAAAAAAD4a062t1tOnT5fjx4+bbuba+n369Glp3bp14DbVqlWTChUqyOrVq83v+rN27domcNvatm0rycnJgdZyAAAAAACisqVbbdq0yYRsHb+t47ZnzZolNWrUkI0bN5qW6sKFC4fcXgN2UlKS+X/9GRy47evt6zJy8uRJc7FpSAcAAAAAwBct3Zdccon88ccfZ20/fPiwue5CVK1a1QTsr7/+Wnr27CndunUzXcbdNGrUKImPjw9cEhISXH08AAAAAEB0ylLo3rlzp+kOnpa2Hv/+++8XdF/amn3ZZZdJgwYNTBiuW7euvPzyy1K6dGkzQZoG+WA6e7lep/Rn2tnM7d/t26Rn0KBBcuTIkcAlMTHxgmoGAAAAAMDx7uWff/554P+/+OIL00ps0xC+ZMkSqVSpklyM1NRUE941hOfMmdPcpy4VprZt22aWCNPu6Ep/6uRr+/fvN8uFqUWLFpnlx7SLekZy585tLgAAAAAA+CZ0d+zY0fyMiYkx3cCDaUDWwP3SSy9l+v60xbldu3ZmcrSjR4+amcqXL18eCPTdu3eXfv36SdGiRU2Q7tOnjwnaOnO5atOmjQnXXbt2lTFjxphx3IMHDzZrexOqAQAAAABhFbq1FVpVrlxZvv32WylevPhFPbi2UN9zzz2yd+9eE7Lr1KljAvd1111nrh83bpzExsaalm5t/daZySdNmhT493FxcTJnzhwzFlzDeP78+c3JgOHDh19UXQAAAAAAeDZ7+Y4dOxx5cF2H+1zy5MkjEydONJeMVKxYUebNm+dIPQAAAAAA+GLJMB1rrRdtrbZbwG1vv/22E7UBAAAAABB9ofvZZ581XbgbNmwoZcqUMWO8AQAAAACAA6F78uTJMnXqVDOBGQAAAAAAcHCdbl0/+6qrrsrKPwUAAABck5JqiR/4pQ4AYdrS/cADD5jlvYYMGeJ8RQAAAEAWxcXGyOhZGyTx4DHPakgoXkAGdqrv2eMDiIDQfeLECXn99ddl8eLFZpkvXaM72NixY52qDwAAALggGri3JyV7XQYAZD10f//991KvXj3z/5s3bw65jknVAAAAAAC4iNC9bNmyrPwzAAAAAACiSpYmUgMAAAAAAC61dLdo0eKc3ciXLl2albsFAAAAACCiZCl02+O5badPn5aNGzea8d3dunVzqjYAAAAAAKIvdI8bNy7d7cOGDZNjx7xbngEAAAAAgIgd03333XfL22+/7eRdAoCjUlIt8QO/1AEAAAAftnRnZPXq1ZInTx4n7xIAHBUXGyOjZ20wa7h6JaF4ARnYqb5njw8AAACfh+7OnTuH/G5Zluzdu1fWrl0rQ4YMcao2AHCFBu7tSclelwEAAIAokKXQHR8fH/J7bGysVK1aVYYPHy5t2rRxqjYAAAAAAKIvdE+ZMsX5SgAAAAAAiDAXNaZ73bp18sMPP5j/r1mzptSvzxhFAAAAAAAuKnTv379f7rjjDlm+fLkULlzYbDt8+LC0aNFCpk+fLiVKlMjK3QIAAAAAEFGytGRYnz595OjRo7JlyxY5dOiQuWzevFmSk5Pl0Ucfdb5KAAAAAACipaV7wYIFsnjxYqlevXpgW40aNWTixIlMpAYAAAAAwMW0dKempkrOnDnP2q7b9DoAAAAAAJDF0N2yZUt57LHHZM+ePYFtv//+u/Tt21datWrlZH0AAAAAAERX6J4wYYIZv12pUiW59NJLzaVy5cpm26uvvup8lQAAAAAARMuY7oSEBFm/fr0Z1/3jjz+abTq+u3Xr1k7XBwAAAABAdLR0L1261EyYpi3aMTExct1115mZzPXSqFEjs1b3l19+6V61AAAAAABEaugeP3689OjRQwoVKnTWdfHx8fLQQw/J2LFjnawPAAAAAIDoCN3fffedXH/99Rler8uFrVu3zom6AAAAAACIrtC9b9++dJcKs+XIkUMOHDjgRF0AAAAAAERX6C5Xrpxs3rw5w+u///57KVOmjBN1AQAAAAAQXaH7hhtukCFDhsiJEyfOuu7vv/+WoUOHyo033uhkfQAAAAAARMeSYYMHD5aZM2fK5ZdfLr1795aqVaua7bps2MSJEyUlJUWefvppt2oFAAAAACByQ3epUqVk1apV0rNnTxk0aJBYlmW26/Jhbdu2NcFbbwMAAAAAAC4wdKuKFSvKvHnz5M8//5Tt27eb4F2lShUpUqSIOxUCAAAAABAtodumIbtRo0bOVgMAAAAAQLROpAYAAAAAADKP0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAQCSG7lGjRkmjRo2kYMGCUrJkSenYsaNs27Yt5DYnTpyQXr16SbFixaRAgQLSpUsX2bdvX8htdu/eLe3bt5d8+fKZ+3nqqafkzJkz2fxsAAAAAADwUehesWKFCdRr1qyRRYsWyenTp6VNmzZy/PjxwG369u0rs2fPlhkzZpjb79mzRzp37hy4PiUlxQTuU6dOyapVq+Sdd96RqVOnyjPPPOPRswIAAAAA4P/kEA8tWLAg5HcNy9pSvW7dOrnmmmvkyJEj8tZbb8m0adOkZcuW5jZTpkyR6tWrm6DepEkTWbhwoWzdulUWL14spUqVknr16smIESNkwIABMmzYMMmVK5dHzw4AAAAAEO18NaZbQ7YqWrSo+anhW1u/W7duHbhNtWrVpEKFCrJ69Wrzu/6sXbu2Cdy2tm3bSnJysmzZsiXbnwMAAAAAAL5o6Q6Wmpoqjz/+uPzjH/+QWrVqmW1JSUmmpbpw4cIht9WArdfZtwkO3Pb19nXpOXnypLnYNKADAAAAABCxLd06tnvz5s0yffr0bJnALT4+PnBJSEhw/TEBAAAAANHHF6G7d+/eMmfOHFm2bJmUL18+sL106dJmgrTDhw+H3F5nL9fr7Nuknc3c/t2+TVqDBg0yXdntS2JiogvPCgAAAAAQ7TwN3ZZlmcA9a9YsWbp0qVSuXDnk+gYNGkjOnDllyZIlgW26pJguEda0aVPzu/7ctGmT7N+/P3AbnQm9UKFCUqNGjXQfN3fu3Ob64AsAAAAAABE1plu7lOvM5J999plZq9seg61dvvPmzWt+du/eXfr162cmV9Nw3KdPHxO0deZypUuMabju2rWrjBkzxtzH4MGDzX1ruAYAAAAAICpD92uvvWZ+XnvttSHbdVmwe++91/z/uHHjJDY2Vrp06WImP9OZySdNmhS4bVxcnOma3rNnTxPG8+fPL926dZPhw4dn87MBAAAAAMBHoVu7l59Pnjx5ZOLEieaSkYoVK8q8efMcrg4AAAAAgAiYSA0AAAAAgEhE6AYAAACyWUrq+Xt8RlMdQCTztHs5AAAAEI3iYmNk9KwNknjwmGc1JBQvIAM71ffs8YFoQegGAAAAPKCBe3tSstdlAHAZ3csBAAAAAHAJoRtARI0J80sdAAAAgKJ7OQBHMDYNAAAAOBuhG4BjGJsGAAAAhKJ7OQAAAAAALiF0AwAAAADgEkI3AAAAAAAuIXQDAAAAAOASQjcAAAAAAC4hdAMAAAAA4BJCNwAAAAAALiF0AwAAAADgEkI3AAAAAAAuIXQDAAAAAOASQjcAAAAAAC4hdAMAAAAA4BJCNwAAAAAALiF0AwAAAADgEkI3AAAAAAAuIXQDPpeSaokf+KUOAAAAIJzk8LoAAOcWFxsjo2dtkMSDxzyrIaF4ARnYqb5njw8AAACEK0I3EAY0cG9PSva6DAAAAAAXiO7lAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAgXSmpltcl+KIG4GLkuKh/DQAAACBixcXGyOhZGyTx4DFPHj+heAEZ2Km+J48NOIXQDQAAACBDGri3JyV7XQYQtuheDgAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAARGLoXrlypXTo0EHKli0rMTEx8umnn4Zcb1mWPPPMM1KmTBnJmzevtG7dWn7++eeQ2xw6dEjuuusuKVSokBQuXFi6d+8ux455s44gAAAAAAC+Cd3Hjx+XunXrysSJE9O9fsyYMfLKK6/I5MmT5euvv5b8+fNL27Zt5cSJE4HbaODesmWLLFq0SObMmWOC/IMPPpiNzwIAAAAAgPTlEA+1a9fOXNKjrdzjx4+XwYMHy80332y2vfvuu1KqVCnTIn7HHXfIDz/8IAsWLJBvv/1WGjZsaG7z6quvyg033CAvvviiaUEHAAAAAMArvh3TvWPHDklKSjJdym3x8fHSuHFjWb16tfldf2qXcjtwK719bGysaRnPyMmTJyU5OTnkAgAAAABA1IRuDdxKW7aD6e/2dfqzZMmSIdfnyJFDihYtGrhNekaNGmUCvH1JSEhw5TkAAAAAAKKbb0O3mwYNGiRHjhwJXBITE70uCQAAAAAQgXwbukuXLm1+7tu3L2S7/m5fpz/3798fcv2ZM2fMjOb2bdKTO3duM9t58AUAAAAAgKgJ3ZUrVzbBecmSJYFtOvZax2o3bdrU/K4/Dx8+LOvWrQvcZunSpZKammrGfgMAAAAAELWzl+t62tu3bw+ZPG3jxo1mTHaFChXk8ccfl+eee06qVKliQviQIUPMjOQdO3Y0t69evbpcf/310qNHD7Os2OnTp6V3795mZnNmLgcAAACiQ0qqJXGxMVFfA/zJ09C9du1aadGiReD3fv36mZ/dunWTqVOnSv/+/c1a3rrutrZoN2vWzCwRlidPnsC/+eCDD0zQbtWqlZm1vEuXLmZtbwAAAADRQcPu6FkbJPHgMU8eP6F4ARnYqb4njw3/8zR0X3vttWY97ozExMTI8OHDzSUj2io+bdo0lyoEAAAAEA40cG9PYilg+I9vx3QDAAAAABDuCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN2IWimpGa8RH411AAAAAHBeDhfuEwgLcbExMnrWBkk8eMyzGhKKF5CBnep79vgAAAAA3EXoRlTTwL09KdnrMgAAAABEKLqXAwAAAADgEkI3InaMsl/qAAAAABC96F4OxzFWGgAAAAD+D6EbrmCsNAAAAADQvRwAAAAAANcQugEAAAAAcAmhGwAAAADgqwmJU3xQg1MY0w0AAAAA8M3EyAkRNikyoTuM6NkefQN4zS91AAAAAHAHEyM7h9AdRrw+4xSJZ50AAAAAwE2E7jDDGScAAAAACB9MpAYAAAAAgEsI3QAAAAAQJTNy+6GGaEP3cgAAAACIgjmamJ/JG4RuAAAAAMgmzNEUfeheDgAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNANAAAAAIBLCN0AAAAAALiE0A0AAAAAgEsI3QAAAAAAuCRiQvfEiROlUqVKkidPHmncuLF88803XpcEAAAAAIhyERG6P/roI+nXr58MHTpU1q9fL3Xr1pW2bdvK/v37vS4NAAAAABDFIiJ0jx07Vnr06CH33Xef1KhRQyZPniz58uWTt99+2+vSAAAAAABRLIeEuVOnTsm6detk0KBBgW2xsbHSunVrWb16dbr/5uTJk+ZiO3LkiPmZnJwsflcin8ip+DhPHz8z+4k6M4c6nUWdzqJOZ1Gns6jTWdTpLOrM/hrt21Jn9NXpJbtGy7LOebsY63y38Lk9e/ZIuXLlZNWqVdK0adPA9v79+8uKFSvk66+/PuvfDBs2TJ599tlsrhQAAAAAEGkSExOlfPnykdvSnRXaKq5jwG2pqaly6NAhKVasmMTExEik0jMxCQkJ5qAoVKiQ+BV1Oos6nUWdzqJOZ1Gns6jTWdTpLOp0FnVGZ50XS9uvjx49KmXLlj3n7cI+dBcvXlzi4uJk3759Idv199KlS6f7b3Lnzm0uwQoXLizRQg/8cDj4qdNZ1Oks6nQWdTqLOp1Fnc6iTmdRp7OoMzrrvBjx8fGRP5Farly5pEGDBrJkyZKQlmv9Pbi7OQAAAAAA2S3sW7qVdhXv1q2bNGzYUK688koZP368HD9+3MxmDgAAAACAVyIidN9+++1y4MABeeaZZyQpKUnq1asnCxYskFKlSnldmq9ol3pdyzxt13q/oU5nUaezqNNZ1Oks6nQWdTqLOp1Fnc6izuisM7uE/ezlAAAAAAD4VdiP6QYAAAAAwK8I3QAAAAAAuITQDQAAAACASwjdAAAAAAC4hNCNsKJrsMM57E9nsT+dxf50FvvTWexPZ7E/ncX+dBb70zmpUbovCd0IC7t27ZLff/9dYmM5ZJ3w888/y6+//sr+dAjHp7PYn85ifzqL/eksPo+cxfHpLI5P5/wc5fsyOp81jO3bt8u4ceOkf//+Mn/+fNm3b5/40caNG6VBgwby5Zdfip/99NNPZq34e++9V959913ZtGmT+NF3330ntWrVki+++EL8jOPTWexPZ7E/ncX+dBafR87i+HQWx6dz2JdhRNfpRvTZtGmTVaRIEatZs2ZW48aNrdy5c1t33nmnNW/ePMtPNm7caOXNm9d64oknzrouNTXV8ostW7ZYhQsXtq6//npzKVWqlNWyZUtrypQplp9s2LDB7M8nn3zS8jOOT2exP53F/nQW+9NZfB45i+PTWRyfzmFfhhdCdxT666+/rBtvvNHq06ePdebMGbNt/vz5Vps2baxrr73WmjlzpuUHP/74o/lwGzZsmPlda/3vf/9r6vv+++8DtXvt1KlTVteuXa0HHngg8MH2zTffmN9r1Khhvfbaa5Yf/PTTT1aOHDms4cOHm99Pnz5tLViwwHr99det5cuXW/v27bP8gOPTWexPZ7E/ncX+dBafR87i+HQWx6dz2Jfhh9AdhfSPb/369a3nnnsuZPvq1autm266yZwtW7NmjeWlEydOWP/85z+tokWLWt9++63Z1qFDB6tmzZpW8eLFrbi4OOupp56yfv31V8tr+sfu6quvtnr16nXWh+AjjzxiNWjQwPrss88sr/849+/f38qTJ481d+5cs61du3Zmf5YtW9Zs1z/eegx4jePTWexPZ7E/ncX+dBafR9F3fP79998cn1F4fLIvww9juqNwxsCTJ09KmTJl5ODBg2ZbSkqK+dmkSRN58sknZffu3fLpp5+abXpixgu5c+eWBx98UFq1amVqqlKliql9ypQpZvyK/nzjjTfkvffe87RO+3Hr1KkjBw4ckD///DNwXdWqVeXhhx+WYsWKycyZMz2tM2fOnNK1a1d56KGHpG/fvlKxYkWz7cMPP5TExERT34YNG2Tq1Kme1snx6Syt6cSJE2GxP3v06OH7/an7juPTOWfOnGF/OkwfOxw+j+6++27ffx6pv/76y/fHZ548eaR79+6+Pz61pnA5Pu+66y5fH5989wxTXqd+eGPChAlWrly5rC+++ML8npKSErhu0qRJVsGCBa39+/dbXtOuJ/ZYlV9++SXkutGjR5uxLH/88YcntQWPkfr444/NeBXtLpN27NSMGTNM1xqvzjIHv7Zbt261HnzwQXOmUf8/2Ntvv23lzJnT2r17t+W1iRMnhsXxuWLFCt8en8F4v198S2cw7bbnx/2Zts4vv/zSl/vz0KFDYbE/09bp1/2p3TO3b9/u+88jrVO7mvr98+jnn3+2XnjhBd8fn1rnv//9b98fn2mPwWnTpvny+Exbi3bL9+PxGezDDz/05b5Mb16EB32+L7MDoTsKJCYmmvET+kEc/Obr1q2b+bDQcT/BFi5caNWuXTvb/zhnVKd2O5k9e7YZBxL8gacfhHXq1DHdV7LT0aNHz6pFDRkyxIypev/990O+/OrkJtqVJrv/8GVUp37pWbp0aWC/2dd98sknZhzQ4cOHs7XOpKQka+3atea405pt3bt399XxmVGd2p3PT8fnrl27zJcaPXGh47v8uj8zqtNv+1Mnqmnfvr21ePHikO06bs5P+zOjOvWY9dP+XL9+vRUbG2t+Bv9d8tv+zKhOv+3P7777zrr88svN+0j/RtkGDx7sq8+jjOrctm2brz6PtE7tpl2xYsWQIO234zO4zgMHDvj2+NTvGzp5Vs+ePa1Ro0b59vjMqE7tqu2X41NDqR5v+rn5ww8/BLYPHDjQV/syozq3bNnim33pFUJ3hNMzdTqbYaNGjcy4noYNG1q9e/cOjFW67bbbrHz58lnvvPOOtWPHDrNNZ76sW7eu9eeff3paZ/A4lbQtOOrRRx+1OnfubCY6ya6ZOfUMXdu2bc0fE/sPh/3hpnTclH5RGzFihAkSR44cMduqVKkS8sHoRZ3BXxzT21/6uuvkMMGBMjte9+rVq5vjLSYmxrrhhhvMNqVfeO666y7fHJ9p69QvPbbgfevl8al1JiQkWC1atLDi4+PNTw0NSo8/Hffnl/2ZUZ0qvUl/vNif+jh6clJr1MmUggOtfXxqK4PX+/Ncdfrp+NQvgRpc+vXrd9Z1Bw8eNDNC++H4TK/O4H2UXnDxYn9qUChWrJj12GOPpft3+/HHH/fF59H56jx58qQvPo/s2b/1vaStwq+88krI8emXz6O0db766qu+fL/r33kdU37rrbeaGbV1bLz2urLpvvPD8ZlendqDwRb8Hc+r41O/b+h3ZP1epydbmjRpYl5/v73X06vz3nvvPed3+Sc8eK97hdAdwfSskX4Y6JtR//+3334zb0g986VfzIIPeH1zVKhQwYRd/XAM/gLsVZ21atUy4Sa9s2h6llS/YG7evDnb6tQP2WrVqpluMFdddZU5O5deoB03bpw5a6f7VJ9X6dKls3V/ZrZOm3ZL/Ne//mU+vLULUHZ+EStTpox5LfVMrJ5RLl++vPliZtMvCHoW18vjM6M69XhNj1fHp9alx9rTTz9t9pvWoftNu5/Z9MuW1+/3jOqcPn26r/anTSek0WWCOnXqZLVu3TrQxdT+AjFgwABP92dGdWpLg5/2p/5t0aCgPYKCuxvrl7Tgkyza2uTl/syoTv1inl7Y9vL41Peynqiw39v6XtegqKHQNmbMGE8/jzJbp9efR/aSRvp5Y7+f9PNTv4/46fMoozp///33dG/v1fGpQU9b1nUSLaXf7bRr8dixY0Nup93jvTw+M1unfaLCi+NTe4boSf9BgwaZv0F6wnfo0KGmAUB7N/nlvZ7ZOr1+r3uJ0B3BtPumdudatWpVYJueSdLu27pdz+rZvvrqKzP+44MPPjChzS91Vq1aNaRO/QOiy3RUrlzZfPhkFz3TqWO8dLZSreG6664zM0MGB9rgL44a1JYtW2a+oAd/aPuhzuCz3NrdR2+j+zk796d+eXnooYdMl2dt5bD33eTJk81JobRn43WIgRfH5/nq1NAVXKe2QHhxfB4/ftx0f9QxU3oM2DXdcsst1siRI61nn302JNRqF0kv9uf56tQlRYLrXLdunSf7M5j2FtHxkF9//bU5e69n5LUu/bJoj0Hz6vg8X526z7RO/Rvr5fGpf8+bN29uvlzZtNVNW5T0C5nWFNyq6NXn0fnq1B4ZL7/8cuA63YdeHp/6vrHr0RYlncn40ksvNRftNWafZNWeT158HmWmTj1RZNepJza8+DzSk6kaSu0gq/Qzs1ChQqY7bNoT1l693y+0Tq/e70r/RurJ/+C5Bu677z7zftIeV/q5avPy+Dxfndrd3KYnCL04PleuXGnVq1fP2rNnT8g+095iun68niQIHq7h1b48V516IuDGoMY+PQHkxb70GqE7gukkMPrH9sUXXwzZrkFBzzDrOCQdX+X3OvUspIYcm477TjtJiNs0HOgfZz0RoDTABgdau3uc12thZrbO4KCofyjtL+XZ+eVWP9imTJkSsv3TTz81rcrJycmmxvRa5v1YZ7B58+Zl+/GpS8Z8/vnn5kuWTQOsBgX94qAtIfp+D+5F4IXM1hncrdeL93swHR+pdSnttq0tyeXKlTM1Z9S65Lc6g8fQerE/9eSVjje87LLLrI4dO5qTAvoFTIOLngDSbrsaEqdOnZqtdWWlziuvvNJ67733fHF8ao3690nH6+pJFu0CrRddwkpbnNLrKebHOnV5K5uefM/uzyMNzum1umtd11xzTaBLrNefR5mtM5hXx6f2aNLeALpuuJ5g1b/zOqmX9gzSXmIatuy/V17KTJ3NmjXz9PhctGiRGbuv4/VtGlT1b9H48eNNo5WedPVaZur86KOPPN2XXiN0RzD9A6xjPnQmS3ucbHCLk7aG3nHHHZbXwqXOtIFav6DZgXbmzJmBcT9er4uY2TpnzZpleSn4bKhds34J02EFwUE27UyX2S1c6gweF6ln5HXsoX0s6pdF/RKh3SG1q2w41BkcFL2kLQfaGmfTrttas7bY6WzBfuH3OvWEi4ZXPcHatGlTa+/evYHrdBKqf/zjHybUei0c6rTDnwYwfZ317/szzzwTchvtMaJdTb2cufhC6gxuafSixmD233U92aqt8fba116G7nCp06ZjirXLtp7409ddg6ye+Ldpy7x2f9ZW2XCo0+5J4AUNppUqVTLfk/X9og0l2uNBh2gpDbX6uem1cKnTS4TuCKfjJHRSA50wLe2H2ksvvWRdccUVJth6LVzqTBu+tCb9Q60hQVuXH374Yats2bIhQc3PdfqhpS74C4Ke+dSzzseOHTO/63gfbRnxw6yW4VKnzT4G7bp1SRE/zhDq9zq1Lm1F0q7kXbt2Ne8bnWRHW++0dVaXjfODcKhTTwDOmTPHmj9/fuBvk/1TJ87U+v0QGMKlTv2Sq93htTeDvubB9PXWVrqdO3daXguXOtNrELjkkkus+++/3/Izv9apPcH0pI++xnqSOu0s69qjRHvmec3PddonVnRyNO31qa+zzikTHF5vv/1201PMS+FSp9dyeL1OONyTmpoqtWrVks8++0xatWplfn/kkUekRYsW5voff/xRypcvLzlyeHsYhEudweLi4uTMmTOSL18++fzzz6Vjx45y9913S86cOWXlypVSpkwZCYc6y5Yt63WJEhsbG/j/U6dOydGjR81rPXToUBkzZoysXr1a4uPjxWvhUqetdOnSIXVv2rTJvM9y584tfuLnOvXEtL5/9GfTpk1NjXPnzpV69epJxYoV5d1335VKlSp5XWbY1Jk3b1657rrrTH36t0nZPw8ePGjqDX6feSUc6tTXukKFCvL666/LHXfcYV7vUaNGyaBBg+TkyZOyZMkSKVasmBQqVIg6syAlJcX8Derfv7+MHTtW1q1bJw0aNBC/8XOdBQsWNBf9Tqc1/vDDD3L11Veb6/T7XoECBaRcuXJel+nrOmNiYkxdjRo1kkWLFpn3zPHjx6VatWrmev27n5ycLM2aNfOkvnCr03Nep35cPD3jnrZLsX0W3t6uZ+t0ggNtMdZZDW+++WYz+Ubw2ErqPH+dadm305ZjnSgiO2cHjcQ6dYIabZXTGYx13cngsUFui8Q67V4O2hJfokQJ377ufq9Tx/lq1+20r7Pd0yE7RFKdaVuV9XXXORJ0fGV2iYQ67Z86tEAnK9MJi7Q+bYnXv/PZOUFRJNSZHh02lCtXrpAJ9LJDJNWpQ5q0l532ttPejNoirxOA+e1197rOc9WY3jJv2lNRu27rcmc6eW92CZc6/ShG/+N18EfWbd26VZ5//nlJSkqSKlWqyI033ijt27cPnAHVs/P2z927d5uzoEuXLpWEhAS56aabAmehqDPzdaY1YcIEefTRR03N9evXp86LqHPVqlXmTGiRIkXM2dIrrriCOi+iTu3dMHPmTPNe0jP2fn3d/V7n6dOnzVn7woULm9/1Y1PP7GeXSKvTNmvWLJkxY4YsX77ctID67XUPhzq1dUlb3f/44w/57bffZP78+aZluXHjxnLppZdS5wXWmZ5///vf5rY1a9akzgus0/4bpK3Hr7zyiuzcudP0vnnsscekevXq1HkBNQbbsWOHvPnmmzJlyhTf/U3yQ51+RegOY9u2bTMfWO3atTNdB/VDTLsNaxgYN25coBtsrly5sv3LV6TXGezAgQOm20x2fXGI5Dr1g+62226TqVOnSo0aNajzIuvctWuXCbN64srPr7tf69QucsHd3O3gkJ0iqc703kfvv/++3H777eYLHHVeXJ1eiOQ6zxVwqTPzddp/j/7++28zdENPDuptqfPCa7TpyVX9dyVKlDCNU9khXOr0Na+b2pE12oVDu7ppF5jgySCee+450z27R48eZy1x5MWsxZFap862vH//fup0sE57luD0lj2hzqzXmZ0TPkVyneHyPgqXOu3XPTuXWYzkOsPldafO6Ksz7fe69LogR2udWXnNw+U7stcrpfiR9zOWIEu0NXjPnj2mi4dNJ4LQ7sM6UdaGDRtk9OjRZrt26ejdu7fpMqNn8qjz4uvs1auXvPzyy9TpYJ2vvvqqOWOfnS0ikV6nvu7Z2XMkkusMl/dRuNRpv+7Z2SIfyXWGy+tOndFXZ9rvddn1tz4c6szKax4u35G9qNPvCN1hyB4RoONI9cu/dt0IfhPcf//9ZtzE7NmzTVcPHW+h2/SSnV8cqJM6L6TO7t27my5y2fWBHA116utOndH1PgqXOsPldQ+XOsPldadO6qTO8KkxnOoMC143tSPrdD1rnQ1QZ1g8evRoSHcYXatV18ScPXu2x1VSp9Oo01nU6SzqdBZ1Oos6nUWdzqLO6KszHGoMpzr9jNAd5pYuXWqWLOrVq5d14MCBwHYdh6ZLbq1atcryA+p0FnU6izqdRZ3Ook5nUaezqNNZ1Bl9dYZDjeFUp18RuiPA559/bt4EnTt3tqZPn27Waxw4cKBZBzMxMdHyC+p0FnU6izqdRZ3Ook5nUaezqNNZ1Bl9dYZDjeFUpx8RuiPEunXrrObNm1sVK1a0Lr30Uuvyyy+31q9fb/kNdTqLOp1Fnc6iTmdRp7Oo01nU6SzqjL46w6HGcKrTb1inO4LoGsyHDh2So0ePSpkyZaR48eLiR9TpLOp0FnU6izqdRZ3Ook5nUaezqDP66gyHGsOpTj8hdAMAAAAA4BLmcgcAAAAAwCWEbgAAAAAAXELoBgAAAADAJYRuAAAAAABcQugGAAAAAMAlhG4AAAAAAFxC6AYAAAAAwCWEbgAAAAAAXELoBgAA6dq5c6fExMTIxo0bvS4FAICwRegGACBK3XvvvSZU25dixYrJ9ddfL99//725PiEhQfbu3Su1atXyulQAAMIWoRsAgCimIVuDtV6WLFkiOXLkkBtvvNFcFxcXJ6VLlzbbAABA1hC6AQCIYrlz5zbBWi/16tWTgQMHSmJiohw4cOCs7uXLly83v2s4b9iwoeTLl0+uuuoq2bZtm9dPAwAA3yJ0AwAA49ixY/L+++/LZZddZrqaZ+Tpp5+Wl156SdauXWtawe+///5srRMAgHBCfzEAAKLYnDlzpECBAub/jx8/LmXKlDHbYmMzPi8/cuRIad68ufl/bRlv3769nDhxQvLkyZNtdQMAEC5o6QYAIIq1aNHCdB/XyzfffCNt27aVdu3aya5duzL8N3Xq1An8v4Z0tX///mypFwCAcEPoBgAgiuXPn990J9dLo0aN5M033zQt3m+88UaG/yZnzpyB/9cx3io1NTVb6gUAINwQugEAQEiI1q7lf//9t9elAAAQERjTDQBAFDt58qQkJSWZ///zzz9lwoQJZkK1Dh06eF0aAAARgdANAEAUW7BgQWBcdsGCBaVatWoyY8YMufbaa82SYQAA4OLEWJZlXeR9AAAAAACAdDCmGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAAAAAcAmhGwAAAAAAlxC6AQAAAABwCaEbAAAAAACXELoBAAAAAHAJoRsAAAAAAJcQugEAAAAAEHf8L6qfN8v/SQz9AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "try:\n", + " import matplotlib.pyplot as plt\n", + "\n", + " # Get the latest daily metric for conv_rate\n", + " latest = metrics[0] if metrics else None\n", + " if latest and latest.get(\"histogram\"):\n", + " hist = latest[\"histogram\"]\n", + " bins = hist[\"bins\"]\n", + " counts = hist[\"counts\"]\n", + "\n", + " fig, ax = plt.subplots(figsize=(10, 4))\n", + " ax.bar(\n", + " [f\"{bins[i]:.2f}\" for i in range(len(counts))],\n", + " counts,\n", + " color=\"steelblue\",\n", + " edgecolor=\"white\",\n", + " )\n", + " ax.set_title(f\"conv_rate distribution — {latest['metric_date']}\")\n", + " ax.set_xlabel(\"Bin\")\n", + " ax.set_ylabel(\"Count\")\n", + " plt.xticks(rotation=45)\n", + " plt.tight_layout()\n", + " plt.show() # pragma: allowlist secret\n", + " else:\n", + " print(\"No histogram data available.\")\n", + "except ImportError:\n", + " print(\"Install matplotlib to visualize: pip install matplotlib\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 8: Time-Series Trend\n", + "\n", + "Plot how a metric (e.g., `mean`) evolves over time." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 data points from 2025-01-01 to 2025-02-28\n", + " 2025-01-01: mean=0.4989, null_rate=0.0000\n", + " 2025-02-28: mean=0.5201, null_rate=0.0000\n", + " ...\n" + ] + } + ], + "source": [ + "timeseries = monitoring.get_timeseries(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " feature_name=\"conv_rate\",\n", + " data_source_type=\"batch\",\n", + " granularity=\"daily\",\n", + " start_date=date(2025, 1, 1),\n", + " end_date=date(2025, 3, 1),\n", + ")\n", + "\n", + "if timeseries:\n", + " dates = [t[\"metric_date\"] for t in timeseries]\n", + " means = [t[\"mean\"] for t in timeseries]\n", + " null_rates = [t[\"null_rate\"] for t in timeseries]\n", + "\n", + " print(f\"{len(timeseries)} data points from {dates[0]} to {dates[-1]}\")\n", + " for t in timeseries[:5]:\n", + " print(f\" {t['metric_date']}: mean={t['mean']:.4f}, null_rate={t['null_rate']:.4f}\")\n", + " print(\" ...\")\n", + "else:\n", + " print(\"No time-series data.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAepVJREFUeJzt3Ql4lNX59/F7Jvs2gewsYacKiqyCoK0bLRSrolgBrSAiWlusihuogOBC3RFFsfXvVhdwodatvLVoqxZURK2IQmVfsxGSyb7NvNd9JjMkmQEDSSZ5Jt/Pdc01mWfOTM4kD8jz8z73sbndbrcAAAAAAAAAQWQP5jcDAAAAAAAAFKEUAAAAAAAAgo5QCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAJrNnXfeKTabrd6xHj16yOWXXy7txb/+9S/zM9B7AABweIRSAAAATbRmzRoTxhQUFIiVgiPvLTY2Vrp16ybnnnuuPPvss1JRUSFt0RlnnFFv3oe76ecDAABtX3hrTwAAACAUQqkFCxaYaqAOHTqIVTz55JMSHx9vQqi9e/fK//t//0+uuOIKWbx4sbzzzjuSmZl51O95xx13yOzZs1tkvrfffrtceeWVvsfr1q2TJUuWyG233Sb9+vXzHT/ppJNa5PsDAIDmRSgFAADQQElJicTFxUmou+iiiyQlJcX3eN68efLSSy/JlClT5Ne//rV8+umnR/2e4eHh5tYSfv7zn9d7HB0dbUIpPa5VVO399wkAgNWwfA8AADSZVtlMnz5dOnfuLFFRUdKzZ0+55pprpLKy0jdm27ZtJuhISkoyy8VOOeUUeffddwP24nn11Vflnnvuka5du5rg4eyzz5YtW7b4xs2cOdNU+JSWlvrNZfLkyZKRkSE1NTVHtZTtu+++k0suuUQ6duwop512mnnum2++MdVPvXr1MvPQ99VKogMHDtR7/c0332y+1s/tXUK2Y8cO35gXX3xRhg4dKjExMebzT5o0SXbv3i1t0aWXXmqqkT777DN5//33fcc//vhj8/vTZX76O9YqqhtuuEHKysp+tKdUXXoe6POPPPJIwIozfe6VV1455vkf6ffZ2N+FBlwnnniieY8zzzzTnK9dunSR+++/3+/77dmzR8aPH29Cr7S0NPMzaavLHwEAaGuolAIAAE2yb98+GT58uOmndNVVV8nxxx9vQqrXX3/dhEaRkZGSnZ0to0aNMo//8Ic/SHJysjz//PNy3nnnmXEXXHBBvff84x//KHa7XW666SYpLCw0YYCGJRqUqIkTJ8rSpUtNqKVBiZe+/9tvv22CpLCwsKP6HPo+ffv2lXvvvVfcbrc5pqGMhijTpk0zgdTGjRvlT3/6k7nXKiINPy688EL53//+Z4IUDVq8lUepqanmXsO1uXPnysUXX2zCntzcXHnsscfkZz/7mXz11VdtcrnfZZddZj7nP/7xD1910muvvWZ+vho26u/v888/N59DQxl9rrE04Dv11FNNRZYGOHXpsYSEBDn//POb/BkC/T6P5ndx8OBBGTt2rPn96ng9T2+99VYZMGCA/PKXvzRjNJDTwHTXrl3mvNZQ9i9/+Yt88MEHTZ4/AADtghsAAKAJpkyZ4rbb7e5169b5Pedyucz99ddfr6mA++OPP/Y9V1RU5O7Zs6e7R48e7pqaGnPsww8/NOP69evnrqio8I199NFHzfENGzb43rdLly7uCRMm1Pt+r776qhn30UcfNXr+8+fPN6+ZPHmy33OlpaV+x1555RW/7/HAAw+YY9u3b683dseOHe6wsDD3PffcU++4fo7w8HC/48Hi/cy5ubkBnz948KB5/oILLjjiz2LRokVum83m3rlzp99719W9e3f31KlTfY+feuopM+b777/3HausrHSnpKTUG/djXnvtNfM+et782O/zaH4Xp59+unmPF154wXdMz8eMjIx659zixYvNOD3vvEpKStx9+vTxmxcAAPDH8j0AAHDMXC6XvPnmm2bXtmHDhvk9713G9d5775lqqrrLqHT5nVZW6TI3XSZVl1YmaYWV109/+lNzr1VL3vfVShh93+LiYt+4FStWmGVWdb9PY/32t7/1O6ZLvLzKy8slLy/PLDtUX3755Y++58qVK83PSCtt9LXem1ZdaRXPhx9+KG2R/m5UUVFRwJ+F9mjSz6HVb1qFpFVGR0N/HrocUiujvLTJur7nb37zm2b5DA1/n0f7u9CfQd256Pmo57D3HFR6/nXq1Mn05vLSpX56XgMAgB/H8j0AAHDMdPmT0+k0/XeOZOfOnTJixAi/494d0/T5uu+hfYvq0r5A3iVVXrqET3eJe+utt0zvIA2nNCS4+uqrj9jT6HC0H1RD+fn5Zle95cuXS05OTr3ndFnhj/nhhx9MaKOhRyARERGHfa3249Lvfyw0QNF+ScfKG/TpUjovXaKmjdD1513399DYn0VdukxOg8yXX35Z7rrrLnNMAyoNFM866yxpDg1/n0f7u9B+Zg3PIz0Ptc+Yl563ffr08Rt33HHHNcMnAAAg9BFKAQCANudw/aC8vYGUViz16NHDNEXXUEp7SWmPHw2rjkXdSiAvrarR5tvayHzQoEGmekarbbTXkN7/GB2jgcXf//73gJ/JW5EUiH5fbbJ9LE4//XTTNP5Yffvtt+ZeAxelTeO1t5SGZNpXSfuGaWNv7R2m/bsa87NoSHf4015U+jm1T5OGXb/73e9ML7Hm0PD3ebS/i8acgwAAoGkIpQAAwDHTZt4Oh8MXYhxO9+7dZfPmzX7HN23a5Hv+WGho9Oijj5pqLV26pyGVd3ldU2k10OrVq02llFYI1a24aehwlVm9e/c2IYZW7fzkJz85qu8/cODAervfHQ1vZdmx0mbdasyYMeZ+w4YNppm7NqfXMMnrWOenNNjT80crpLSKTpuoa4P1ltKU38Xh6Hmr576+b91zINC5DgAA/BFKAQCAY6ZVLePHj5cXX3xRvvjiC7++Ut6L9XHjxpmldmvXrpWRI0f6+hLpDm8aJPXv3/+Yvr9WRenOfBqWrFq1Sq677jppLt5KmYaVMfo5GtKqIaU7ENalO7fNmTPHBFv6M6obXOj7auWR7mR3uGBp9OjREmy6pO7pp582vyfdWe5wPwv9WgPBYxUeHi6TJ0823+/777831VInnXSStJSm/C4OR89r3aFQd+bz7gKp4Zqe1wAA4McRSgEAgCa59957zYW5LhnTBs/aJ2r//v1madYnn3xi+gfNnj1bXnnlFfnlL38pf/jDH0y/Iw2Stm/fLm+88cYxL9kaMmSIWWJ2++23S0VFxTEv3QtEK8B+9rOfmdCrqqrK9DvSz6lzbmjo0KHmXucxadIk059IeyZpdc7dd99twhBt6K4BnvZp0vf461//an5eN910k7QWDVN02Zr2r9KleNps/D//+Y+p0tLfn5cu19PPonPVcfqz0d9bw95SR0urrpYsWWKajN93333SklridzFjxgx5/PHHzedYv369aXquVWba7BwAAPw4QikAANAkGtZ89tlnMnfuXLMUS5fS6TENoLwX5+np6aZ3kPYjeuyxx8xOdloVo32gzjnnnCZ9fw2i7rnnHhNOaUjVnLSK59prr5WlS5eaappf/OIXpidR586d6407+eSTTcPuZcuWmYot7V+kYYdWUGkgp8vFHnnkEVOlozIzM817nXfeedKarrnmGnOvO+GlpKSYvlnPPPOM6dEVFRXlG6chm/6uNFBctGiRGX/BBRfIzJkzTYB1rDTMO+GEE0yl1KWXXiotrbl/F3p+6xJPPUf0vNbH+jn03NfliQAA4Mhsbro1AgAAoJUMHjzYVM5puAMAANqX5tneBAAAADhK2ofs66+/rtc8HQAAtB9USgEAgJBUXFxsbkeiu795m3gjeHTHOu3B9NBDD0leXp5s27bNLAkEAADtC5VSAAAgJD344IOm8fSRbrt3727tabZL2mB92rRppoG8NsAnkAIAoH2iUgoAAIQkrb7R25GcdtppBCIAAACthFAKAAAAAAAAQcfyPQAAAAAAAARdePC/ZehxuVyyb98+SUhIEJvN1trTAQAAAAAAaDW6KK+oqEg6d+4sdvvh66EIpZqBBlKZmZmtPQ0AAAAAAIA2QzeV6dq162GfJ5RqBloh5f1hOxwOsWq1V25urtka+0gpJgAAAAAAaBmuELk2dzqdpnjHm5ccDqFUM/Au2dNAysqhVHl5uZm/lU98AAAAAACsyhVi1+Y/1uLI+p8QAAAAAAAAlkMoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAACgfYdSS5culR49ekh0dLSMGDFCPv/888OOfe6550zDrLo3fZ1XVVWV3HrrrTJgwACJi4uTzp07y5QpU2Tfvn313ic/P18uvfRS00SsQ4cOMn36dCkuLm7RzwkAAAAAANBQrrNMvt9XZO7bgzYTSq1YsUJmzZol8+fPly+//FIGDhwoY8aMkZycnMO+RoOk/fv3+247d+70PVdaWmreZ+7cueZ+5cqVsnnzZjnvvPPqvYcGUhs3bpT3339f3nnnHfnoo4/kqquuatHPCgAAAAAAUNeqr3bJ1Mf/JX9893/mXh+HOpvb7XZLG6CVUSeffLI8/vjjvm0QMzMz5dprr5XZs2cHrJS6/vrrpaCgoNHfY926dTJ8+HATXnXr1k2+//576d+/vzk+bNgwM2bVqlUybtw42bNnj6muagyn0ymJiYlSWFhogjIr0p+3BoBpaWkhse0kAAAAAABtXWV1jWzLLpKvt+fJsx9urvec3WaTF/5wpqQ6YsRqGpuThEsbUFlZKevXr5c5c+b4jmkwMnr0aFm7du1hX6fL7Lp3724ClSFDhsi9994rJ5xwwmHH6w9Dl/npMj2l761fewMppd9Tv/dnn30mF1xwQcD3qaioMLe6P2yl89CbFem8NZ+06vwBAAAAAGjLyiurZVtOkWzZ75QtWYWyJcspO3OLxXWYWiE9vvdAsSTHR4nVNDZbaBOhVF5entTU1Eh6enq94/p406ZNAV9z3HHHyTPPPCMnnXSSCZsefPBBGTVqlFmK17VrV7/x5eXlpsfU5MmTfSldVlaWqQyqKzw8XJKSksxzh7No0SJZsGCB3/Hc3FzzfaxITxj9OWowRaUUAAAAAADHrqyyRnYeKJUdeaWyM89zv7+wXALlTwnR4dKlQ7Rsyqrf39puE4msKTtiW6O2qqioyDqh1LEYOXKkuXlpINWvXz956qmn5K677qo3VpueX3zxxSZwefLJJ5v8vbWiS/tf1a2U0qWGqampll6+p1Vk+hkIpQAAAAAAaJyisipT+bQ1SyugPFVQe/NLA45Nio+SPhkO6ZOR6Lnv5JCUhGhzPf7/vt4tS977VlxuTyD1h3EnyvG9/IturKDuRnRtPpRKSUmRsLAwyc7OrndcH2dkZDTqPSIiImTw4MGyZcuWgIGU9pH64IMP6oVG+t4NE8fq6mqzI9+Rvm9UVJS5NaRhjpUDHf1DYPXPAAAAAABASykoqfAET/sL5Yf9ugSvULIKAu+Ul5YY4wug+nZKlN4ZDklOOHxY88sh3WVIrxT5bts+6d+rs6R3iBOramyu0CZCqcjISBk6dKisXr1axo8f76vc0cczZ85s1Hvo8r8NGzaYJuUNA6kffvhBPvzwQ0lOTq73Gq200kbp2s9Kv7/S4Eq/tzZeBwAAAAAA7dOBonJP76f9Tl8AlesM3LKnU8dYE0Bp+KQhlAZQHeKOvhdUqiNG+nVOsGRz82PRJkIppcvhpk6dapqO6w55ixcvlpKSEpk2bZp5fsqUKdKlSxfTz0ktXLhQTjnlFOnTp48Jlh544AFTDXXllVf6AqmLLrpIvvzyS3nnnXdMaOXtE6U9ozQI0+V+Y8eOlRkzZsiyZcvMazQEmzRpUqN33gMAAAAAANalrX40bNLQyRM+eSqh8osPbXBWV9ekOOmj4VMnh/Q1AVSiJMREBH3eoaDNhFITJ040jcLnzZtnwqNBgwbJqlWrfM3Pd+3aVa/86+DBgyZM0rEdO3Y0lU5r1qyR/v37m+f37t0rb731lvla36surZo644wzzNcvvfSSCaLOPvts8/4TJkyQJUuWBPGTAwAAAACAYAVQ2QVlJnz6IetQAFVYWuk3Vvs6dU2O91Q/dfIsweuVniBxUQRQzcXm1t8ImkQbnScmJprd66zc6Fz7a+luhPSUAgAAAABYncvtlv35pb6ld9774vJqv7Fhdpt0T02obT5eG0ClJUh0ZHBreVwhcm3e2JykzVRKAQAAAAAAHIsal1v2HCg2VU9a/aQBlO6GV1rpH0BFhNmlR5ongPJWQfVMS5DI8LBWmXt7RigFAAAAAAAso7rGJbvyig9VP+13ytZsp1RU1fiNjQy3S690bwNyz0543dMSTDCF1kcoBQAAAAAA2qTK6hrZmVvsW3qnAdS2bKdU1bj8xkZHhJld77w74Ol9ZkqchFl4GVyoI5QCAAAAAACtTiudtufo0jtnbQBVKDtyiqTa5d8KOzYq/FD/pwzPErwuSRpA2Vpl7jg2hFIAAAAAACCoyiqrTcWTBk/eEEororQ5eUMJMRGm8qluD6hOHWPFbiOAsjpCKQAAAAAA0GJKyqtMzydP/ydPI/LdecXiHz+JJMZGmuDJ1wOqU6KkJ8aIjQAqJBFKAQAAAACAZuEsqzS73nkDqB+yCmVffmnAsckJUb6ld94eUHqMAKr9IJQCAAAAAABHraCkorYBee0yvKxCyS4oCzhWq518PaA6JZqG5Enx0UGfM9oWQikAAAAAAHBEB4rKfQGUdye8PGd5wLHa78lb+dSnk8N8rcvygIYIpQAAAAAAgOF2uyXXWV7bgNwTPmkQlV9c4TdWF9l1SY7zC6DioyNaZe6wHkIpAAAAAADaaQCVVVBWpwG5J4AqLK30G2u3iWSmxNc2IPf0geqd7pDYKGIFHDvOHgAAAAAAQpzL7ZZ9+SX1ekBpCFVcXu03Nsxukx6pCb7KJw2ieqY7JDoirFXmjtBFKAUAAAAAQAipcblld16xr/JJg6itWYVSVlnjNzYizC490zSAql2Cl+GQHmkJEhlOAIWWRygFAAAAAIBFVde4ZGeuJ4Dy9oDaluWUimqX39iocLv0SnfUC6C6pSaYYApoDYRSAAAAAABYQGV1jQmgNHzyBlDbs4ukqsY/gNKldr0zHL4eUHqfmRInYXYCKLQdhFIAAAAAALQxFVU1si3b6VmCt9+zBG9HbpFZmtdQXFS4qX7SyidvAKW74tltuj8e0HYRSgEAAAAA0IrKKqtlqzYf9y7B2++UXXnFpjl5QwkxEfWqnzSIyugYSwAFSyKUAgAAAAAgSErKqzy73/kCqELZc6BE/OMnkQ5xkSZ46puR6KuESkuMERsBFEIEoRQAAAAAAC3AWVrp2/3OsxNeoezLLw04NiUh2tOAPONQI/Kk+CgCKIQ0QikAAAAAAJqooKSiTgNyp6mAyi4sCzg2PTHGV/nkXYrXMT4q6HMGWhuhFAAAAAAAjeR2uyW/2BNAbakTQuUVlQcc3zkp1oROdXtAOWIjgz5voC0ilAIAAAAA4DABVE5hma/y6YfanfAOllT4jdVFdl2T43xL7zSE6p3hkPjoiFaZO2AFhFIAAAAAgHZPA6j9B0vr94DaXyjOsiq/sXabSLeUBE/41MnhC6BiIrnEBo4Gf2IAAAAAAO2Ky+2WvQdK6jQg91RClVRU+40Ns9ukR2r9AKpnukOiI8JaZe5AKCGUAgAAAACErBqXS3bnHQqg9H5btlPKKmv8xkaE2aVneoKv/5PeuqfGS2Q4ARTQEgilAAAAAAAhoarGJbtyiw4twasNoCqqXX5jo8Lt0ivDU/nk7QGlAVR4mL1V5g60R4RSAAAAAADLqayukR05Rb7d7zSA2p5TZIKphmIiw6R3nd3vNIDKTIk3S/MAtB5CKQAAAABAm1ZeVSPbs+s2IHfKjtwiqXG5/cbGR4eb0KlPbQClQVTnpDix2wiggLaGUAoAAAAA0GaUVlTL1mxP5ZO3B9TuvGIJkD+JIybCt/TO04g8UTI6xIiNAAqwBEIpAAAAAECrKC6v8lU+eaugdFe8APmTdIyLkr61u995A6hURzQBFGBhhFIAAAAAgBbnLK2UH0wApdVPThNA7T9YGnBsiiO6TgNyzxK85ITooM8ZQMsilAIAAAAANKuDxRW+pXcmhMpySk5hWcCx6R1ipG+DHlAd4qKCPmcAwUcoBQAAAAA4Jm63Ww4UVdRpQK4BVKE5FkiXpDjP7nedPFVQvTMc4oiJDPq8AbQNhFIAAAAAgEYFUNmFZbUNyA/1gCooqfQbq12eMlPifZVPGkL1TndIXHREq8wdQNtEKAUAAAAAqMfldpt+T57+T54QSgOoorIqv7F2m026p2oApdVPniqoXukOiYnkchPAkbWpvyWWLl0qDzzwgGRlZcnAgQPlsccek+HDhwcc+9xzz8m0adPqHYuKipLy8nLf45UrV8qyZctk/fr1kp+fL1999ZUMGjSo3mvOOOMM+fe//13v2NVXX21eBwAAAAChrsbllr35Jb6ld3q/NcspJRXVfmPD7TbpkZZQ2//JE0L1THNIVERYq8wdgLW1mVBqxYoVMmvWLBMGjRgxQhYvXixjxoyRzZs3S1paWsDXOBwO87xXw61AS0pK5LTTTpOLL75YZsyYcdjvrc8tXLjQ9zg2NrZZPhMAAAAAtCU1Lpfsyi32VT79UBtAlVfV+I2NCLObiqc+Wv1UuxOeVkRFhhNAAQixUOrhhx824ZC3+knDqXfffVeeeeYZmT17dsDXaAiVkZFx2Pe87LLLzP2OHTuO+L01hDrS+wAAAACA1VTVuGRnTtGhXfCynLIt2ymV1S6/sVrp1Ls2gDI9oDISpVtKvISH2Vtl7gDahzYRSlVWVpoldnPmzPEds9vtMnr0aFm7du1hX1dcXCzdu3cXl8slQ4YMkXvvvVdOOOGEo/7+L730krz44osmmDr33HNl7ty5VEsBAAAAsIzK6hrZrgFUnR5QO3KKTDDVUGxkuNn1zhM+eXpAdU2OlzB7/ZUnANAuQqm8vDypqamR9PT0esf18aZNmwK+5rjjjjNVVCeddJIUFhbKgw8+KKNGjZKNGzdK165dG/29L7nkEhNsde7cWb755hu59dZbzZJA7Ud1OBUVFebm5XQ6zb2GY3qzIp237qZh1fkDAAAA7YUutduerbvfeZbg6fK7nXnFpjdUQ/HR4abqScMnbxDVqWOsaU5en14L+L8eQHC5QuTavLHzbxOh1LEYOXKkuXlpINWvXz956qmn5K677mr0+1x11VW+rwcMGCCdOnWSs88+W7Zu3Sq9e/cO+JpFixbJggUL/I7n5ubWa7RutRNGwz09+bVKDQAAAEDrK6uskZ0HSmVnXqnsqL3tLywXd4D8KCE6XHqkxEr3lFjpkRxrvk5JiKzfe7e6RPJyS4L6GQC0v2vzoqIi64RSKSkpEhYWJtnZ2fWO6+PG9nqKiIiQwYMHy5YtW5o0F22yrvR9DhdK6TJDbcpet1IqMzNTUlNTTfN1q574+h8r/QxWPvEBAAAAqyour/I1IN9iqqCcsi+/RALVLyXFRx2qftJKqE4OSUmI9tv8CYC1uELk2jw6Oto6oVRkZKQMHTpUVq9eLePHj/f9IvTxzJkzG/Ueuvxvw4YNMm7cuCbN5euvvzb3WjF1OFFRUebWkJ4wVj5p9MS3+mcAAAAArKCwtNL0f6rbhHz/wdKAY1Md0b7d77w74SUnNO6CD4D12ELg2ryxc28ToZTSyqOpU6fKsGHDZPjw4bJ48WIpKSnx7cY3ZcoU6dKli1k6pxYuXCinnHKK9OnTRwoKCuSBBx6QnTt3ypVXXul7z/z8fNm1a5fs27fPPNZeUUqrr/SmS/RefvllE2QlJyebnlI33HCD/OxnPzO9qgAAAACgqfKLy03lkyd88gRQOYVlAcdmdIjx7X6nDci1GqpDnP//EAeAUNBmQqmJEyeankzz5s2TrKwsGTRokKxatcrX/FzDpbpJ28GDB2XGjBlmbMeOHU2l1Zo1a6R///6+MW+99ZYv1FKTJk0y9/Pnz5c777zTVGj985//9AVgugRvwoQJcscddwT1swMAAACwPu0Bk1dU7gmfapuQ69f5xYc2SaqrS1JcvR3wNIhKiIkI+rwBoLXY3Po3J5pEe0olJiaaZmRW7imVk5MjaWlpli4RBAAAAIJBL6OyC8rkB9P/qVB+0F5Q+wvNsryG7DaRrsnxvgBK73tlOCQuigAKQGhemzc2J2kzlVIAAAAA0Ba53G7Zn19aJ4DyVEJpY/KG7DabdE+NN5VP3hCqd7pDoiO59AKAhvibEQAAAABq1bjcsvdAsa/5uLcHVGlFtd/YcLtNeqQl1DYg9yy/65WeIJHhYa0ydwCwGkIpAAAAAO1Sjcslu3KLfZVPGkBtzXJKeVWN39jIcLv0Snf4+j/1zUiU7mkJEhFm3eU1ANDaCKUAAAAAhLyqGpfsyCnyVD7pErz9Ttme45TKapff2KiIME/4lHFoCV5mSryEE0ABQLMilAIAAAAQUiqqamR7bQDl2Qmv0ARS1S7/PZ5iI8OlT6f6AVSX5HgJ0+7kAIAWRSgFAAAAwLLKK6tla7az3g54O3OLTXPyhuKjI0wApUvvvEvwOiXFmubkAIDgI5QCAAAAYAklFVWyLcvpa0Ku93sOaADlPzYxNtJX+eTdCS89MUZsBFAA0GYQSgEAAABoc4rKqnz9n7wB1N78koBjkxOizPI73xK8Tg5JSYgmgAKANo5QCgAAAECrKiipMMGTpwG5hlCFklVQFnBsWmKMqX7yVEF5Aqik+OigzxkA0HSEUgAAAACC5kBReW0Dck8IpV/nOssDju3UMbZeANU7wyEd4qKCPmcAQMsglAIAAADQ7NxutwmbPA3IPUvw9Ov84oqA47smxZneT95G5L0zEiUhJiLo8wYABA+hFAAAAIAmB1C63M4XQNX2gSosrfQba7eJZKbE1y698/SA6pWeIHFRBFAA0N4QSgEAAABoNJfbLfvyS2SLLr8zy/A8S/CKy6v9xobZbdI9NeHQEjwNoNISJDqSyxAAAKEUAAAAgMOocbllz4Hi2gooz/K7rVlOKa30D6AiwuzSIy2htv+TwwRQPdMSJDI8rFXmDgBo+wilAAAAAEh1jUt25RX7Kp+0EmprtlMqqmr8xkaG26V3uid48lZBdUtNMMEUAACNRSgFAAAAtDOV1TWyM/dQAKX327OLpKrG5Tc2OiLM7Hrn3QFP7zNT4iTMTgAFAGgaQikAAAAghGml0/Ycp/ygPaBqQ6gdOUVS7XL7jY2NCvctvdMd8PS+S5IGULZWmTsAILQRSgEAAAAhoqyyWrZle8InE0JlFZqKKG1O3lBCTISv8skbRHXqGCt2GwEUACA4CKUAAAAACyoprzI9n8wSPFMB5ZTdecXiHz+JdIiL9C2/8/aASkuMERsBFACgFRFKAQAAAG2cs6zSNB73NCDXnfAKZV9+acCxyQlRvqV33kooPUYABQBoawilAAAAgDakoKSitgF5bRVUVqFkF5QFHJueGHOoB1SnRNOQPCk+OuhzBgDgWBBKAQAAAK3kQFG5b/ndD1meSqg8Z3nAsdrvydcDqpPDfJ0YGxn0OQMA0FwIpQAAAIAW5na7JddZXtuA3FP9pJVQ+cUVfmN1kV2X5LhDPaBqA6j46IhWmTsAAC2FUAoAAABo5gAqq6CsTgNyTwBVWFrpN9ZuE+mWkuALnjSI6pXukNgo/pkOAAh9/NcOAAAAOEYut1v2HijxBU8aRG3NKpTi8mq/sWF2m/RI9QRQ3iqonukOiY4Ia5W5AwDQ2gilAAAAgEaocblkd54ngPI2ItcAqqyyxm9sRJhdeqZpAFXbAyrDIT3SEiQynAAKAAAvQikAAACggeoal+zMLa4TQBXKtiynVFS7/MZGhdvNkru6AVT31AQJD7O3ytwBALAKQikAAAC0a5XVNSaA0vDJ2wdqe06RVNX4B1AxkWHSW5uPZxzqAZWZEidhdgIoAACOFqEUAAAA2o2KqhrZlu309IDa7+kBtSO3SGpcbr+xcVHhpvpJAyhvDyjdFc9u0/3xAABAq4dSNTU18txzz8nq1aslJydHXK76/0fpgw8+aOq3AAAAAI5aWWW1bM3yBFCeCiin7MorNs3JG0qIiTDBU1+tgqoNojp1jBUbARQAAG03lLruuutMKHXOOefIiSeeyH+4AQAAEHQl5VW+3e88VVCFsudAifjHTyId4iL9Aqi0xBj+HQsAgNVCqeXLl8urr74q48aNa54ZAQAAAEfgLK2UH2qX33mroPYfLA04NiUh2tOAPONQI/Kk+CgCKAAAQiGUioyMlD59+jTPbAAAAIA6CkoqDjUg16V4+wslu7As4Nj0DjGm71PdHlAd46OCPmcAABCkUOrGG2+URx99VB5//HH+jxMAAACOidvtlgNFFb6ld94QKq+oPOD4zkmxvt3vvEGUIzYy6PMGAACtGEp98skn8uGHH8rf//53OeGEEyQiIqLe8ytXrmzqtwAAAECIBVA5hWUNekA55WBJhd9Y/V+eXZPjPOFTnQAqLrr+vzkBAEA7DKU6dOggF1xwQbNMZunSpfLAAw9IVlaWDBw4UB577DEZPnx4wLHaXH3atGn1jkVFRUl5eXm9QGzZsmWyfv16yc/Pl6+++koGDRpU7zU6Xqu9tDdWRUWFjBkzRp544glJT09vls8EAADQ3gMo7ffkW35XWwnlLKvyG2u32aR7arwneOrkWYLXK90hMZFN/icrAABog5r8X/hnn322WSayYsUKmTVrlgmRRowYIYsXLzYB0ebNmyUtLS3gaxwOh3neq+HywZKSEjnttNPk4osvlhkzZgR8jxtuuEHeffddee211yQxMVFmzpwpF154ofznP/9pls8FAADQXrjcbrPjnYZO3gbkW7OcUlJR7Tc23G6THmkJ9QKoHmkOiY4Ia5W5AwCA4Gsz/9vp4YcfNsGRt/pJwykNi5555hmZPXt2wNdoCJWRkXHY97zsssvM/Y4dOwI+X1hYKP/3f/8nL7/8spx11lm+kK1fv37y6aefyimnnNIMnwwAACD01LhcsjuvxLf8Tu+3ZTulrLLGb2xEmF16pnsCKA2f9KYVUZHhBFAAALRnzRJKvf766/Lqq6/Krl27pLKyst5zX3755Y++Xl+jS+zmzJnjO2a322X06NGydu3aw76uuLhYunfvLi6XS4YMGSL33nuv6WvVWPo9q6qqzPfxOv7446Vbt27m+xJKAQAAiFTVuGRXbtGhHlC1AVRFtctvbFS4XXrV2f1ObxpAhYfZW2XuAAAghEOpJUuWyO233y6XX365/O1vfzOVTlu3bpV169bJ73//+0a9R15entTU1Pj1cdLHmzZtCvia4447zlRRnXTSSabi6cEHH5RRo0bJxo0bpWvXro36vtq7KjIy0vTFavh99bnD0d5TevNyOp3mXsMxvVmRzlt7Plh1/gAAoHlUVtfIjpxiT+8n0wPKKdtznFJd4/YbGxMZJr3THbUNyB3m1jU5XsLs/jsy828MAADaz7W5q5Hzb3IopU3B//SnP8nkyZNN8/FbbrlFevXqJfPmzTPNxVvKyJEjzc1LAylddvfUU0/JXXfdJS1p0aJFsmDBAr/jubm59RqtW+2E0XBPT36tUgMAAKFPK512HyiVHXmlsjPPc7/3YJkEyJ8kNjJMeqTESne9JcdKz5RYSUuMMs3JfdxlciCvLKifAQCAUOIKkWvzoqKi4IRSumRPAyEVExPj+8baz0mXvz3++OM/+h4pKSkSFhYm2dnZ9Y7r4yP1jKorIiJCBg8eLFu2bGn03PW9delgQUFBvWqpH/u+usxQm7LXrZTKzMyU1NRU03zdqie+9ujSz2DlEx8AAARWWlFtltz5dsDLcsruvGJxBQigHDER9aqfdAleRocYv01lAABA83KFyLV5dHR0cEIpDW+0Ikp7O2kvJm0QPnDgQNm+fbtJ9hpDl9ANHTpUVq9eLePHj/f9IvSx7obXGLr8b8OGDTJu3LhGz12/p4ZZ+n0mTJhgjulufhq01a3CaigqKsrcGtITxsonjZ74Vv8MAABApLi8yhM87a/tAZVVKHsPlEigf5l1jIuSvp08S/D6mp3wEiXVEU0ABQBAK7GFwLV5Y+fe5FBKd6176623TJWS9pO64YYbTOPzL774Qi688MJGv49WHk2dOlWGDRsmw4cPl8WLF0tJSYlvN74pU6ZIly5dzNI5tXDhQlOJ1adPH1Pp9MADD8jOnTvlyiuv9L2nhmUaMO3bt88XOHmDNL0lJibK9OnTzfdOSkoyVU7XXnutCaRocg4AAKygsLSyNoDSHfA8VVD7D5YGHJviiPYFT31qm5EnJzTu/2QCAAA0tyaHUtpPytvAShubJycny5o1a+S8886Tq6++utHvM3HiRNOTSXtRaZPxQYMGyapVq3zNzzVcqpu0HTx4UGbMmGHGduzY0VQ96fft37+/b4yGZd5QS02aNMncz58/X+68807z9SOPPGLeVyultHn5mDFjTJ8sAACAtuZgcYWv8smEUFlOySkM3MNJl9uZ3e+0Aqo2hOoQ51/pDQAA0Fps7sauscNhaU8prbrSZmRW7imVk5MjaWlpli4RBAAgFOg/z/KKys3yOw2gvEHUgaJDu//W1SUpzlf5pCFU7wyHOGIigz5vAADQNK4QuTZvbE7S5Eop9fHHH5td77Zu3WqW7ukyu7/85S/Ss2dPOe2005rjWwAAAIRsAJVdWFa7/M7TgFwDqIKSSr+x2uUpMyXeL4CKi4polbkDAAA0RZNDqTfeeMPstHfppZfKV199ZZbAKU3D7r33Xnnvvfea+i0AAABCgsvtNv2eGgZQRWVVfmPtNpt0T42vbUDuaUTeK90hMZHN8v8UAQAAWl2T/1Vz9913y7Jly0wj8uXLl/uOn3rqqeY5AACA9qjG5Za9+SW1vZ88PaA0hCqtqPYbG263SY+0hNoG5J4eUD3TEiQqIqxV5g4AAGCJUEp3tPvZz37md1zXDuqueAAAAKGuxuWSXbnFvsonrYLamuWU8qoav7ERYXZT8dSnU+0SvIxEUxEVGU4ABQAA2pcmh1IZGRmyZcsW6dGjR73jn3zyifTq1aupbw8AANCmVNW4ZGdOUZ0G5E7Zlu2UymrPbsR1aaVT73Rv/yeHCaC6pcRLeJh1G5cCAAC0mVBqxowZct1118kzzzwjNptN9u3bJ2vXrpWbbrpJ5s6d2zyzBAAAaAWV1TWyPafIEz7VBlA7copMMNVQbGS4aTruqX7y9IDqmhwvYXZtTw4AAIBmD6Vmz55ttiw8++yzpbS01Czli4qKMqHUtdde29S3BwAACIryymrZ1iCA2plbZHpDNRQfHeFZfpdxqAdUp6RY05wcAAAAjWNz6z7EzaCystIs4ysuLpb+/ftLfHy8tBdOp9P00NIdBx0Oh1iRBos5OTmSlpYmdjtLCgAAoU2bjW/V5XfaA6p2J7w9B4olQP4kibGRtQ3IPVVQGkSld4gxFeIAAADNyRUi1+aNzUmOuVLqiiuuaNQ4XdYHAADQWorKqmoDKK2A8oRQe/JLAo5Nio8yAZSpgKrtAZXqiCaAAgAAaAHHHEo999xz0r17dxk8eLA0U7EVAABAkxSWVvoqn7QRuS7B23+wNOBYDZu8u995A6jkhOigzxkAAKC9OuZQ6pprrpFXXnlFtm/fLtOmTZPf/OY3kpSU1LyzAwAAOIz84vLa/k9O3054uc7ygGM7dYz1NB+v7f+kDck7xEUFfc4AAABopp5SFRUVsnLlSrNEb82aNXLOOefI9OnT5Re/+EW7KnOnpxQAAC1H/6miYZOpfNrvrF2GVyj5xRUBx3dNiqvXA6p3RqIkxEQEfd4AAADt9drc2dI9pZTusjd58mRz27lzp1nS97vf/U6qq6tl48aN7arZOQAAaJ4AKrugzARPniV4nh5QuiyvIbtNpGtyvGcJnukD5ZBeGQ6JiyKAAgAAsIImhVJ1aYKn1VH6j8mamprmelsAABCiXG637M8v9VU+eRuRF5dX+Y2122zSPfVQAKVVUL3THRId2Wz/lAEAAECQNelfcnWX733yySfyq1/9Sh5//HEZO3aspcvMAABA86pxuWXvgeJD1U+1TchLK6r9xobbbdIjLeFQBVSnROmZliCR4WGtMncAAAC0sVBKl+ktX75cMjMz5YorrjBNz1NSUpp3dgAAwHJqXC7ZmVt8qAfU/kLZmu2Uiir/SurIcLv0StcG5I7aJXiJ0j0tQSLC+J9bAAAAoe6YQ6lly5ZJt27dpFevXvLvf//b3ALRSioAABCaqmpcsiOnqDaA0j5QTtme45TKapff2OiIMLPrnXcHPA2iuqXGSxjV1QAAAO3SMYdSU6ZMaVc77AEA0N5ppdP22gDKLMPbX2gCqWqX/0a+sVHh9aqf9OsuyRpA8W8HAAAANDGU0p32AABAaCqvrDZL7jwNyD33uiRPm5M3FB8d4at88vaA6tQx1jQnBwAAAA6HLWsAAGjnSiqqZGtt8KTNx7UKandesfjHTyKJsZG+AMrbiDw9MYbqaQAAABw1QikAANoRZ1mlL4Dy7oS3N78k4NjkhKg6/Z80gHJISkI0ARQAAACaBaEUAAAhqqCkwlf55KmCKpSsgrKAY9MSYw5VP9UGUEnx0UGfMwAAANoPQikAAELAgaLy2gbk3j5QhZLnLA84Vvs9eSqgPDvh6RI8XZYHAAAABBOhFAAAFuJ2uyXXWe4LnrQSSr/OL67wG6uL7Lokx/kqn7QKqnd6oiTERLTK3AEAAIC6CKUAAGjDAZQut/MFULU9oApLK/3G2m0imSnxh3pAmQDKIbFR/KceAAAAbRP/UgUAoA1wud2yL79Etux31gmgCqW4vNpvbJjdJt1TE+otv+uV7pDoiLBWmTsAAABwLAilAAAIshqXW/YcKPbtfqcBlO6IV1rpH0BFhNmlR1pCbQNyhwmgeqYlSGQ4ARQAAACsjVAKAIAWVF3jkl153gBKK6CcsjXbKRVVNX5jI8PtZsmdBk/enfC6pSaYYAoAAAAINYRSAAA0k8rqGtmZeyiA0vvt2UVSVePyG6tL7XrXBk/ePlCZKXESZieAAgAAQPtAKAUAwDHQSqftOU75Yb9n+Z2GUDtyiqTa5fYbq83GvZVP3h5QXZI0gNL98QAAAID2iVAKAIAfUVZZLduyNYDyLL/TAEororQ5eUMJMRGHwqfaICqjY6zYbQRQAAAAQF2EUgAA1FFSXuVpPl67A54GUXsOlIh//CTSIS6y3vI7DaHSEmPERgAFAAAA/ChCKQBAu+Usq/RVPnn7QO3LLw04NiUh2rf7nTeISk6IIoACAAAAjhGhFACgXSgoqagNnmqX4WUVSnZBWcCx6YkxfgFUx/iooM8ZAAAACGWEUgCAkOJ2uyW/uDaA0uV3tUvx8pzlAcd36hhbpwG5Q/pmJIojNjLo8wYAAADaG0IpAIClA6hcZ7kvgPIsw3PKwZIKv7G6yK5Lcly9HlC9MxwSHx3RKnMHAAAA2rs2FUotXbpUHnjgAcnKypKBAwfKY489JsOHDw849rnnnpNp06bVOxYVFSXl5eX1Llbmz58vf/7zn6WgoEBOPfVUefLJJ6Vv376+MT169JCdO3fWe59FixbJ7Nmzm/3zAQCOnf6dvv9gqacJuamA8gRRzrIqv7F2m0i3lART+eQNoHqlOyQ2qk39Zw8AAABo19rMv85XrFghs2bNkmXLlsmIESNk8eLFMmbMGNm8ebOkpaUFfI3D4TDPezVsNnv//ffLkiVL5Pnnn5eePXvK3LlzzXt+9913Eh0d7Ru3cOFCmTFjhu9xQkJCi3xGAEDjuNxu2XugxLMDnrcH1P5CKamo9hsbZrdJj1RPAOWtguqZ7pDoiLBWmTsAAAAAi4VSDz/8sAmGvNVPGk69++678swzzxy2aklDqIyMjMP+H3UNtu644w45//zzzbEXXnhB0tPT5c0335RJkybVC6EO9z4AgJZV43LJ7jxPAOVtRL41q1DKKmv8xkaE2aVnWkKdBuQO6ZGWIJHhBFAAAACA1bSJUKqyslLWr18vc+bM8R2z2+0yevRoWbt27WFfV1xcLN27dxeXyyVDhgyRe++9V0444QTz3Pbt280yQH0Pr8TERFOFpe9ZN5T64x//KHfddZd069ZNLrnkErnhhhskPPzwP5qKigpz83I6neZe56E3K9J5a5Bn1fkDsIbqGpfsyis24dNW04DcKduynVJR7f93T1S43Sy50+BJez9pCNUtJV7Cw+x+Y/m7CwAAAKHAFSLX5o2df5sIpfLy8qSmpsZUMdWljzdt2hTwNccdd5ypojrppJOksLBQHnzwQRk1apRs3LhRunbtagIp73s0fE/vc+oPf/iDCbSSkpJkzZo1Jhjbv3+/qdw6HO05tWDBAr/jubm59XpaWe2E0Z+jnvwaCAJAU1XVuGRPfpnsyCuVnXml5n53fplUu9x+Y6Mj7NItOVZ6pHhu3ZNjpVOHaLM075ByyT9gzb9jAQAAgPZ0bV5UVGSdUOpYjBw50ty8NJDq16+fPPXUU6bqqbG0j5WXBlyRkZFy9dVXm+BJG6cHosFV3ddppVRmZqakpqaaPldWPfF1OaR+Biuf+ABaR3lVjWzPccrW/U75wVRAFcrO3GKpCRBAxUWFm+onXYJn7jMc0jkpTuwN+gICAAAA7Y0rRK7N6/bxbvOhVEpKioSFhUl2dna94/q4sb2eIiIiZPDgwbJlyxbz2Ps6fY9OnTrVe89BgwYd9n10eV91dbXs2LHDVGMFomFVoMBKTxgrnzR64lv9MwBoeWWV1Wbpnaf/kzYgd5oledqcvCFHTISn/1NGoi+E6tQx1m9jCgAAAAChc23e2Lm3iVBKq5OGDh0qq1evlvHjx/vSQX08c+bMRr2HLv/bsGGDjBs3zjzW3fY0mNL38IZQWtH02WefyTXXXHPY9/n666/ND+9wO/4BQHtSUl51aPe72kbkuiuef/wk0jEuSvp20sonTwClPaBSHdEEUAAAAADabiildDnc1KlTZdiwYTJ8+HCzc15JSYlvN74pU6ZIly5dzLI6tXDhQjnllFOkT58+UlBQIA888IDs3LlTrrzySvO8XgRdf/31cvfdd0vfvn1NSDV37lzp3LmzL/jShucaUp155plmBz59rE3Of/Ob30jHjh1b8acBAMHnLK2UH2orn7wB1P6DpQHHpjiiTfjUt3YZngZQSfFRBFAAAAAArBdKTZw40TQKnzdvnmlErtVNq1at8jUq37VrV73yr4MHD8qMGTPMWA2QtNJKG5X379/fN+aWW24xwdZVV11lgqvTTjvNvKd3baMuwVu+fLnceeedZjc9Da40lKrbLwoAQtHB4gpf8LTFVEE5JbuwLODY9A4xngDK1wMqUTrGB+65BwAAAACNZXNrS3c0iS4LTExMNB3yrdzoPCcnxyxbtPK6VQD16V/xB4r8A6i8osC72HVOiq0TQOkyPIc4YiKDPm8AAACgPXKFyLV5Y3OSNlMpBQBoegCVU1hW2//p0BK8gpJKv7G6yK5rcpwnfPIGUBkOiYuOaJW5AwAAAGh/CKUAwKIBlPZ7qhtAaRWUs6zKb6zdZpPuqfG+yicNonqlOyQmkv8EAAAAAGg9XJEAQBvncrtlz4GS2qV3nuqnrVlOKamo9hsbbrdJj7SEOjvgOaRnmkOiIsJaZe4AAAAAcDiEUgDQhtS4XLI7r6S2AsoTQG3LdkpZZY3f2Igwu/RMT/D1f9J7rYiKDCeAAgAAAND2EUoBQCupqnHJrtyiQ0vwagOoimqX31itdOqd7jDL77wBVLeUeAkPs27zQwAAAADtG6EUAARBZXWNbM8p8u1+p0HUjpwiE0w1FBsZLr0zNIDyNB/XAKprcryE2bU9OQAAAACEBkIpAGhm5VU1puJJAyhvFdTO3CKpcbn9xsZHhx/q/1TbiLxzUpxpTg4AAAAAoYxQCgCaoLSiWrbWC6AKZXdesQTIn8QRE+Hp/+QLoBIlo0OM2AigAAAAALRDhFIA0EjF5VW+5uNb9jvN13sPlEiA/EmS4qMOLb+rDaBSHdEEUAAAAABQi1AKAAIoLK2s7f+kIZQngNp/sDTg2BRHtC946lvbiDw5ITrocwYAAAAAKyGUAtDu5ReX+yqfvD2gcgrLAo7V5Xa+HlC1lVAd4qKCPmcAAAAAsDpCKQDthtvtlryihgFUoRwoqgg4vktSnG/3Ow2hdEc8R0xk0OcNAAAAAKGIUApAyAZQ2YVl9XbA0wCqoKTSb6x2ecpMifdVPnkDqLioiFaZOwAAAAC0B4RSACzP5Xabfk+eBuSHAqiisiq/sXabTbqnxtfugOcJoHqlOyQmkr8OAQAAACCYuAoDYCk1LrfsPVBsgqcfsg6FUKUV1X5jw+026ZGWUKf/U6L0TEuQqIiwVpk7AAAAAOAQQikAbVaNyyW7cmsDqNr+T1uznFJeVeM3NiLMbiqezO53tQGUBlJ6HAAAAADQ9hBKAWgTqmpcsjOnqF7107Zsp1RWu/zGaqVT73RvA3KHCaC6pcRLOAEUAAAAAFgGoRSAoKusrpHtGkDV9oDS+x05RVLtcvuNjY0M9wVP3p3wuiTHS5hd25MDAAAAAKyKUApAiyqvrJat2dp43OkLoHbmFpvm5A3FR0eYAKqvBlCmEXmidEqKNc3JAQAAAAChhVAKQLMpqaiSbaYB+aEAas8BDaD8xybGRtbbAU8DqPQOMWIjgAIAAACAdoFQCsAxKSqrkq1ZnuDJWwW1J78k4Nik+Chf8ORdipfqiCaAAgAAAIB2jFAKwI8qLK309X/SHfD066yCsoBjNWwyDcjrBFDJCdFBnzMAAAAAoG0jlAJQT35xeW0A5fQFULnO8oBjO3WMNc3HNXjSIKp3hkM6xEUFfc4AAAAAAOshlALaKbfbbcImDZ40gPrB3BdKfnFFwPFdk+LMEjxvI/LeGYmSEBMR9HkDAAAAAEIDoRTQTgKo7IIyEzzV7QGly/IasttEuibHe5bg1TYi75XhkLgoAigAAAAAQPMhlAJCjMvtlv35pbXhU2FtBZRTisur/MaG2W3SPTXBswRPA6hOidIrLUGiI/mrAQAAAADQsrjyBCysxuWWPQeKaxuQO00QtTXLKaWV1X5jI8Ls0iOtfgDVMy1BIsPDWmXuAAAAAID2jVAKsIjqGpfsyiv2NR/X6qet2U6pqKrxGxsZbpde6dqA3OHbCa97WoIJpgAAAAAAaAsIpYA2qLK6Rnbm1g+gtuc4pbLa5Tc2OiLM7HrnDZ80iOqWGi9hdgIoAAAAAEDbRSgFtDKtdNqeU+TrAaVL8XbkFEm1y+03NjYq/NDyOw2gOiVKl6Q40xsKAAAAAAArIZQCgqi8stosudPg6YfaHfC0IkqbkzcUHx1RW/1UWwXVKVE6dYwVu40ACgAAAABgfYRSQAspqagyTcdNAFXbiHx3XrH4x08iibGRfgFUemKM2AigAAAAAAAhilAKaAbOskq/AGpvfknAsckJUab3k68HVCeHpCREE0ABAAAAANoVQingKBWUVJjQydOA3NMHKqugLODYtMQY6VvbA8obQCXFRwd9zgAAAAAAtDWEUsARHCgq91U+efpAFUqeszzgWO335KmAOhRC6bI8AAAAAADQxkOppUuXygMPPCBZWVkycOBAeeyxx2T48OEBxz733HMybdq0eseioqKkvPxQYOB2u2X+/Pny5z//WQoKCuTUU0+VJ598Uvr27esbk5+fL9dee628/fbbYrfbZcKECfLoo49KfHx8C35StDV6ruQ6y33Bk6cCyin5xRV+Y3WRXZfkuENL8Do5pHd6oiTERLTK3AEAAAAAsKI2E0qtWLFCZs2aJcuWLZMRI0bI4sWLZcyYMbJ582ZJS0sL+BqHw2Ge92rYk+f++++XJUuWyPPPPy89e/aUuXPnmvf87rvvJDras4Tq0ksvlf3798v7778vVVVVJui66qqr5OWXX27hT4zWDKB0ud2h/k+eAKqwtNJvrN0mkpkSX6f/U6L0TndIbFSb+aMDAAAAAIAl2dx6hd4GaBB18skny+OPP24eu1wuyczMNFVMs2fPDlgpdf3115sKqED0Y3Xu3FluvPFGuemmm8yxwsJCSU9PN6+dNGmSfP/999K/f39Zt26dDBs2zIxZtWqVjBs3Tvbs2WNe3xhOp1MSExPN+2tQZkX6887JyTEBoFaMhQqX2y378kvqLcHTEKq4vNpvbJjdJt1TEzzL72oDqF7pDomOCGuVuQMAAAAA2hdXiFybNzYnaRPlHpWVlbJ+/XqZM2eO75j+8EePHi1r16497OuKi4ule/fu5pc2ZMgQuffee+WEE04wz23fvt0sA9T38NIfiIZf+p4aSul9hw4dfIGU0vH6vT/77DO54IILAn7fiooKc6v7w1Y6D71Zkc5bgzyrzl/VuNyy50CxJ3yqDaC2ZjulrLLGb2x4mE16pmn45L0lSo+0eIkM9w+grPwzAQAAAABYhysErs1VY+ffJkKpvLw8qampMVVMdenjTZs2BXzNcccdJ88884ycdNJJJnl78MEHZdSoUbJx40bp2rWrCaS879HwPb3P6X3DpYHh4eGSlJTkGxPIokWLZMGCBX7Hc3Nz6/W0stoJoz9HPfmtkMZWu9yy72CZ7MgrlZ15peZ+V36ZVFb7n/iRYTbJTI6VHimeW/eUWOnSIVrCw+p+zgopyPfvHwUAAAAAQLC4LHZtfjhFRUXWCaWOxciRI83NSwOpfv36yVNPPSV33XVXi35vrejS/ld1K6V0qWFqaqqll+9pTy79DG3txK+srpGdubUVULXL8LbnFElVjX8ApUvtetepftL7zJQ4CWtjnwkAAAAAACtdmx8Nbx9vS4RSKSkpEhYWJtnZ2fWO6+OMjIxGvUdERIQMHjxYtmzZYh57X6fv0alTp3rvOWjQIN8YXatZV3V1tdmR70jfV3f501tDesJY+aTRE7+1P0NFVY1sz3F6ekDt12V4hbIjp8hURjWkzcY1dKrbhLxLkgZQ9RveAwAAAABgFbY2cG3eVI2de5sIpSIjI2Xo0KGyevVqGT9+vC8d1MczZ85s1Hvo8r8NGzaYJuVKd9vTYEnfwxtCaUWT9oq65pprzGOttNJG6drPSr+/+uCDD8z31t5TaFllldWy1fR/8gRQGkTtyis2zckbSoiJOBQ+1QZRGR1jxd5gx0UAAAAAAGANbSKUUrocburUqabp+PDhw2Xx4sVSUlIi06ZNM89PmTJFunTpYvo5qYULF8opp5wiffr0McHSAw88IDt37pQrr7zSlyzq7nx333239O3b14RUc+fONTvqeYMvXe43duxYmTFjhixbtkyqqqpMCKZN0Bu78x4ap6S8qrYBuQZQhSaA2nOgRAJt/dghLtIXQHnuHZKWGGN+pwAAAAAAIDS0mVBq4sSJplH4vHnzTJNxrW5atWqVr1H5rl276pV/HTx40IRJOrZjx46m0mnNmjXSv39/35hbbrnFBFtXXXWVCa5OO+0085511za+9NJLJog6++yzzftPmDBBlixZEuRPH1qcpZW+AMosw8sqlH35pQHHpiREH1qCVxtEJSdEEUABAAAAABDibG5t6Y4m0WWBiYmJpkO+lRuda38t3Y3waNatFpRUmODJEz55gqjsgrKAY9MTY2qDp0N9oDrG+/fmAgAAAACgPXId47W5VXOSNlMphbZNs8v8Yk8AZZbf1e6El1dUHnB856TY2v5Ph5bgOWIjgz5vAAAAAADQNhFKwch1lsn3+4rEFp0gaYmxklNY5ql8MgGUpxH5wZIKv9fpIruuyXG+pXcaQPXOcEh8dESrfA4AAAAAAGANhFKQVV/tksXvbKhtOv4/iY4Ik/KqGr9xdptIt5QE6dPp0PK7XukOiY3iNAIAAAAAAEeHNKGd0wqpR9/1BlIeGkhpANUzzduA3GECqJ7pDhNYAQAAAAAANBWhVDu3N79EXAFa3d89+WQZ2jutNaYEAAAAAADaAeu2ckez6JIUZ6qi6rLbbNItNaG1pgQAAAAAANoBQql2LtURI9edM8AXTOn9deecaI4DAAAAAAC0FJbvQcYO7iaDeybLd9v2Sf9enSW9Q1xrTwkAAAAAAIQ4KqVgaGVUv84JVEgBAAAAAICgIJQCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0NDpvBm6329w7nU6xKpfLJUVFRRIdHS12O1klAAAAAADBFirX5t58xJuXHA6hVDPQE0ZlZma29lQAAAAAAADaTF6SmJh42Odt7h+LrdCoJHPfvn2SkJAgNptNrJpiaqi2e/ducTgcrT0dAAAAAADaHWeIXJtr1KSBVOfOnY9Y8UWlVDPQH3DXrl0lFOhJb+UTHwAAAAAAq3OEwLX5kSqkvKy7QBEAAAAAAACWRSgFAAAAAACAoCOUghEVFSXz58839wAAAAAAIPii2tm1OY3OAQAAAAAAEHRUSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAAAAACDpCKQAAAAAAAAQdoRQAAAAAAACCjlAKAAAAAAAAQUcoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAAAg6AilAAAAAAAAEHSEUgAAAAAAAAg6QikAAAAAAAAEXXjwv2Xocblcsm/fPklISBCbzdba0wEAAAAAAGg1brdbioqKpHPnzmK3H74eilCqGWgglZmZ2drTAAAAAAAAaDN2794tXbt2PezzhFLNQCukvD9sh8MhVq32ys3NldTU1COmmAAAAAAAoGW4QuTa3Ol0muIdb15yOIRSzcC7ZE8DKSuHUuXl5Wb+Vj7xAQAAAACwKleIXZv/WIsj639CAAAAAAAAWA6hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAAAAACDpCKQAAAAAAAAQdoRQAAAAAAACCjlAKAAAAAAAAQUcoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAAAg6AilAAAAAAAAEHSEUgAAAAAAAAg6QikAAAAAAAAEHaEUAAAAAAAAgo5QCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgsF0otXbpUevToIdHR0TJixAj5/PPPjzj+tddek+OPP96MHzBggLz33nuHHfvb3/5WbDabLF68uAVmDgAAAAAAAEuGUitWrJBZs2bJ/Pnz5csvv5SBAwfKmDFjJCcnJ+D4NWvWyOTJk2X69Ony1Vdfyfjx483t22+/9Rv717/+VT799FPp3LlzED4JAAAAAABA+2apUOrhhx+WGTNmyLRp06R///6ybNkyiY2NlWeeeSbg+EcffVTGjh0rN998s/Tr10/uuusuGTJkiDz++OP1xu3du1euvfZaeemllyQiIiJInwYAAAAAAKD9skwoVVlZKevXr5fRo0f7jtntdvN47dq1AV+jx+uOV1pZVXe8y+WSyy67zARXJ5xwQgt+AgAAAAAAAHiFi0Xk5eVJTU2NpKen1zuujzdt2hTwNVlZWQHH63Gv++67T8LDw+UPf/hDo+dSUVFhbl5Op9MXcOnNinTebrfbsvMHAAAAAMDqXCFybd7Y+VsmlGoJWnmlS/y0P5U2OG+sRYsWyYIFC/yO5+bmSnl5uVj1hCksLDQnv1agAQAAAACA4HKFyLV5UVFRaIVSKSkpEhYWJtnZ2fWO6+OMjIyAr9HjRxr/8ccfmybp3bp18z2v1Vg33nij2YFvx44dAd93zpw5puF63UqpzMxMSU1NFYfDIVY98TWY089g5RMfAAAAAACrcoXItXl0dHRohVKRkZEydOhQWb16tdlBz/vL0sczZ84M+JqRI0ea56+//nrfsffff98cV9pLKlDPKT2uzdQPJyoqytwa0hPGyieNnvhW/wwAAAAAAFiZLQSuzRs7d8uEUkqrk6ZOnSrDhg2T4cOHm2qmkpISX4A0ZcoU6dKli1lep6677jo5/fTT5aGHHpJzzjlHli9fLl988YX86U9/Ms8nJyebW126+55WUh133HGt8AkBAAAAAADaB0uFUhMnTjR9m+bNm2ealQ8aNEhWrVrla2a+a9euemncqFGj5OWXX5Y77rhDbrvtNunbt6+8+eabcuKJJ7bipwAAAAAAAIDNrd2z0CTaUyoxMdE0I7NyTyntr5WWlmbpEkEAAAAAAKzKFSLX5o3NSaz7CQEAAAAAAGBZhFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAAAAACDpCKQAAAAAAAAQdoRQAAAAAAACCjlAKAAAAAAAAQUcoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAAAg6AilAAAAAAAAEHSEUgAAAAAAAAg6QikAAAAAAAAEHaEUAAAAAAAAgo5QCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAAAAAILOcqHU0qVLpUePHhIdHS0jRoyQzz///IjjX3vtNTn++OPN+AEDBsh7773ne66qqkpuvfVWczwuLk46d+4sU6ZMkX379gXhkwAAAAAAALRflgqlVqxYIbNmzZL58+fLl19+KQMHDpQxY8ZITk5OwPFr1qyRyZMny/Tp0+Wrr76S8ePHm9u3335rni8tLTXvM3fuXHO/cuVK2bx5s5x33nlB/mQAAAAAAADti83tdrvFIrQy6uSTT5bHH3/cPHa5XJKZmSnXXnutzJ4922/8xIkTpaSkRN555x3fsVNOOUUGDRoky5YtC/g91q1bJ8OHD5edO3dKt27dGjUvp9MpiYmJUlhYKA6HQ6xIf5Ya7qWlpYndbqmsEgAAAACAkOAKkWvzxuYklvmElZWVsn79ehk9erTvmP6C9PHatWsDvkaP1x2vtLLqcOOV/sBsNpt06NChGWcPAAAAAACAusLFIvLy8qSmpkbS09PrHdfHmzZtCviarKysgOP1eCDl5eWmx5Qu+TtSkldRUWFudRNAb6KpNyvSeWvRnFXnDwAAAACA1blC5Nq8sfO3TCjV0rTp+cUXX2x++U8++eQRxy5atEgWLFjgdzw3N9cEW1Y9YbRKTD+/lUsEAQAAAACwKleIXJsXFRWFViiVkpIiYWFhkp2dXe+4Ps7IyAj4Gj3emPHeQEr7SH3wwQc/2hdqzpw5puF63Uop7W2Vmppq6Z5SumxRP4OVT3wAAAAAAKzKFSLX5tHR0aEVSkVGRsrQoUNl9erVZgc97y9LH8+cOTPga0aOHGmev/76633H3n//fXO8YSD1ww8/yIcffijJyck/OpeoqChza0hPGCufNHriW/0zAAAAAABgZbYQuDZv7NwtE0oprU6aOnWqDBs2zOyQt3jxYrO73rRp08zzU6ZMkS5dupjldeq6666T008/XR566CE555xzZPny5fLFF1/In/70J18gddFFF8mXX35pdujTnlXeflNJSUkmCAMAAAAAAEDzs1QoNXHiRNO3ad68eSY8GjRokKxatcrXzHzXrl310rhRo0bJyy+/LHfccYfcdttt0rdvX3nzzTflxBNPNM/v3btX3nrrLfO1vlddWjV1xhlnBPXzAQAAAAAAtBc2t3bPQpNoT6nExETTjMzKPaVycnIkLS3N0iWCAAAAAABYlStErs0bm5NY9xMCAAAAAADAsgilAAAAAAAAEHSEUgAAAAAAALBGKFVQUCBPP/20zJkzR/Lz880x3cFOG4cDAAAAAAAAzb773jfffCOjR482Dat27NghM2bMkKSkJFm5cqXZ/e6FF1442rcEAAAAAABAO3PUlVKzZs2Syy+/XH744QeJjo72HR83bpx89NFHzT0/AAAAAAAAhKCjDqXWrVsnV199td/xLl26SFZWVnPNCwAAAAAAACHsqEOpqKgocTqdfsf/97//SWpqanPNCwAAAAAAACHsqEOp8847TxYuXChVVVXmsc1mM72kbr31VpkwYUJLzBEAAAAAAADtPZR66KGHpLi4WNLS0qSsrExOP/106dOnjyQkJMg999zTMrMEAAAAAABA+959T3fde//99+U///mP/Pe//zUB1ZAhQ8yOfAAAAAAAAECLhFIvvPCCTJw4UU499VRz86qsrJTly5fLlClTjvYtAQAAAAAA0M4c9fK9adOmSWFhod/xoqIi8xwAAAAAAADQ7KGU2+02zc0b2rNnj1naBwAAAAAAADTb8r3BgwebMEpvZ599toSHH3ppTU2NbN++XcaOHdvYtwMAAAAAAEA71uhQavz48eb+66+/ljFjxkh8fLzvucjISOnRo4dMmDChZWYJAAAAAACA9hlKzZ8/39xr+KSNzqOjo1tyXgAAAAAAAAhhR7373tSpU1tmJgAAAAAAAGg3jjqU0v5RjzzyiLz66quya9cuqaysrPd8fn5+c84PAAAAAAAAIeiod99bsGCBPPzww2YJX2FhocyaNUsuvPBCsdvtcuedd7bMLAEAAAAAANC+Q6mXXnpJ/vznP8uNN95oduCbPHmyPP300zJv3jz59NNPW2aWAAAAAAAAaN+hVFZWlgwYMMB8rTvwabWU+tWvfiXvvvtu888QAAAAAAAAIeeoQ6muXbvK/v37zde9e/eWf/zjH+brdevWSVRUVPPPEAAAAAAAACHnqEOpCy64QFavXm2+vvbaa2Xu3LnSt29fmTJlilxxxRUtMUcAAAAAAAC09933/vjHP/q+1mbn3bt3lzVr1phg6txzz23u+QEAAAAAACAEHXUo1dApp5xibuqLL76QYcOGNce8AAAAAAAAEMKOevlecXGxlJWV1Tv29ddfmyqpESNGNOfcAAAAAAAA0N5Dqd27d8vIkSMlMTHR3GbNmiWlpaWml5SGUXFxcWYZHwAAAAAAANBsy/duvvlmKS8vl0cffVRWrlxp7j/++GMTSG3dutXsygcAAAAAAAA0a6XURx99JE8++aTMnDlTli9fLm63Wy699FJ5/PHHgxpILV26VHr06CHR0dEmEPv888+POP61116T448/3owfMGCAvPfee/We188xb9486dSpk8TExMjo0aPlhx9+aOFPAQAAAAAA0L41OpTKzs6Wnj17mq/T0tIkNjZWfvnLX0owrVixwiwbnD9/vnz55ZcycOBAGTNmjOTk5AQcr8sJJ0+eLNOnT5evvvpKxo8fb27ffvutb8z9998vS5YskWXLlslnn31mliHqe2pVWLviPCCRezebewAAAAAA0Aqc7eva3ObWUqFGCAsLk6ysLElNTTWPHQ6H/Pe///UFVcGglVEnn3yyqc5SLpdLMjMz5dprr5XZs2f7jZ84caKUlJTIO++84zumOwUOGjTIhFD60Tt37iw33nij3HTTTeb5wsJCSU9Pl+eee04mTZrUqHk5nU7TZ0tfqz8Xy1n/vrjfeVJPBnHbbGL75QyRQWe29qwAAAAAAGg/vv5Q3H//86Fr83N/JzJktFhRY3OSRveU0gDnJz/5idhsNt8ufIMHDxa7vX6xVX5+vrSEyspKWb9+vcyZM8d3TL+3Lrdbu3ZtwNfoca2sqkuroN58803z9fbt203Qpu/hpT80Db/0tYcLpSoqKsyt7g/bG5LpzVKcB8RWG0gpc//enzw3AAAAAAAQNDbvvQZTbz8p7l4DRRzJYjWNzUYaHUo9++yz0pry8vKkpqbGVDHVpY83bdoU8DUaOAUar8e9z3uPHW5MIIsWLZIFCxb4Hc/NzbXcsj8tC0xqXLEcAAAAAAAIEpvbJQe3fi+VXX4iVlNUVNS8odTUqVObMp+QotVadSuwtFJKlxHq0kbLLd+LDvOUBdYJptw2u7ivWWzJNBYAAAAAAMtxHhDbk9f5XZt36N3Pktfmutlcs4ZSrS0lJcX0tdKG63Xp44yMjICv0eNHGu+912O6+17dMdp36nCioqLMrSFdTthwOWOb1yFV5NzfmbJATWH1pLede43Y0jJbe2YAAAAAALQP0bGBr831mt2CGpuNWCZBiYyMlKFDh8rq1avrrVHUxyNHjgz4Gj1ed7x6//33feO1SbsGU3XHaNWT7sJ3uPcMSUNGi/u6ZZJ/7g3m3qqN1AAAAAAAsKwh7e/a3DKVUkqXzOkywmHDhsnw4cNl8eLFZne9adOmmeenTJkiXbp0MT2f1HXXXSenn366PPTQQ3LOOefI8uXL5YsvvpA//cnTxFubtl9//fVy9913S9++fU1INXfuXLMj3/jx46VdcSR71qlasCwQAAAAAICQ4Ghf1+aWCqUmTpxomonPmzfPNCLXJXarVq3yNSrftWtXvRKxUaNGycsvvyx33HGH3HbbbSZ40p33TjzxRN+YW265xQRbV111lRQUFMhpp51m3rOx6x8BAAAAAABw9GxuN1uvNZUu+UtMTJTCwkLrNTqvsxQyJydH0tLSrNcXCwAAAACAEOAKkWvzxuYkjaqUqrvT3I95+OGHGz0WAAAAAAAA7VOjQqmvvvqqUW+mPZoAAAAAAACAZgmlPvzww8YMAwAAAAAAABrFugsUAQAAAAAAENqVUhdeeGGj33DlypVNmQ8AAAAAAADagUaFUtoxHQAAAAAAAAhqKPXss8822zcEAAAAAAAA6CkFAAAAAACAtlkpVVfPnj3FZrMd9vlt27Y1dU4AAAAAAAAIcUcdSl1//fX1HldVVclXX30lq1atkptvvrk55wYAAAAAAIAQddSh1HXXXRfw+NKlS+WLL75ojjkBAAAAAAAgxDVbT6lf/vKX8sYbbzTX2wEAAAAAACCENVso9frrr0tSUlJzvR0AAAAAAABC2FEv3xs8eHC9Rudut1uysrIkNzdXnnjiieaeHwAAAAAAAELQUYdS48ePr/fYbrdLamqqnHHGGXL88cc359wAAAAAAAAQoo46lJo/f37LzAQAAAAAAADtRrP1lAIAAAAAAACavVJKl+nV7SUViD5fXV3d6G8OAAAAAACA9qnRodRf//rXwz63du1aWbJkibhcruaaFwAAAAAAAEJYo0Op888/3+/Y5s2bZfbs2fL222/LpZdeKgsXLmzu+QEAAAAAACAEHVNPqX379smMGTNkwIABZrne119/Lc8//7x07969+WcIAAAAAACA9h1KFRYWyq233ip9+vSRjRs3yurVq02V1IknnthyMwQAAAAAAED7Xb53//33y3333ScZGRnyyiuvBFzOBwAAAAAAADSGze12uxu7+15MTIyMHj1awsLCDjtu5cqV0t44nU5JTEw0lWQOh0OsSJvU5+TkSFpamvldAwAAAACA4HKFyLV5Y3OSRldKTZkyRWw2W3PNDwAAAAAAAO1Yo0Op5557rmVnAgAAAAAAgHbDurVgAAAAAAAAsCxCKQAAAAAAAASdZUKp/Px8ufTSS02DrA4dOsj06dOluLj4iK8pLy+X3//+95KcnCzx8fEyYcIEyc7O9j3/3//+VyZPniyZmZmmiXu/fv3k0UcfDcKnAQAAAAAAaN8sE0ppILVx40Z5//335Z133pGPPvpIrrrqqiO+5oYbbpC3335bXnvtNfn3v/8t+/btkwsvvND3/Pr1601H+xdffNG89+233y5z5syRxx9/PAifCAAAAAAAoP2yud1ut7Rx33//vfTv31/WrVsnw4YNM8dWrVol48aNkz179kjnzp39XqPbDqampsrLL78sF110kTm2adMmUw21du1aOeWUUwJ+L62s0u/3wQcfNPtWh21ZqGw7CQAAAACAVblC5Nq8sTmJJT6hhki6ZM8bSKnRo0ebX9Bnn30W8DVaBVVVVWXGeR1//PHSrVs3836Hoz+wpKSkZv4EAAAAAAAAqCtcLCArK8ukhHWFh4eb8EifO9xrIiMjTZhVV3p6+mFfs2bNGlmxYoW8++67R5xPRUWFudVNAL2Jpt6sSOetRXNWnT8AAAAAAFbnCpFr88bOv1VDqdmzZ8t99913xDG6lC4Yvv32Wzn//PNl/vz58otf/OKIYxctWiQLFizwO56bm2uaq1v1hNEqMT35rVwiCAAAAACAVblC5Nq8qKio7YdSN954o1x++eVHHNOrVy/JyMgwayrrqq6uNjvy6XOB6PHKykopKCioVy2lu+81fM13330nZ599tmmcfscdd/zovLUZ+qxZs+pVSukOftrDyso9pWw2m/kMVj7xAQAAAACwKleIXJtHR0e3/VBKf8h6+zEjR4404ZL2iRo6dKg5po3I9Zc1YsSIgK/RcREREbJ69WqZMGGCObZ582bZtWuXeT8v3XXvrLPOkqlTp8o999zTqHlHRUWZW0N6wlj5pNET3+qfAQAAAAAAK7OFwLV5Y+duiU+oO+aNHTtWZsyYIZ9//rn85z//kZkzZ8qkSZN8O+/t3bvXNDLX55V2eZ8+fbqpaPrwww9NoDVt2jQTSHl33tMle2eeeaZZrqfjtNeU3nQZHgAAAAAAANp5o3P10ksvmSBKl9lp4qbVT0uWLPE9rzvtaSVUaWmp79gjjzziG6uNyceMGSNPPPGE7/nXX3/dBFAvvviiuXl1795dduzYEcRPBwAAAAAA0L7Y3No9C02iPaW0MkubkVm5p5T27dJdDq1cIggAAAAAgFW5QuTavLE5iXU/IQAAAAAAACyLUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAAAAACDpCKQAAAAAAAAQdoRQAAAAAAACCjlAKAAAAAAAAQUcoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAAAg6AilAAAAAAAAEHSEUgAAAAAAAAg6QikAAAAAAAAEHaEUAAAAAAAAgo5QCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNBZJpTKz8+XSy+9VBwOh3To0EGmT58uxcXFR3xNeXm5/P73v5fk5GSJj4+XCRMmSHZ2dsCxBw4ckK5du4rNZpOCgoIW+hQAAAAAAACwVCilgdTGjRvl/fffl3feeUc++ugjueqqq474mhtuuEHefvttee211+Tf//637Nu3Ty688MKAYzXkOumkk1po9gAAAAAAALBcKPX999/LqlWr5Omnn5YRI0bIaaedJo899pgsX77cBE2BFBYWyv/93//Jww8/LGeddZYMHTpUnn32WVmzZo18+umn9cY++eSTpjrqpptuCtInAgAAAAAAaN8sEUqtXbvWLNkbNmyY79jo0aPFbrfLZ599FvA169evl6qqKjPO6/jjj5du3bqZ9/P67rvvZOHChfLCCy+Y9wMAAAAAAEDLCxcLyMrKkrS0tHrHwsPDJSkpyTx3uNdERkaaMKuu9PR032sqKipk8uTJ8sADD5iwatu2bY2aj75Ob15Op9Pcu1wuc7Minbfb7bbs/AEAAAAAsDpXiFybN3b+rRpKzZ49W+67774fXbrXUubMmSP9+vWT3/zmN0f1ukWLFsmCBQv8jufm5prm6lY9YXTJo578VIwBAAAAABB8rhC5Ni8qKmr7odSNN94ol19++RHH9OrVSzIyMiQnJ6fe8erqarMjnz4XiB6vrKw0vaLqVkvp7nve13zwwQeyYcMGef31181j/aWrlJQUuf322wMGT94wa9asWfUqpTIzMyU1NdXsDmjVE193HtTPYOUTHwAAAAAAq3KFyLV5dHR02w+l9Iestx8zcuRIEy5pnyhtWO4NlPSXpY3PA9FxERERsnr1apkwYYI5tnnzZtm1a5d5P/XGG29IWVmZ7zXr1q2TK664Qj7++GPp3bv3YecTFRVlbg3pCWPlk0ZPfKt/BgAAAAAArMwWAtfmjZ27JXpK6RK7sWPHyowZM2TZsmWmgfnMmTNl0qRJ0rlzZzNm7969cvbZZ5uG5cOHD5fExESZPn26qWjS3lNawXTttdeaQOqUU04xr2kYPOXl5fm+X8NeVAAAAAAAAGg+lgil1EsvvWSCKA2eNHHT6qclS5b4ntegSiuhSktLfcceeeQR31htTD5mzBh54oknWukTAAAAAAAAwMvm9jZSwjHTnlJamaXNyKzcU0r7dukuh1YuEQQAAAAAwKpcIXJt3ticxLqfEAAAAAAAAJZFKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAAAAACDpCKQAAAAAAAAQdoRQAAAAAAACCjlAKAAAAAAAAQUcoBQAAAAAAgKAjlAIAAAAAAEDQEUoBAAAAAAAg6AilAAAAAAAAEHSEUgAAAAAAAAi68OB/y9DjdrvNvdPpFKtyuVxSVFQk0dHRYreTVQIAAAAAEGyuELk29+Yj3rzkcAilmoGeMCozM7O1pwIAAAAAANBm8pLExMTDPm9z/1hshUYlmfv27ZOEhASx2Wxi1RRTQ7Xdu3eLw+Fo7ekAAAAAANDuOEPk2lyjJg2kOnfufMSKLyqlmoH+gLt27SqhQE96K5/4AAAAAABYnSMErs2PVCHlZd0FigAAAAAAALAsQikAAAAAAAAEHaEUjKioKJk/f765BwAAAAAAwRfVzq7NaXQOAAAAAACAoKNSCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIICjZ5BAAAAAAAdYXXewQ0s+LiYomKipKIiAgTTNlsttaeEgAAAAAA7crWrVvllVdekZKSEjnxxBPl0ksvlbaASim0mO+//14uuOACWbFihVRWVppAioopAAAAAACCZ8OGDTJq1Cj54osv5O2335bHH39c3nvvPWkLqJRCi9i5c6dMmDDBpLFaLRUdHS3nnXeeREZGUjEFAAAAAEAQZGdny8SJE2X69Oly7733Sl5enpx11lmyb98+aQuolEKzq6mpkTfeeEP69Okjn3/+uXTo0MGc/G+99RYVUwAAAAAABMnmzZvNNfjvf/978zglJUUGDhwo//3vf+V3v/uduVZvTYRSaHZhYWEmeZ0yZYo52d99911JT0/3BVMVFRUEUwAAAAAAtLDw8HApLS31LdfT6/KXXnpJ7Ha7qZpavny5XHzxxdJabG6SAbSAqqoq09zcSyukzj//fFM6eNttt5mv9fm//e1v5msAAAAAANC89Br8D3/4g1nF1LdvX/nggw9k5cqVpr2Oev755+Xuu++Wv/71r6YBerDRUwrNQhPW3bt3S2xsrKSlpUnHjh3F5XKZ9LW6utr0knrzzTdl/PjxJpnVJX4ffvihqZw6+eSTpXPnzq39EQAAAAAAsLTS0lJzi4mJMdfhumppyZIlpoeU9n7Ozc2V008/3Te+e/fu5tq9blFJMBFKocm++eYb+fWvf22CJl2apye9dvM/5ZRTfOWCGkxFRUWZyijdke+yyy4zf0A++ugjAikAAAAAAJpo48aNcv3110tWVpZ5fOWVV8rUqVPNNbre9Jpdr8vz8/MlMTHRjPnHP/4hqampptdUayCUQpPoyX7uuefKpEmTTDf/7777TlasWCE/+9nP5IUXXjDHvcGU/gHQIEqT2ISEBBNInXDCCa39EQAAAAAAsLTvv/9ezjzzTHMNrk3NtYfUU089JaNGjTKrk5QGU1u3bpXrrrtOevToYdru6PW7rmJKTk5ulXnTUwpN8vXXX5uqp7ffftuc1KqsrEzmzZtnSgR1reo555zjW8r3xBNPyMyZM2X9+vUyePDg1p4+AAAAAACWdvDgQRNG9enTR5YuXeo7PnToUBk+fLg8+eSTvmty3XVv9uzZ5rpdVy3dfvvtrVosQqUUmqSwsNCUCHqzTT3Rde3q/fffb07ySy65RL744gvTUE1NnDhRxo4dK7169WrlmQMAAAAAYH179+4Vh8Nhrre9G43pKqWzzz5bDhw4YI7ZbDazemngwIHy2muvSXx8vGm/o8v5WpO9Vb87LO+0006Tn/70pzJnzhyzLlWTVw2m9ITXY4MGDZJXXnnFhFZ6XEsCCaQAAAAAAGgeWumklVLaRsfbPkclJSVJcXGx+Vqv0cPCwsxjDaRUawdSilAKTaIntaaxO3bsMMv1nE6nCaZUly5dzMm+adMm8wfAexwAAAAAADSdtyhkwoQJ5rEWhHivvUtKSsxue166ounOO+80FVNtBcv3cMz0ZNeT/5prrjHN0nRnPV2yp2tStXRQaWVUx44dzUmvfzB0PAAAAAAAaDpvAOW9PtdbdXW1qZbSDca8u+zNnTtX7rnnHtMXWotL2goaneOYadCkJ7O3Ydpdd90l7777rhQUFMh5550nu3fvlnfeeUc+/fRTdtkDAAAAAKAFr82L6yzNU48++qh888030r17d1m0aJF88sknpvl5W8J6KjSKBk+BTvqdO3fKgAED5F//+pdJXu+77z75xS9+IRs2bDDrU9euXUsgBQAAAABAM3O73aYqynttPn78eBM8eenyvWeffdYs22uLgZRi+R5+dHc9LffzNjD3lgZ6T/pTTz1VfvWrX5mG5+r00083N/3DUXctKwAAAAAAODb79u2TdevWSXl5udndfsiQIWapni7T27Ztm5xxxhnyy1/+0ndtrjIyMkyV1HvvvSf9+vWTtojlezis7777TkaNGiW33HKL3HbbbeZY3WDqiiuukIiICFm2bJmvV5R3HSsAAAAAAGi6DRs2yAUXXGD6Nefk5JhjTzzxhJxzzjnmGnzs2LGSkpIiL774Yr3rcX0uKytLOnXqJG0VoRQC2rNnj+kLpeV+eXl5cvPNN8vs2bPrLd2rqqoyoRQAAAAAAGh+W7duNauRfvOb35hrcu3drIGU7qr3/PPPS1xcnFRWVppr87qBVN2CkraM5XvwoyfvG2+8IT179pSZM2fK559/Lvfee695Tv8QEEgBAAAAANCyKisrZenSpWYFk24sptfgHTp0kJNPPtn0dPb2fo6MjPR7rRUCKUUohYAn77hx4yQtLU3OPPNMGTRokCn702793mBK/zBYJXkFAAAAAMBq7Ha79OnTxxSM6DW4t13OWWedJQsXLjQ9oBMSEuq9xmotdQilEJA2TtOTX+m61SuvvNKc2HUrpvRkf/vtt2XkyJFm/SoAAAAAAGge4eHhppdUw55Q3sooba3jDaE2bdokxx9/vKUCKUUoBV8n/71798qBAwdk9OjRJpHVm24vqX8QNHTSxuZKgyk98XXso48+Krt27Wrt6QMAAAAAEDLX5nl5eTJmzBhJT083x73X5rpiyel0SmlpqQmnNISaM2eO3HfffXLw4EFxOByWCqYIpSDffPON/OpXvzJlf//73/9kwIABctVVV5lGavHx8b7G5qmpqTJ9+nQTSOlufLqWde3atW26kz8AAAAAAFa9Np8xY4Zcdtll5trc20JHwygNqGJiYmTBggWm79Snn34qiYmJYjU0BGrnNH2dNGmSXHLJJfLuu++aVFZL/p577jnTOK2oqMgEUt4Galox9d1335k/JJ988okMGzastT8CAAAAAAAheW3+/PPP+67NvT2dNaDSohEtJtGVTB9++KEMHz5crIhQqp3LysqSsrIyc+L36NHDnNgaSGmZ4Jo1a0wJYHl5uTn5tULqxRdflH/84x/mpO/fv39rTx8AAAAAgHZzba5yc3Nlw4YN8s4778jnn38uQ4cOFasilGrnvGtQvX2hdJ2qHtMk9vTTTzcJ7bp168xzOu7UU0+Vzz77TIYMGdLKMwcAAAAAoP1dm3fp0kVuvPFGWb9+vQwcOFCszObW8he0WxUVFXLaaadJRkaGvPnmm2apnreBmp4aeoIPHjzYlAxabWtJAAAAAABC7drcOz4qKkqsjkqpdkz7ROlJ/Oyzz8pHH30k11xzjTnuPek1gDrvvPMkJyfHHCeQAgAAAACg9a7N3bV1RaEQSClCqXZM+0TpznonnniiSVtfeeUVmTJlimRnZ/vGbN++XTp27GjGAQAAAACA1rs2d9VuQhYqWL7XjjRcfuctBSwuLjalf19//bVpqta9e3dJSkqS5ORk+dvf/iZr1641W1ECAAAAAICm4dr8ECql2oGtW7fKwYMH6530msLqSb9jxw75yU9+YhqmnX322bJx40YZN26caZyWlpZmOvmH2kkPAAAAAECwcW3uj0qpEPff//7XNEN7+umn5Yorrqj33O7du80ueueff778+c9/NmWA2kzNm9rqYy0jBAAAAAAAx45r88AIpUL8pD/11FNl5syZ8sc//tHv+ccee0y2bdsmDz/8cL2k1nvis9seAAAAAABNw7X54RFKhahNmzaZ0r558+bJ3LlzTbL6r3/9S7Zs2WKap/Xt21dSU1NDOnEFAAAAAKA1cW1+ZOE/8jwsSE/mV1991axNveiii8yxn//853LgwAGzTlWbpPXs2dOksCeddFJrTxcAAAAAgJDDtfmPa38xXDug6erVV18tM2bMMGtWNZXt0KGD2VoyNzdXHnzwQbM+9e677zbd/QEAAAAAQPPi2vzHUSkVotLT082JrV38tUu/ft2vXz/z3AUXXCA7d+6U++67TwoLCyU+Pr61pwsAAAAAQMjh2vzICKVCxL59++TLL7+UyspK6datmwwbNsysS73jjjvMSd67d28zTssGNYnt06ePdOzYUSIjI1t76gAAAAAAhASuzY8OoVQI2LBhg4wfP15SUlJMx/4ePXrILbfcIr/+9a+lU6dOkpGR4evUrye9+uc//yldu3aV2NjYVp49AAAAAADWx7X50aOnlMVt3bpVxo0bZ5qm/eMf/5BVq1bJCSecYO41eW24deSuXbvk5ptvlr/85S/y0EMPSVxcXKvOHwAAAAAAq+Pa/NjY3PqTgSVpOeCcOXNkz5495kT2lvs988wzJo3dvHmz6ebvpetXn3rqKVmzZo288sorMmjQoFacPQAAAAAA1se1+bFj+Z7Ft5fUMj9tkqYnvTd5HTVqlGmQVlVVVW/88OHDpaioSBYuXChdunRptXkDAAAAABAquDY/doRSFhYdHW3Wq/bs2bPecd1iMiIiot6Jv379ehk6dKicffbZrTBTAAAAAABCE9fmx46eUhazf/9+U+qn61I1jfWe9LpG1bs+VbeSPHjwoO818+bNk5///Ody4MABk9gCAAAAAIBjx7V586BSykK++eYbOe+88yQqKkqys7NN9349qceMGSNJSUm+EkG92e12UyZ49913y4MPPigff/xxvTWsAAAAAADg6HFt3nxodG4Rubm58rOf/UwuvPBCmT59uikPnDVrlvnDcPHFF8vvf/97SU1NNWNzcnJk7Nix8pOf/ET++te/muZpWh4IAAAAAACOHdfmzYtKKQud+OXl5ebE79Wrlzm2fPlymT17tqxcudJsH6knf2xsrCkF/Prrr2XTpk3y2WeftetO/gAAAAAANBeuzZsXPaUsQhujVVdXS2lpqXlcVlZm7v/4xz/KmWeeKU8++aRs2bLFHOvYsaP87ne/ky+//JKTHgAAAACAZsK1efNi+Z6F6LaRuhb1gw8+MI8rKirMGlZ18sknS58+feSVV14xjzW51TJCAAAAAADQfLg2bz5USrVRJSUlUlRUJE6n03fsqaeeko0bN8oll1xiHutJrwmt0jWt+hovTnoAAAAAAJqGa/OWRSjVBn333Xdmferpp58u/fr1k5deeskc168fffRRef/99+XXv/61KRvUTv7eBmq6dlX/IFD8BgAAAABA03Bt3vJodN4GT3pNVqdMmSLDhg2T9evXy7Rp06R///4yePBgs+2knuC6LvWkk06S448/XiIjI+Xdd9+VTz/9VMLD+ZUCAAAAANAUXJsHBz2l2pD8/HyZPHmyOZk1dfXSZmkDBgyQJUuW+I5p+eDdd99tXqPlgNdcc435wwEAAAAAAI4d1+bBQ3TXhmjJX0FBgVx00UXmscvlMiWAPXv2NCe40gxRbwkJCXLffffVGwcAAAAAAJqGa/Pg4afVhqSnp8uLL74oP/3pT83jmpoac9+lSxffiW2z2czXdZus6TEAAAAAANB0XJsHD6FUG9O3b19fwhoREWG+1vRVm6V5LVq0SJ5++mlfd39OfAAAAAAAmg/X5sHB8r02ShNXPeG9J7U3jZ03b55Zr/rVV1/ROA0AAAAAgBbEtXnLolKqDfP2oNcTPDMzUx588EG5//775YsvvpCBAwe29vQAAAAAAAh5XJu3HOK8NsybwGqp4J///GdxOBzyySefyJAhQ1p7agAAAAAAtAtcm7ccKqUsYMyYMeZ+zZo1MmzYsNaeDgAAAAAA7Q7X5s3P5vbWoaFNKykpkbi4uNaeBgAAAAAA7RbX5s2LUAoAAAAAAABBx/I9AAAAAAAABB2hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAACDoCKUAAAAAAAAQdIRSAAAAbcjll18uNpvN3CIiIiQ9PV1+/vOfyzPPPCMul6vR7/Pcc89Jhw4dWnSuAAAATUEoBQAA0MaMHTtW9u/fLzt27JC///3vcuaZZ8p1110nv/rVr6S6urq1pwcAANAsCKUAAADamKioKMnIyJAuXbrIkCFD5LbbbpO//e1vJqDSCij18MMPy4ABAyQuLk4yMzPld7/7nRQXF5vn/vWvf8m0adOksLDQV3V15513mucqKirkpptuMu+trx0xYoQZDwAAEGyEUgAAABZw1llnycCBA2XlypXmsd1ulyVLlsjGjRvl+eeflw8++EBuueUW89yoUaNk8eLF4nA4TMWV3jSIUjNnzpS1a9fK8uXL5ZtvvpFf//rXpjLrhx9+aNXPBwAA2h+b2+12t/YkAAAAcKinVEFBgbz55pt+z02aNMkESd99953fc6+//rr89re/lby8PPNYK6quv/56815eu3btkl69epn7zp07+46PHj1ahg8fLvfee2+LfS4AAICGwv2OAAAAoE3S/5eoS/HUP//5T1m0aJFs2rRJnE6n6TVVXl4upaWlEhsbG/D1GzZskJqaGvnJT35S77gu6UtOTg7KZwAAAPAilAIAALCI77//Xnr27GkaoGvT82uuuUbuueceSUpKkk8++USmT58ulZWVhw2ltOdUWFiYrF+/3tzXFR8fH6RPAQAA4EEoBQAAYAHaM0ornW644QYTKrlcLnnooYdMbyn16quv1hsfGRlpqqLqGjx4sDmWk5MjP/3pT4M6fwAAgIYIpQAAANoYXU6XlZVlAqTs7GxZtWqVWaqn1VFTpkyRb7/9VqqqquSxxx6Tc889V/7zn//IsmXL6r1Hjx49TGXU6tWrTYN0rZ7SZXuXXnqpeQ8NtDSkys3NNWNOOukkOeecc1rtMwMAgPaH3fcAAADaGA2hOnXqZIIl3Rnvww8/NDvt/e1vfzPL7jRkevjhh+W+++6TE088UV566SUTWtWlO/Bp4/OJEydKamqq3H///eb4s88+a0KpG2+8UY477jgZP368rFu3Trp169ZKnxYAALRX7L4HAAAAAACAoKNSCgAAAAAAAEFHKAUAAAAAAICgI5QCAAAAAABA0BFKAQAAAAAAIOgIpQAAAAAAABB0hFIAAAAAAAAIOkIpAAAAAAAABB2hFAAAAAAAAIKOUAoAAAAAAABBRygFAAAAAACAoCOUAgAAAAAAQNARSgEAAAAAAECC7f8D11SrppRFFAIAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "try:\n", + " import matplotlib.pyplot as plt\n", + "\n", + " if timeseries:\n", + " fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 6), sharex=True)\n", + "\n", + " ax1.plot(dates, means, marker=\".\", color=\"steelblue\")\n", + " ax1.set_ylabel(\"Mean\")\n", + " ax1.set_title(\"conv_rate — Daily Trend\")\n", + " ax1.grid(True, alpha=0.3)\n", + "\n", + " ax2.plot(dates, null_rates, marker=\".\", color=\"coral\")\n", + " ax2.set_ylabel(\"Null Rate\")\n", + " ax2.set_xlabel(\"Date\")\n", + " ax2.grid(True, alpha=0.3)\n", + "\n", + " plt.xticks(rotation=45)\n", + " plt.tight_layout()\n", + " plt.show() # pragma: allowlist secret\n", + "except ImportError:\n", + " print(\"Install matplotlib to visualize: pip install matplotlib\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 9: On-Demand Exploration (Transient Compute)\n", + "\n", + "Compute metrics for an arbitrary date range without storing them. Useful for ad-hoc investigation." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "conv_rate (numeric):\n", + " rows=905 nulls=0 null_rate=0.0000\n", + " mean=0.5041 stddev=0.1929\n", + " p50=0.4964 p95=0.8221 p99=0.9757\n", + "\n", + "avg_daily_trips (numeric):\n", + " rows=905 nulls=0 null_rate=0.0000\n", + " mean=20.1525 stddev=4.4410\n", + " p50=20.0000 p95=27.0000 p99=31.9600\n", + "\n", + "vehicle_type (categorical):\n", + " rows=905 nulls=0 null_rate=0.0000\n", + " unique_values=5\n", + " van: 194\n", + " sedan: 193\n", + " suv: 186\n", + " truck: 171\n", + " compact: 161\n", + "\n" + ] + } + ], + "source": [ + "transient_result = monitoring.compute_transient(\n", + " project=\"monitoring_demo\",\n", + " feature_view_name=\"driver_stats\",\n", + " feature_names=[\"conv_rate\", \"avg_daily_trips\", \"vehicle_type\"],\n", + " start_date=date(2025, 1, 10),\n", + " end_date=date(2025, 1, 20),\n", + ")\n", + "\n", + "for fm in transient_result.get(\"metrics\", []):\n", + " print(f\"{fm['feature_name']} ({fm['feature_type']}):\")\n", + " print(f\" rows={fm['row_count']} nulls={fm['null_count']} null_rate={fm['null_rate']:.4f}\")\n", + " if fm[\"feature_type\"] == \"numeric\":\n", + " print(f\" mean={fm['mean']:.4f} stddev={fm['stddev']:.4f}\")\n", + " print(f\" p50={fm['p50']:.4f} p95={fm['p95']:.4f} p99={fm['p99']:.4f}\")\n", + " elif fm[\"feature_type\"] == \"categorical\" and fm.get(\"histogram\"):\n", + " hist = fm[\"histogram\"]\n", + " print(f\" unique_values={hist['unique_count']}\")\n", + " for entry in hist[\"values\"]:\n", + " print(f\" {entry['value']}: {entry['count']}\")\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 10: REST API Usage\n", + "\n", + "Once the Feast registry server is running, all monitoring endpoints are available via HTTP.\n", + "\n", + "```bash\n", + "# Start the server\n", + "feast serve_registry\n", + "```\n", + "\n", + "### Compute metrics via REST" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'job_id': '077f59c5-c341-4fbb-9adc-b0111fc9228b', 'status': 'completed', 'computed_feature_views': 1, 'computed_features': 20, 'granularities': ['biweekly', 'daily', 'monthly', 'quarterly', 'weekly'], 'duration_ms': 98}\n", + "[{'project_id': 'monitoring_demo', 'feature_view_name': 'driver_stats', 'feature_name': 'conv_rate', 'metric_date': '2025-01-01', 'granularity': 'daily', 'data_source_type': 'batch', 'computed_at': '2026-04-21T13:41:42.687597+05:30', 'is_baseline': True, 'feature_type': 'numeric', 'row_count': 4922, 'null_count': 0, 'null_rate': 0.0, 'mean': 0.4988999058272324, 'stddev': 0.1975387054069251, 'min_val': 0.0, 'max_val': 1.0, 'p50': 0.4998365219303598, 'p75': 0.633892663793526, 'p90': 0.7521919750314627, 'p95': 0.825733080299169, 'p99': 0.9640086762359101, 'histogram': {'bins': [0.0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1.0], 'counts': [53, 67, 75, 146, 180, 267, 355, 399, 432, 493, 505, 420, 411, 330, 283, 186, 124, 93, 46, 57], 'bin_width': 0.05}}, {'project_id': 'monitoring_demo', 'feature_view_name': 'driver_stats', 'feature_name': 'conv_rate', 'metric_date': '2025-02-28', 'granularity': 'daily', 'data_source_type': 'batch', 'computed_at': '2026-04-21T19:02:39.068597+05:30', 'is_baseline': False, 'feature_type': 'numeric', 'row_count': 104, 'null_count': 0, 'null_rate': 0.0, 'mean': 0.5201334885346333, 'stddev': 0.21216576270117404, 'min_val': 0.09993354474902831, 'max_val': 1.0, 'p50': 0.5065079886167952, 'p75': 0.6963620898617928, 'p90': 0.7809868206291576, 'p95': 0.8538056054296318, 'p99': 0.9187701931117264, 'histogram': {'bins': [0.09993354474902831, 0.1449368675115769, 0.18994019027412548, 0.23494351303667405, 0.27994683579922264, 0.32495015856177123, 0.3699534813243198, 0.4149568040868684, 0.459960126849417, 0.5049634496119656, 0.5499667723745142, 0.5949700951370628, 0.6399734178996113, 0.6849767406621599, 0.7299800634247084, 0.774983386187257, 0.8199867089498056, 0.8649900317123542, 0.9099933544749028, 0.9549966772374514, 1.0], 'counts': [4, 1, 6, 7, 5, 5, 7, 6, 11, 5, 4, 10, 5, 8, 9, 3, 4, 2, 1, 1], 'bin_width': 0.045003322762548585}}]\n", + "[{'project_id': 'monitoring_demo', 'feature_view_name': 'driver_stats', 'feature_name': 'conv_rate', 'metric_date': '2025-01-01', 'granularity': 'daily', 'data_source_type': 'batch', 'computed_at': '2026-04-21T13:41:42.687597+05:30', 'is_baseline': True, 'feature_type': 'numeric', 'row_count': 4922, 'null_count': 0, 'null_rate': 0.0, 'mean': 0.4988999058272324, 'stddev': 0.1975387054069251, 'min_val': 0.0, 'max_val': 1.0, 'p50': 0.4998365219303598, 'p75': 0.633892663793526, 'p90': 0.7521919750314627, 'p95': 0.825733080299169, 'p99': 0.9640086762359101, 'histogram': {'bins': [0.0, 0.05, 0.1, 0.15000000000000002, 0.2, 0.25, 0.30000000000000004, 0.35000000000000003, 0.4, 0.45, 0.5, 0.55, 0.6000000000000001, 0.65, 0.7000000000000001, 0.75, 0.8, 0.8500000000000001, 0.9, 0.9500000000000001, 1.0], 'counts': [53, 67, 75, 146, 180, 267, 355, 399, 432, 493, 505, 420, 411, 330, 283, 186, 124, 93, 46, 57], 'bin_width': 0.05}}]\n" + ] + } + ], + "source": [ + "# This cell is for reference — run it when the registry server is up.\n", + "\n", + "import requests\n", + "\n", + "BASE_URL = \"http://localhost:6572/api/v1\"\n", + "\n", + "# Auto-compute all metrics\n", + "resp = requests.post(f\"{BASE_URL}/monitoring/auto_compute\", json={\n", + " \"project\": \"monitoring_demo\",\n", + "})\n", + "print(resp.json())\n", + "\n", + "# Read per-feature metrics\n", + "resp = requests.get(f\"{BASE_URL}/monitoring/metrics/features\", params={\n", + " \"project\": \"monitoring_demo\",\n", + " \"feature_view_name\": \"driver_stats\",\n", + " \"feature_name\": \"conv_rate\",\n", + " \"granularity\": \"daily\",\n", + " \"data_source_type\": \"batch\",\n", + "})\n", + "print(resp.json())\n", + "\n", + "# Read baseline\n", + "resp = requests.get(f\"{BASE_URL}/monitoring/metrics/baseline\", params={\n", + " \"project\": \"monitoring_demo\",\n", + " \"feature_view_name\": \"driver_stats\",\n", + " \"feature_name\": \"conv_rate\",\n", + " \"data_source_type\": \"batch\",\n", + "})\n", + "print(resp.json())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 11: Monitoring Feature Serving Logs\n", + "\n", + "If your feature service has logging enabled, you can compute metrics from actual production traffic.\n", + "\n", + "### Define a feature service with logging" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "See the code cell above for the logging config pattern.\n", + "Once applied, log metrics can be computed with:\n", + " CLI: feast monitor run --source-type log\n", + " API: POST /monitoring/compute/log\n", + " SDK: monitoring.compute_log_metrics(project, feature_service_name)\n" + ] + } + ], + "source": [ + "# Example feature service definition with logging\n", + "#\n", + "# from feast import FeatureService, LoggingConfig\n", + "# from feast.infra.offline_stores.contrib.postgres_offline_store.postgres_source import (\n", + "# PostgreSQLLoggingDestination,\n", + "# )\n", + "#\n", + "# driver_service = FeatureService(\n", + "# name=\"driver_service\",\n", + "# features=[driver_stats_fv],\n", + "# logging_config=LoggingConfig(\n", + "# destination=PostgreSQLLoggingDestination(table_name=\"feast_driver_logs\"),\n", + "# sample_rate=1.0,\n", + "# ),\n", + "# )\n", + "print(\"See the code cell above for the logging config pattern.\")\n", + "print(\"Once applied, log metrics can be computed with:\")\n", + "print(\" CLI: feast monitor run --source-type log\")\n", + "print(\" API: POST /monitoring/compute/log\")\n", + "print(\" SDK: monitoring.compute_log_metrics(project, feature_service_name)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Compute log metrics (SDK)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment when you have a feature service with logging enabled\n", + "#\n", + "# result = monitoring.compute_log_metrics(\n", + "# project=\"monitoring_demo\",\n", + "# feature_service_name=\"driver_service\",\n", + "# granularity=\"daily\",\n", + "# )\n", + "# print(result)\n", + "\n", + "# Or auto-compute all log metrics\n", + "# result = monitoring.auto_compute_log_metrics(project=\"monitoring_demo\")\n", + "# print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read log vs. batch metrics side-by-side" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Uncomment the cell above once log metrics have been computed.\n" + ] + } + ], + "source": [ + "# Compare batch vs. log metrics for the same feature\n", + "#\n", + "# batch = monitoring.get_feature_metrics(\n", + "# project=\"monitoring_demo\",\n", + "# feature_view_name=\"driver_stats\",\n", + "# feature_name=\"conv_rate\",\n", + "# data_source_type=\"batch\",\n", + "# granularity=\"daily\",\n", + "# )\n", + "#\n", + "# log = monitoring.get_feature_metrics(\n", + "# project=\"monitoring_demo\",\n", + "# feature_view_name=\"driver_stats\",\n", + "# feature_name=\"conv_rate\",\n", + "# data_source_type=\"log\",\n", + "# granularity=\"daily\",\n", + "# )\n", + "#\n", + "# print(\"Batch metrics:\")\n", + "# for m in batch[:3]:\n", + "# print(f\" {m['metric_date']}: mean={m['mean']:.4f}\")\n", + "#\n", + "# print(\"\\nLog metrics:\")\n", + "# for m in log[:3]:\n", + "# print(f\" {m['metric_date']}: mean={m['mean']:.4f}\")\n", + "\n", + "print(\"Uncomment the cell above once log metrics have been computed.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 12: Scheduling in Production\n", + "\n", + "### Cron (simplest)\n", + "\n", + "```bash\n", + "# Compute all batch + log metrics daily at 2 AM\n", + "0 2 * * * cd /path/to/feast/repo && feast monitor run --source-type all >> /var/log/feast-monitor.log 2>&1\n", + "```\n", + "\n", + "### Airflow\n", + "\n", + "```python\n", + "from airflow.operators.bash import BashOperator\n", + "\n", + "monitor_task = BashOperator(\n", + " task_id=\"feast_monitor\",\n", + " bash_command=\"feast monitor run --source-type all\",\n", + " cwd=\"/path/to/feast/repo\",\n", + ")\n", + "```\n", + "\n", + "### Kubernetes CronJob\n", + "\n", + "```yaml\n", + "apiVersion: batch/v1\n", + "kind: CronJob\n", + "metadata:\n", + " name: feast-monitor\n", + "spec:\n", + " schedule: \"0 2 * * *\"\n", + " jobTemplate:\n", + " spec:\n", + " template:\n", + " spec:\n", + " containers:\n", + " - name: feast-monitor\n", + " image: feast-image:latest\n", + " command: [\"feast\", \"monitor\", \"run\", \"--source-type\", \"all\"]\n", + " volumeMounts:\n", + " - name: feast-repo\n", + " mountPath: /feast/repo\n", + " restartPolicy: OnFailure\n", + " volumes:\n", + " - name: feast-repo\n", + " configMap:\n", + " name: feast-repo-config\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "| Capability | CLI | REST API | SDK |\n", + "|-----------|-----|----------|-----|\n", + "| Auto-compute (all granularities) | `feast monitor run` | `POST /monitoring/auto_compute` | `monitoring.auto_compute_metrics()` |\n", + "| Targeted compute | `feast monitor run --feature-view X --granularity daily` | `POST /monitoring/compute` | `monitoring.compute_metrics()` |\n", + "| Set baseline | `feast monitor run --set-baseline` | `POST /monitoring/compute` (with `set_baseline: true`) | `monitoring.compute_metrics(set_baseline=True)` |\n", + "| Log metrics | `feast monitor run --source-type log` | `POST /monitoring/compute/log` | `monitoring.compute_log_metrics()` |\n", + "| On-demand exploration | — | `POST /monitoring/compute/transient` | `monitoring.compute_transient()` |\n", + "| Read metrics | — | `GET /monitoring/metrics/*` | `monitoring.get_feature_metrics()` etc. |\n", + "| Read baseline | — | `GET /monitoring/metrics/baseline` | `monitoring.get_baseline()` |\n", + "| Time-series | — | `GET /monitoring/metrics/timeseries` | `monitoring.get_timeseries()` |" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv312", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/rag-retriever/README.md b/examples/rag-retriever/README.md index 4c9eb9bf8c2..7df89957cfa 100644 --- a/examples/rag-retriever/README.md +++ b/examples/rag-retriever/README.md @@ -62,6 +62,59 @@ Navigate to the examples/rag-retriever directory. Here you will find the followi Open `rag_feast.ipynb` and follow the steps in the notebook to run the example. +## Using DocEmbedder for Simplified Ingestion + +As an alternative to the manual data preparation steps in the notebook above, Feast provides the `DocEmbedder` class that automates the entire document-to-embeddings pipeline: chunking, embedding generation, FeatureView creation, and writing to the online store. + +### Install Dependencies + +```bash +pip install feast[milvus,rag] +``` + +### Quick Start + +```python +from feast import DocEmbedder +from datasets import load_dataset + +# Load your dataset +dataset = load_dataset("facebook/wiki_dpr", "psgs_w100.nq.exact", split="train[:1%]", + with_index=False, trust_remote_code=True) +df = dataset.select(range(100)).to_pandas() + +# DocEmbedder handles everything in one step +embedder = DocEmbedder( + repo_path="feature_repo_docembedder/", + feature_view_name="text_feature_view", +) + +result = embedder.embed_documents( + documents=df, + id_column="id", + source_column="text", + column_mapping=("text", "text_embedding"), +) +``` + +### What DocEmbedder Does + +1. **Generates a FeatureView**: Automatically creates a Python file with Entity and FeatureView definitions compatible with `feast apply` +2. **Applies the repo**: Registers the FeatureView in the Feast registry and deploys infrastructure (e.g., Milvus collection) +3. **Chunks documents**: Splits text into smaller passages using `TextChunker` (configurable chunk size, overlap, etc.) +4. **Generates embeddings**: Produces vector embeddings using `MultiModalEmbedder` (defaults to `all-MiniLM-L6-v2`) +5. **Writes to online store**: Stores the processed data in your configured online store (e.g., Milvus) + +### Customization + +* **Custom Chunker**: Subclass `BaseChunker` for your own chunking strategy +* **Custom Embedder**: Subclass `BaseEmbedder` to use a different embedding model +* **Logical Layer Function**: Provide a `SchemaTransformFn` to control how the output maps to your FeatureView schema + +### Example Notebook + +See **`rag_feast_docembedder.ipynb`** for a complete end-to-end example that uses DocEmbedder with the Wiki DPR dataset and then queries the results using `FeastRAGRetriever`. + ## FeastRagRetriver Low Level Design Low level design for feast rag retriever diff --git a/examples/rag-retriever/rag_feast_docembedder.ipynb b/examples/rag-retriever/rag_feast_docembedder.ipynb new file mode 100644 index 00000000000..47728fef556 --- /dev/null +++ b/examples/rag-retriever/rag_feast_docembedder.ipynb @@ -0,0 +1,648 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "2855fd1a", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install --quiet feast[milvus] sentence-transformers datasets\n", + "# %pip install bigtree==0.19.2\n", + "# %pip install marshmallow==3.10.0 " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3bb14cf1", + "metadata": {}, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "# load wikipedia dataset - 1% of the training split\n", + "dataset = load_dataset(\n", + " \"facebook/wiki_dpr\",\n", + " \"psgs_w100.nq.exact\",\n", + " split=\"train[:1%]\",\n", + " with_index=False,\n", + " trust_remote_code=True,\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "92a5e18c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idtexttitleembeddings
01Aaron Aaron ( or ; \"Ahärôn\") is a prophet, hig...Aaron[0.013342111, 0.58217376, -0.31309745, -0.6991...
12God at Sinai granted Aaron the priesthood for ...Aaron[-0.19236332, 0.539003, -0.5652932, -0.5195250...
23his rod turn into a snake. Then he stretched o...Aaron[-0.23045847, 0.28877887, -0.3449004, -0.14077...
34however, Aaron and Hur remained below to look ...Aaron[0.107315615, 0.5992388, -0.37498242, -0.53419...
45Aaron and his sons to the priesthood, and arra...Aaron[0.32623303, 0.51600194, -0.5568064, -0.494033...
\n", + "
" + ], + "text/plain": [ + " id text title \\\n", + "0 1 Aaron Aaron ( or ; \"Ahärôn\") is a prophet, hig... Aaron \n", + "1 2 God at Sinai granted Aaron the priesthood for ... Aaron \n", + "2 3 his rod turn into a snake. Then he stretched o... Aaron \n", + "3 4 however, Aaron and Hur remained below to look ... Aaron \n", + "4 5 Aaron and his sons to the priesthood, and arra... Aaron \n", + "\n", + " embeddings \n", + "0 [0.013342111, 0.58217376, -0.31309745, -0.6991... \n", + "1 [-0.19236332, 0.539003, -0.5652932, -0.5195250... \n", + "2 [-0.23045847, 0.28877887, -0.3449004, -0.14077... \n", + "3 [0.107315615, 0.5992388, -0.37498242, -0.53419... \n", + "4 [0.32623303, 0.51600194, -0.5568064, -0.494033... " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset.column_names\n", + "df = dataset.select(range(100)).to_pandas()\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "088eaf84", + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "import os\n", + "\n", + "\n", + "def write_feature_store_yaml(file_path: str, project_name: str) -> str:\n", + " \"\"\"\n", + " Write a feature_store.yaml file to the specified path.\n", + "\n", + " Args:\n", + " file_path: Full path where the YAML file should be written\n", + " (e.g. \"feature_repo/feature_store.yaml\").\n", + " project_name: The project name to use in the YAML.\n", + "\n", + " Returns:\n", + " The absolute path of the written file.\n", + " \"\"\"\n", + " config = {\n", + " \"project\": project_name,\n", + " \"provider\": \"local\",\n", + " \"registry\": \"data/registry.db\",\n", + " \"online_store\": {\n", + " \"type\": \"milvus\",\n", + " \"host\": \"http://localhost\",\n", + " \"port\": 19530,\n", + " \"vector_enabled\": True,\n", + " \"embedding_dim\": 384,\n", + " \"index_type\": \"FLAT\",\n", + " \"metric_type\": \"COSINE\",\n", + " },\n", + " \"offline_store\": {\n", + " \"type\": \"file\",\n", + " },\n", + " \"entity_key_serialization_version\": 3,\n", + " \"auth\": {\n", + " \"type\": \"no_auth\",\n", + " },\n", + " }\n", + "\n", + " os.makedirs(os.path.dirname(os.path.abspath(file_path)), exist_ok=True)\n", + "\n", + " with open(file_path, \"w\") as f:\n", + " yaml.dump(config, f, default_flow_style=False, sort_keys=False)\n", + "\n", + " return os.path.abspath(file_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f951c804", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mkdir: feature_repo_docebedder: File exists\n", + "/Users/chpatel/projects/feast/examples/rag-retriever\n" + ] + } + ], + "source": [ + "%mkdir feature_repo_docebedder\n", + "!pwd" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "27be0f7e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "YAML written to: /Users/chpatel/projects/feast/examples/rag-retriever/feature_repo_docebedder/feature_store.yaml\n" + ] + } + ], + "source": [ + "path = write_feature_store_yaml(\"feature_repo_docebedder/feature_store.yaml\", \"my_project\")\n", + "print(f\"YAML written to: {path}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a19428c3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No project found in the repository. Using project name my_project defined in feature_store.yaml\n", + "Applying changes for project my_project\n", + "Connecting to Milvus remotely at http://localhost:19530\n", + "Deploying infrastructure for \u001b[1m\u001b[32mtext_feature_view\u001b[0m\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/chpatel/projects/feast/sdk/python/feast/infra/online_stores/milvus_online_store/milvus.py:86: UserWarning: Field name \"vector_enabled\" in \"MilvusOnlineStoreConfig\" shadows an attribute in parent \"VectorStoreConfig\"\n", + " class MilvusOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig):\n" + ] + } + ], + "source": [ + "from feast import DocEmbedder\n", + "\n", + "de = DocEmbedder(repo_path=\"feature_repo_docebedder\", feature_view_name=\"text_feature_view\",yaml_file=\"feature_store.yaml\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ed217e95", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b19b54476308402eaa251a88fc098300", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Batches: 0%| | 0/4 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
passage_idtextembeddingevent_timestampsource_id
01_0Aaron Aaron ( or ; \"Ahärôn\") is a prophet, hig...[0.002557202707976103, 0.12003513425588608, -0...2026-02-11 12:26:29.098091+00:001
11_1Israelites, Aaron served as his brother's spok...[-0.01853535883128643, 0.13290095329284668, -0...2026-02-11 12:26:29.098091+00:001
22_0God at Sinai granted Aaron the priesthood for ...[0.014343681745231152, 0.10290483385324478, -0...2026-02-11 12:26:29.098091+00:002
32_1could not speak well, God appointed Aaron as M...[0.0504433810710907, 0.1175316572189331, -0.00...2026-02-11 12:26:29.098091+00:002
43_0his rod turn into a snake. Then he stretched o...[-0.06228446215391159, 0.10652626305818558, 0....2026-02-11 12:26:29.098091+00:003
..................
19598_1State College before entering Columbia Univers...[0.03597380220890045, 0.04296444356441498, 0.0...2026-02-11 12:26:29.098091+00:0098
19699_0joined the Merchant Marine to earn money to co...[0.05798682942986488, -0.007653537206351757, -...2026-02-11 12:26:29.098091+00:0099
19799_1spent several months in a mental institution a...[0.05905637890100479, 0.030195411294698715, -0...2026-02-11 12:26:29.098091+00:0099
198100_0harboring stolen goods in his dorm room. It wa...[-0.005938616115599871, 0.02653227001428604, -...2026-02-11 12:26:29.098091+00:00100
199100_1Eugene to party meetings. Ginsberg later said ...[0.007752032019197941, 0.06832979619503021, 0....2026-02-11 12:26:29.098091+00:00100
\n", + "

200 rows × 5 columns

\n", + "" + ], + "text/plain": [ + " passage_id text \\\n", + "0 1_0 Aaron Aaron ( or ; \"Ahärôn\") is a prophet, hig... \n", + "1 1_1 Israelites, Aaron served as his brother's spok... \n", + "2 2_0 God at Sinai granted Aaron the priesthood for ... \n", + "3 2_1 could not speak well, God appointed Aaron as M... \n", + "4 3_0 his rod turn into a snake. Then he stretched o... \n", + ".. ... ... \n", + "195 98_1 State College before entering Columbia Univers... \n", + "196 99_0 joined the Merchant Marine to earn money to co... \n", + "197 99_1 spent several months in a mental institution a... \n", + "198 100_0 harboring stolen goods in his dorm room. It wa... \n", + "199 100_1 Eugene to party meetings. Ginsberg later said ... \n", + "\n", + " embedding \\\n", + "0 [0.002557202707976103, 0.12003513425588608, -0... \n", + "1 [-0.01853535883128643, 0.13290095329284668, -0... \n", + "2 [0.014343681745231152, 0.10290483385324478, -0... \n", + "3 [0.0504433810710907, 0.1175316572189331, -0.00... \n", + "4 [-0.06228446215391159, 0.10652626305818558, 0.... \n", + ".. ... \n", + "195 [0.03597380220890045, 0.04296444356441498, 0.0... \n", + "196 [0.05798682942986488, -0.007653537206351757, -... \n", + "197 [0.05905637890100479, 0.030195411294698715, -0... \n", + "198 [-0.005938616115599871, 0.02653227001428604, -... \n", + "199 [0.007752032019197941, 0.06832979619503021, 0.... \n", + "\n", + " event_timestamp source_id \n", + "0 2026-02-11 12:26:29.098091+00:00 1 \n", + "1 2026-02-11 12:26:29.098091+00:00 1 \n", + "2 2026-02-11 12:26:29.098091+00:00 2 \n", + "3 2026-02-11 12:26:29.098091+00:00 2 \n", + "4 2026-02-11 12:26:29.098091+00:00 3 \n", + ".. ... ... \n", + "195 2026-02-11 12:26:29.098091+00:00 98 \n", + "196 2026-02-11 12:26:29.098091+00:00 99 \n", + "197 2026-02-11 12:26:29.098091+00:00 99 \n", + "198 2026-02-11 12:26:29.098091+00:00 100 \n", + "199 2026-02-11 12:26:29.098091+00:00 100 \n", + "\n", + "[200 rows x 5 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "de.embed_documents(documents=df, id_column=\"id\", source_column=\"text\", column_mapping= (\"text\", \"text_embedding\"))" + + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b25b69df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/Users/chpatel/projects/feast/examples/rag-retriever/feature_repo_docebedder\n" + ] + } + ], + "source": [ + "%cd feature_repo_docebedder" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "5bf57671", + "metadata": {}, + "outputs": [], + "source": [ + "from feast import FeatureStore\n", + "import pandas as pd\n", + "\n", + "store = FeatureStore(repo_path=\".\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2bd1f1da", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "92de6524b74c4a98ac1b56668926681a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Loading checkpoint shards: 0%| | 0/2 [00:00:241: DeprecationWarning: builtin type SwigPyPacked has no __module__ attribute\n", + ":241: DeprecationWarning: builtin type SwigPyObject has no __module__ attribute\n", + ":241: DeprecationWarning: builtin type swigvarlink has no __module__ attribute\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.append(\"..\")\n", + "from text_feature_view import text_feature_view\n", + "from feast.vector_store import FeastVectorStore\n", + "from feast.rag_retriever import FeastIndex, FeastRAGRetriever\n", + "\n", + "generator_config=generator_model.config\n", + "question_encoder = AutoModel.from_pretrained(\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "question_encoder_tokenizer = AutoTokenizer.from_pretrained(\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "\n", + "\n", + "query_encoder_config = {\n", + " \"model_type\": \"bert\",\n", + " \"hidden_size\": 384\n", + "}\n", + "\n", + "vector_store = FeastVectorStore(\n", + " repo_path=\".\",\n", + " rag_view=text_feature_view,\n", + " features=[\"text_feature_view:text\", \"text_feature_view:embedding\", \"text_feature_view:passage_id\",\"text_feature_view:source_id\"]\n", + ")\n", + "\n", + "feast_index = FeastIndex()\n", + "\n", + "config = RagConfig(\n", + " question_encoder=query_encoder_config,\n", + " generator=generator_config.to_dict(),\n", + " index=feast_index\n", + ")\n", + "retriever = FeastRAGRetriever(\n", + " question_encoder=question_encoder,\n", + " question_encoder_tokenizer=question_encoder_tokenizer,\n", + " generator_tokenizer=generator_tokenizer,\n", + " feast_repo_path=\".\",\n", + " feature_view=vector_store.rag_view,\n", + " features=vector_store.features,\n", + " generator_model=generator_model, \n", + " search_type=\"vector\",\n", + " id_field=\"passage_id\",\n", + " text_field=\"text\",\n", + " config=config,\n", + " index=feast_index,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "09793dd4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting to Milvus remotely at http://localhost:19530\n", + "Generated Answer: Context: \n", + "\n", + "Question: What is the capital of Ireland?\n", + "\n", + "Answer: The capital of Ireland is Dublin.\n", + "\n", + "Context: \n", + "\n", + "Question: What is the capital of Ireland?\n", + "\n", + "Answer: The capital of Ireland is Dublin.\n", + "\n", + "Context: \n", + "\n", + "Question: What is the capital city of Australia?\n", + "\n", + "Answer: The capital city of Australia is Canberra.\n", + "\n", + "Context: \n", + "\n", + "Question: What is the capital of Ireland?\n", + "\n", + "Answer: The capital of I\n" + ] + } + ], + "source": [ + "query = \"What is the capital of Ireland?\"\n", + "answer = retriever.generate_answer(query, top_k=10)\n", + "print(\"Generated Answer:\", answer)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/go.mod b/go.mod index d59d6cfa4b3..4de94b829d6 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/feast-dev/feast -go 1.24.0 - -toolchain go1.24.4 +go 1.25.0 require ( cloud.google.com/go/storage v1.58.0 @@ -21,24 +19,24 @@ require ( github.com/mattn/go-sqlite3 v1.14.23 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 - github.com/redis/go-redis/v9 v9.6.1 + github.com/redis/go-redis/v9 v9.20.0 github.com/roberson-io/mmh3 v0.0.0-20190729202758-fdfce3ba6225 github.com/rs/zerolog v1.33.0 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/otel v1.38.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 - go.opentelemetry.io/otel/sdk v1.38.0 - go.opentelemetry.io/otel/trace v1.38.0 - golang.org/x/sync v0.18.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba - google.golang.org/grpc v1.76.0 - google.golang.org/protobuf v1.36.10 + go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 + go.opentelemetry.io/otel/sdk v1.44.0 + go.opentelemetry.io/otel/trace v1.44.0 + golang.org/x/sync v0.20.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa + google.golang.org/grpc v1.81.1 + google.golang.org/protobuf v1.36.11 ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.123.0 // indirect cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -46,7 +44,7 @@ require ( cloud.google.com/go/iam v1.5.3 // indirect cloud.google.com/go/monitoring v1.24.2 // indirect filippo.io/edwards25519 v1.1.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 // indirect github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect @@ -71,13 +69,12 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect + github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect - github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.1.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/goccy/go-json v0.10.3 // indirect @@ -87,13 +84,13 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/klauspost/asmfmt v1.3.2 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect @@ -105,32 +102,32 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.66.1 // indirect github.com/prometheus/procfs v0.16.1 // indirect - github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect + github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/zeebo/errs v1.4.0 // indirect - github.com/zeebo/xxh3 v1.0.2 // indirect + github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.42.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.1 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.45.0 // indirect + golang.org/x/crypto v0.51.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.55.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/tools v0.44.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/api v0.256.0 // indirect google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b9112cc4961..f936e04c8f5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4= @@ -22,8 +22,8 @@ cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4 cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0 h1:xfK3bbi6F2RDtaZFtUdKO3osOBIhNb+xTs8lFW6yx9o= @@ -94,29 +94,27 @@ github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1x github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= -github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= -github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= -github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= -github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= -github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= -github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= +github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI= -github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -155,8 +153,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -171,8 +169,8 @@ github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -224,8 +222,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= -github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/redis/go-redis/v9 v9.20.0 h1:WnQYxLkgO2xiXTCJY0ldIiI8dNqCDlQAG+AtaH7a2a0= +github.com/redis/go-redis/v9 v9.20.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA= github.com/roberson-io/mmh3 v0.0.0-20190729202758-fdfce3ba6225 h1:ZMsPCp7oYgjoIFt1c+sM2qojxZXotSYcMF8Ur9/LJlM= github.com/roberson-io/mmh3 v0.0.0-20190729202758-fdfce3ba6225/go.mod h1:XEESr+X1SY8ZSuc3jqsTlb3clCkqQJ4DcF3Qxv1N3PM= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -236,8 +234,8 @@ github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWR github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= -github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= +github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -250,88 +248,89 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= -github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= -github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= +github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= -go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= +go.opentelemetry.io/contrib/detectors/gcp v1.42.0 h1:kpt2PEJuOuqYkPcktfJqWWDjTEd/FNgrxcniL7kQrXQ= +go.opentelemetry.io/contrib/detectors/gcp v1.42.0/go.mod h1:W9zQ439utxymRrXsUOzZbFX4JhLxXU4+ZnCt8GG7yA8= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 h1:wm/Q0GAAykXv83wzcKzGGqAnnfLFyFe7RslekZuv+VI= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0/go.mod h1:ra3Pa40+oKjvYh+ZD3EdxFZZB0xdMfuileHAm4nNN7w= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa h1:efT73AJZfAAUV7SOip6pWGkwJDzIGiKBZGVzHYa+ve4= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.256.0 h1:u6Khm8+F9sxbCTYNoBHg6/Hwv0N/i+V94MvkOSor6oI= google.golang.org/api v0.256.0/go.mod h1:KIgPhksXADEKJlnEoRa9qAII4rXcy40vfI8HRqcU964= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 h1:LvZVVaPE0JSqL+ZWb6ErZfnEOKIqqFWUJE2D0fObSmc= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9/go.mod h1:QFOrLhdAe2PsTp3vQY4quuLKTi9j3XG3r6JPPaw7MSc= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= -google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/go/infra/docker/feature-server/Dockerfile b/go/infra/docker/feature-server/Dockerfile index b1fcda18c9b..3f7a2ab7b94 100644 --- a/go/infra/docker/feature-server/Dockerfile +++ b/go/infra/docker/feature-server/Dockerfile @@ -1,4 +1,5 @@ -FROM golang:1.24.12 +FROM golang:1.25 +ENV GOTOOLCHAIN=auto # Update the package list and install the ca-certificates package RUN apt-get update && apt-get install -y ca-certificates diff --git a/go/internal/feast/metrics/metrics.go b/go/internal/feast/metrics/metrics.go index 804eef6fa1b..d4783f257b7 100644 --- a/go/internal/feast/metrics/metrics.go +++ b/go/internal/feast/metrics/metrics.go @@ -30,7 +30,6 @@ var ( TimeHistogramType = reflect.TypeOf((*TimeHistogram)(nil)).Elem() ) - func RegisterTimeHistogram(name, help, namespace string, labelNames []string, tag reflect.StructTag) (func(prometheus.Labels) interface{}, prometheus.Collector, error) { f, collector, err := prometheusvanilla.BuildHistogram(name, help, namespace, labelNames, tag) if err != nil { diff --git a/go/internal/feast/onlineserving/serving.go b/go/internal/feast/onlineserving/serving.go index ff70443015a..1ce5f6c555c 100644 --- a/go/internal/feast/onlineserving/serving.go +++ b/go/internal/feast/onlineserving/serving.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "errors" "fmt" + "regexp" "sort" "strings" @@ -20,6 +21,8 @@ import ( "github.com/feast-dev/feast/go/types" ) +var versionTagRegex = regexp.MustCompile(`^[vV]\d+$`) + /* FeatureVector type represent result of retrieving single feature for multiple rows. It can be imagined as a column in output dataframe / table. @@ -492,6 +495,18 @@ func ParseFeatureReference(featureRef string) (featureViewName, featureName stri featureViewName = parsedFeatureName[0] featureName = parsedFeatureName[1] } + + // Handle @version qualifier on feature view name + if atIdx := strings.Index(featureViewName, "@"); atIdx >= 0 { + suffix := featureViewName[atIdx+1:] + if versionTagRegex.MatchString(suffix) { + e = fmt.Errorf("versioned feature refs (@%s) are not supported by the Go feature server", suffix) + return + } + if strings.EqualFold(suffix, "latest") { + featureViewName = featureViewName[:atIdx] + } + } return } diff --git a/go/internal/feast/onlinestore/dynamodbonlinestore.go b/go/internal/feast/onlinestore/dynamodbonlinestore.go index e6d620ee10c..235449bfdf2 100644 --- a/go/internal/feast/onlinestore/dynamodbonlinestore.go +++ b/go/internal/feast/onlinestore/dynamodbonlinestore.go @@ -53,7 +53,7 @@ func NewDynamodbOnlineStore(project string, config *registry.RepoConfig, onlineS ctx := context.Background() cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { - panic(err) + return nil, err } store.client = dynamodb.NewFromConfig(cfg) @@ -237,24 +237,64 @@ func (d *DynamodbOnlineStore) OnlineRead(ctx context.Context, entityKeys []*type // process response from dynamodb for j := 0; j < batchSize; j++ { - entityId := Responses[j]["entity_id"].(*dtypes.AttributeValueMemberS).Value - timestampString := Responses[j]["event_ts"].(*dtypes.AttributeValueMemberS).Value + entityIdAttr, ok := Responses[j]["entity_id"] + if !ok || entityIdAttr == nil { + continue + } + entityIdMember, ok := entityIdAttr.(*dtypes.AttributeValueMemberS) + if !ok { + return fmt.Errorf("unexpected DynamoDB attribute type for 'entity_id' in table %s", tableName) + } + entityId := entityIdMember.Value + + tsAttr, ok := Responses[j]["event_ts"] + if !ok || tsAttr == nil { + continue + } + tsMember, ok := tsAttr.(*dtypes.AttributeValueMemberS) + if !ok { + return fmt.Errorf("unexpected DynamoDB attribute type for 'event_ts' in table %s", tableName) + } + timestampString := tsMember.Value + t, err := time.Parse("2006-01-02 15:04:05-07:00", timestampString) if err != nil { return err } timeStamp := timestamppb.New(t) - featureValues := Responses[j]["values"].(*dtypes.AttributeValueMemberM).Value + rawValues, ok := Responses[j]["values"] + if !ok || rawValues == nil { + continue + } + valuesMap, ok := rawValues.(*dtypes.AttributeValueMemberM) + if !ok { + return fmt.Errorf("unexpected DynamoDB attribute type for 'values' in table %s", tableName) + } + featureValues := valuesMap.Value entityIndex := entityIndexMap[entityId] for _, featureName := range featureNames { - featureValue := featureValues[featureName].(*dtypes.AttributeValueMemberB).Value + featureIndex := featureNamesIndex[featureName] + rawVal, exists := featureValues[featureName] + if !exists || rawVal == nil { + mu.Lock() + results[entityIndex][featureIndex] = FeatureData{ + Reference: serving.FeatureReferenceV2{FeatureViewName: featureViewName, FeatureName: featureName}, + Timestamp: timestamppb.Timestamp{Seconds: timeStamp.Seconds, Nanos: timeStamp.Nanos}, + Value: types.Value{Val: &types.Value_NullVal{NullVal: types.Null_NULL}}, + } + mu.Unlock() + continue + } + memberB, ok := rawVal.(*dtypes.AttributeValueMemberB) + if !ok { + return fmt.Errorf("unexpected DynamoDB attribute type for feature %q in view %q", featureName, featureViewName) + } var value types.Value - if err := proto.Unmarshal(featureValue, &value); err != nil { + if err := proto.Unmarshal(memberB.Value, &value); err != nil { return err } - featureIndex := featureNamesIndex[featureName] mu.Lock() results[entityIndex][featureIndex] = FeatureData{Reference: serving.FeatureReferenceV2{FeatureViewName: featureViewName, FeatureName: featureName}, diff --git a/go/internal/feast/onlinestore/postgresonlinestore.go b/go/internal/feast/onlinestore/postgresonlinestore.go index a05e21df775..4077a9e06fa 100644 --- a/go/internal/feast/onlinestore/postgresonlinestore.go +++ b/go/internal/feast/onlinestore/postgresonlinestore.go @@ -166,7 +166,7 @@ func buildPostgresConnString(config map[string]interface{}) string { if sslMode, ok := config["sslmode"].(string); ok && sslMode != "" { query.Set("sslmode", sslMode) } else { - query.Set("sslmode", "disable") + query.Set("sslmode", "require") } if v, ok := config["sslcert_path"].(string); ok && v != "" { @@ -194,4 +194,4 @@ func buildPostgresConnString(config map[string]interface{}) string { } return connURL.String() -} \ No newline at end of file +} diff --git a/go/internal/feast/onlinestore/postgresonlinestore_test.go b/go/internal/feast/onlinestore/postgresonlinestore_test.go index 2d81ba2cddb..b241e857e18 100644 --- a/go/internal/feast/onlinestore/postgresonlinestore_test.go +++ b/go/internal/feast/onlinestore/postgresonlinestore_test.go @@ -34,7 +34,7 @@ func TestBuildPostgresConnStringDefaults(t *testing.T) { } connStr := buildPostgresConnString(config) assert.Contains(t, connStr, "localhost:5432") - assert.Contains(t, connStr, "sslmode=disable") + assert.Contains(t, connStr, "sslmode=require") } func TestBuildPostgresConnStringWithSSL(t *testing.T) { diff --git a/go/internal/feast/registry/registry.go b/go/internal/feast/registry/registry.go index 51aa031bbda..3ff94807049 100644 --- a/go/internal/feast/registry/registry.go +++ b/go/internal/feast/registry/registry.go @@ -81,6 +81,10 @@ func (r *Registry) InitializeRegistry() error { } func (r *Registry) RefreshRegistryOnInterval() { + if r.cachedRegistryProtoTtl <= 0 { + log.Info().Msg("Registry cache TTL is non-positive; skipping periodic refresh") + return + } ticker := time.NewTicker(r.cachedRegistryProtoTtl) for ; true; <-ticker.C { err := r.refresh() diff --git a/go/internal/feast/registry/registry_test.go b/go/internal/feast/registry/registry_test.go index 6f75dbbbeb2..0f5d1c20ea7 100644 --- a/go/internal/feast/registry/registry_test.go +++ b/go/internal/feast/registry/registry_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/stretchr/testify/assert" ) func TestCloudRegistryStores(t *testing.T) { @@ -99,6 +100,24 @@ func TestCloudRegistryStores(t *testing.T) { } } +func TestRefreshRegistryOnIntervalNonPositiveTTL(t *testing.T) { + tests := []struct { + name string + ttl time.Duration + }{ + {name: "zero ttl", ttl: 0}, + {name: "negative ttl", ttl: -1 * time.Second}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := &Registry{cachedRegistryProtoTtl: test.ttl} + assert.NotPanics(t, func() { + r.RefreshRegistryOnInterval() + }) + }) + } +} + // MockS3Client is mock client for testing S3 registry store type MockS3Client struct { GetObjectFn func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) diff --git a/go/internal/feast/server/http_server.go b/go/internal/feast/server/http_server.go index adfd40110e7..876f42f846b 100644 --- a/go/internal/feast/server/http_server.go +++ b/go/internal/feast/server/http_server.go @@ -2,6 +2,7 @@ package server import ( "context" + "crypto/tls" "encoding/json" "fmt" "net/http" @@ -396,6 +397,34 @@ func (s *httpServer) Serve(host string, port int) error { return err } +func (s *httpServer) ServeTLS(host string, port int, certFile string, keyFile string) error { + mux := http.NewServeMux() + mux.Handle("/get-online-features", metricsMiddleware(recoverMiddleware(http.HandlerFunc(s.getOnlineFeatures)))) + mux.Handle("/health", metricsMiddleware(http.HandlerFunc(healthCheckHandler))) + s.server = &http.Server{ + Addr: fmt.Sprintf("%s:%d", host, port), + Handler: mux, + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 15 * time.Second, + TLSConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + CurvePreferences: []tls.CurveID{ + tls.CurveP256, + tls.X25519MLKEM768, + //tls.SecP256r1MLKEM768, // Only available in Go 1.26 + }, + }, + } + err := s.server.ListenAndServeTLS(certFile, keyFile) + // Don't return the error if it's caused by graceful shutdown using Stop() + if err == http.ErrServerClosed { + return nil + } + log.Fatal().Stack().Err(err).Msg("Failed to start HTTPS server") + return err +} + func healthCheckHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Healthy") diff --git a/go/main.go b/go/main.go index f49a27efa46..7f89fe66c3b 100644 --- a/go/main.go +++ b/go/main.go @@ -11,6 +11,7 @@ import ( "strings" "sync" "syscall" + "time" "github.com/feast-dev/feast/go/internal/feast" "github.com/feast-dev/feast/go/internal/feast/registry" @@ -36,15 +37,28 @@ import ( var tracer trace.Tracer +var newSignalStopChannel = func() (chan os.Signal, func()) { + stop := make(chan os.Signal, 1) + signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) + return stop, func() { + signal.Stop(stop) + } +} + type ServerStarter interface { StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions) error StartGrpcServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions) error + StartHttpsServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions, certFile string, keyFile string) error } type RealServerStarter struct{} func (s *RealServerStarter) StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions) error { - return StartHttpServer(fs, host, port, metricsPort, writeLoggedFeaturesCallback, loggingOpts) + return StartHttpServer(fs, host, port, metricsPort, writeLoggedFeaturesCallback, loggingOpts, false, "", "") +} + +func (s *RealServerStarter) StartHttpsServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions, certFile string, keyFile string) error { + return StartHttpServer(fs, host, port, metricsPort, writeLoggedFeaturesCallback, loggingOpts, true, certFile, keyFile) } func (s *RealServerStarter) StartGrpcServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions) error { @@ -58,18 +72,22 @@ func main() { port := 8080 metricsPort := 9090 server := RealServerStarter{} + certFile := "" + keyFile := "" // Current Directory repoPath, err := os.Getwd() if err != nil { log.Error().Stack().Err(err).Msg("Failed to get current directory") } - flag.StringVar(&serverType, "type", serverType, "Specify the server type (http or grpc)") + flag.StringVar(&serverType, "type", serverType, "Specify the server type (http, https or grpc)") flag.StringVar(&repoPath, "chdir", repoPath, "Repository path where feature store yaml file is stored") flag.StringVar(&host, "host", host, "Specify a host for the server") flag.IntVar(&port, "port", port, "Specify a port for the server") flag.IntVar(&metricsPort, "metrics-port", metricsPort, "Specify a port for the metrics server") + flag.StringVar(&certFile, "tls-cert-file", "", "Path to the TLS certificate file") + flag.StringVar(&keyFile, "tls-key-file", "", "Path to the TLS key file") flag.Parse() // Initialize tracer @@ -119,8 +137,10 @@ func main() { err = server.StartHttpServer(fs, host, port, metricsPort, nil, loggingOptions) } else if serverType == "grpc" { err = server.StartGrpcServer(fs, host, port, metricsPort, nil, loggingOptions) + } else if serverType == "https" { + err = server.StartHttpsServer(fs, host, port, metricsPort, nil, loggingOptions, certFile, keyFile) } else { - fmt.Println("Unknown server type. Please specify 'http' or 'grpc'.") + fmt.Println("Unknown server type. Please specify 'http' or 'grpc' or 'https'.") } if err != nil { @@ -227,27 +247,34 @@ func StartGrpcServer(fs *feast.FeatureStore, host string, port int, metricsPort // StartHttpServerWithLogging starts HTTP server with enabled feature logging // Go does not allow direct assignment to package-level functions as a way to // mock them for tests -func StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions) error { +func StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort int, writeLoggedFeaturesCallback logging.OfflineStoreWriteCallback, loggingOpts *logging.LoggingOptions, httpsEnable bool, certFile string, keyFile string) error { + if httpsEnable && (certFile == "" || keyFile == "") { + return fmt.Errorf("--tls-cert-file and --tls-key-file must be provided for HTTPS server.") + } + loggingService, err := constructLoggingService(fs, writeLoggedFeaturesCallback, loggingOpts) if err != nil { return err } ser := server.NewHttpServer(fs, loggingService) log.Info().Msgf("Starting a HTTP server on host %s, port %d", host, port) + // Start metrics server - metricsServer := &http.Server{Addr: fmt.Sprintf(":%d", metricsPort)} + mux := http.NewServeMux() + mux.Handle("/metrics", promhttp.Handler()) + metricsServer := &http.Server{ + Addr: fmt.Sprintf(":%d", metricsPort), + Handler: mux, + } go func() { log.Info().Msgf("Starting metrics server on port %d", metricsPort) - mux := http.NewServeMux() - mux.Handle("/metrics", promhttp.Handler()) - metricsServer.Handler = mux if err := metricsServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Error().Err(err).Msg("Failed to start metrics server") } }() - stop := make(chan os.Signal, 1) - signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) + stop, stopCleanup := newSignalStopChannel() + defer stopCleanup() var wg sync.WaitGroup wg.Add(1) @@ -263,7 +290,9 @@ func StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort log.Error().Err(err).Msg("Error when stopping the HTTP server") } log.Info().Msg("Stopping metrics server...") - if err := metricsServer.Shutdown(context.Background()); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := metricsServer.Shutdown(ctx); err != nil { log.Error().Err(err).Msg("Error stopping metrics server") } if loggingService != nil { @@ -279,7 +308,11 @@ func StartHttpServer(fs *feast.FeatureStore, host string, port int, metricsPort } }() - err = ser.Serve(host, port) + if httpsEnable { + err = ser.ServeTLS(host, port, certFile, keyFile) + } else { + err = ser.Serve(host, port) + } close(serverExited) wg.Wait() return err diff --git a/go/main_test.go b/go/main_test.go index f1f2ae98698..7eb0e0a6676 100644 --- a/go/main_test.go +++ b/go/main_test.go @@ -1,12 +1,28 @@ package main import ( + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "io" + "math/big" + "net" + "net/http" + "os" + "strings" + "syscall" "testing" + "time" "github.com/feast-dev/feast/go/internal/feast" "github.com/feast-dev/feast/go/internal/feast/server/logging" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" ) // MockServerStarter is a mock of ServerStarter interface for testing @@ -67,3 +83,130 @@ func TestConstructLoggingService(t *testing.T) { assert.NoError(t, err) // Further assertions can be added here based on the expected behavior of constructLoggingService } + +func TestStartHttpsServerHealthEndpoint(t *testing.T) { + certPath, keyPath := createSelfSignedTLSFiles(t) + host := "127.0.0.1" + port := getFreePort(t) + metricsPort := getFreePort(t) + + stop := make(chan os.Signal, 1) + prevNewSignalStopChannel := newSignalStopChannel + newSignalStopChannel = func() (chan os.Signal, func()) { + return stop, func() {} + } + t.Cleanup(func() { + newSignalStopChannel = prevNewSignalStopChannel + }) + + errCh := make(chan error, 1) + go func() { + errCh <- StartHttpServer(&feast.FeatureStore{}, host, port, metricsPort, nil, &logging.LoggingOptions{}, true, certPath, keyPath) + }() + + httpsClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //nolint:gosec + }, + } + t.Cleanup(httpsClient.CloseIdleConnections) + + url := fmt.Sprintf("https://%s:%d/health", host, port) + + var ( + resp *http.Response + err error + ) + require.Eventually(t, func() bool { + resp, err = httpsClient.Get(url) + if err != nil { + return false + } + return true + }, 5*time.Second, 100*time.Millisecond) + require.NoError(t, err) + t.Cleanup(func() { + if resp != nil && resp.Body != nil { + _ = resp.Body.Close() + } + }) + + body, readErr := io.ReadAll(resp.Body) + require.NoError(t, readErr) + + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "Healthy", strings.TrimSpace(string(body))) + + stop <- syscall.SIGTERM + + select { + case startErr := <-errCh: + require.NoError(t, startErr) + case <-time.After(5 * time.Second): + t.Fatal("StartHttpsServer did not shutdown within timeout") + } +} + +func TestStartHttpsServerTLSFilesRequired(t *testing.T) { + err := StartHttpServer(&feast.FeatureStore{}, "127.0.0.1", 0, 0, nil, &logging.LoggingOptions{}, true, "", "") + require.Error(t, err) + assert.Contains(t, err.Error(), "--tls-cert-file and --tls-key-file must be provided") +} + +func getFreePort(t *testing.T) int { + t.Helper() + + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + defer func() { + _ = listener.Close() + }() + + addr, ok := listener.Addr().(*net.TCPAddr) + require.True(t, ok) + return addr.Port +} + +func createSelfSignedTLSFiles(t *testing.T) (string, string) { + t.Helper() + + priv, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + tmpl := x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "localhost", + }, + NotBefore: time.Now().Add(-1 * time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + DNSNames: []string{"localhost"}, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + } + + der, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv) + require.NoError(t, err) + + certFile, err := os.CreateTemp(t.TempDir(), "feast-test-cert-*.pem") + require.NoError(t, err) + defer func() { + _ = certFile.Close() + }() + + keyFile, err := os.CreateTemp(t.TempDir(), "feast-test-key-*.pem") + require.NoError(t, err) + defer func() { + _ = keyFile.Close() + }() + + err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: der}) + require.NoError(t, err) + + err = pem.Encode(keyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + require.NoError(t, err) + + return certFile.Name(), keyFile.Name() +} diff --git a/infra/charts/feast-feature-server/Chart.yaml b/infra/charts/feast-feature-server/Chart.yaml index af9895f8ee8..fd31828aa05 100644 --- a/infra/charts/feast-feature-server/Chart.yaml +++ b/infra/charts/feast-feature-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: feast-feature-server description: Feast Feature Server in Go or Python type: application -version: 0.61.0 +version: 0.64.0 keywords: - machine learning - big data diff --git a/infra/charts/feast-feature-server/README.md b/infra/charts/feast-feature-server/README.md index da74f905aa4..595a9bf9ead 100644 --- a/infra/charts/feast-feature-server/README.md +++ b/infra/charts/feast-feature-server/README.md @@ -1,6 +1,6 @@ # Feast Python / Go Feature Server Helm Charts -Current chart version is `0.61.0` +Current chart version is `0.64.0` ## Installation @@ -42,7 +42,7 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/python-helm-d | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"quay.io/feastdev/feature-server"` | Docker image for Feature Server repository | -| image.tag | string | `"0.61.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.64.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | | imagePullSecrets | list | `[]` | | | livenessProbe.initialDelaySeconds | int | `30` | | | livenessProbe.periodSeconds | int | `30` | | diff --git a/infra/charts/feast-feature-server/templates/deployment.yaml b/infra/charts/feast-feature-server/templates/deployment.yaml index 6cd17d4a4d1..ef0cc9671de 100644 --- a/infra/charts/feast-feature-server/templates/deployment.yaml +++ b/infra/charts/feast-feature-server/templates/deployment.yaml @@ -11,10 +11,12 @@ spec: {{- include "feast-feature-server.selectorLabels" . | nindent 6 }} template: metadata: - {{- with .Values.podAnnotations }} + {{- if or .Values.podAnnotations .Values.metrics.enabled }} annotations: + {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} - {{- if .Values.metrics.enabled }} + {{- end }} + {{- if $.Values.metrics.enabled }} instrumentation.opentelemetry.io/inject-python: "true" {{- end }} {{- end }} diff --git a/infra/charts/feast-feature-server/values.yaml b/infra/charts/feast-feature-server/values.yaml index 159ec432163..03a2f1f0b1d 100644 --- a/infra/charts/feast-feature-server/values.yaml +++ b/infra/charts/feast-feature-server/values.yaml @@ -9,7 +9,7 @@ image: repository: quay.io/feastdev/feature-server pullPolicy: IfNotPresent # image.tag -- The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) - tag: 0.61.0 + tag: 0.64.0 logLevel: "WARNING" # Set log level DEBUG, INFO, WARNING, ERROR, and CRITICAL (case-insensitive) diff --git a/infra/charts/feast/Chart.yaml b/infra/charts/feast/Chart.yaml index fee9360d800..881c595ba97 100644 --- a/infra/charts/feast/Chart.yaml +++ b/infra/charts/feast/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 description: Feature store for machine learning name: feast -version: 0.61.0 +version: 0.64.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index bbe86e319cf..afa964c7656 100644 --- a/infra/charts/feast/README.md +++ b/infra/charts/feast/README.md @@ -8,7 +8,7 @@ This repo contains Helm charts for Feast Java components that are being installe ## Chart: Feast -Feature store for machine learning Current chart version is `0.61.0` +Feature store for machine learning Current chart version is `0.64.0` ## Installation @@ -65,8 +65,8 @@ See [here](https://github.com/feast-dev/feast/tree/master/examples/java-demo) fo | Repository | Name | Version | |------------|------|---------| | https://charts.helm.sh/stable | redis | 10.5.6 | -| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.61.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.61.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.64.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.64.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index 57f0e1b918a..7b6e40c3da0 100644 --- a/infra/charts/feast/charts/feature-server/Chart.yaml +++ b/infra/charts/feast/charts/feature-server/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Feast Feature Server: Online feature serving service for Feast" name: feature-server -version: 0.61.0 -appVersion: v0.61.0 +version: 0.64.0 +appVersion: v0.64.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/feature-server/README.md b/infra/charts/feast/charts/feature-server/README.md index 7b31a355b29..04714b14ed2 100644 --- a/infra/charts/feast/charts/feature-server/README.md +++ b/infra/charts/feast/charts/feature-server/README.md @@ -1,6 +1,6 @@ # feature-server -![Version: 0.61.0](https://img.shields.io/badge/Version-0.61.0-informational?style=flat-square) ![AppVersion: v0.61.0](https://img.shields.io/badge/AppVersion-v0.61.0-informational?style=flat-square) +![Version: 0.64.0](https://img.shields.io/badge/Version-0.64.0-informational?style=flat-square) ![AppVersion: v0.64.0](https://img.shields.io/badge/AppVersion-v0.64.0-informational?style=flat-square) Feast Feature Server: Online feature serving service for Feast @@ -17,7 +17,7 @@ Feast Feature Server: Online feature serving service for Feast | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"quay.io/feastdev/feature-server-java"` | Docker image for Feature Server repository | -| image.tag | string | `"0.61.0"` | Image tag | +| image.tag | string | `"0.64.0"` | Image tag | | ingress.grpc.annotations | object | `{}` | Extra annotations for the ingress | | ingress.grpc.auth.enabled | bool | `false` | Flag to enable auth | | ingress.grpc.class | string | `"nginx"` | Which ingress controller to use | diff --git a/infra/charts/feast/charts/feature-server/values.yaml b/infra/charts/feast/charts/feature-server/values.yaml index dc0e5178125..0051f028279 100644 --- a/infra/charts/feast/charts/feature-server/values.yaml +++ b/infra/charts/feast/charts/feature-server/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Feature Server repository repository: quay.io/feastdev/feature-server-java # image.tag -- Image tag - tag: 0.61.0 + tag: 0.64.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/charts/transformation-service/Chart.yaml b/infra/charts/feast/charts/transformation-service/Chart.yaml index 572a3dd84f2..ca053c674bc 100644 --- a/infra/charts/feast/charts/transformation-service/Chart.yaml +++ b/infra/charts/feast/charts/transformation-service/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 description: "Transformation service: to compute on-demand features" name: transformation-service -version: 0.61.0 -appVersion: v0.61.0 +version: 0.64.0 +appVersion: v0.64.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/charts/transformation-service/README.md b/infra/charts/feast/charts/transformation-service/README.md index 27be0d7f33c..f6e39356eee 100644 --- a/infra/charts/feast/charts/transformation-service/README.md +++ b/infra/charts/feast/charts/transformation-service/README.md @@ -1,6 +1,6 @@ # transformation-service -![Version: 0.61.0](https://img.shields.io/badge/Version-0.61.0-informational?style=flat-square) ![AppVersion: v0.61.0](https://img.shields.io/badge/AppVersion-v0.61.0-informational?style=flat-square) +![Version: 0.64.0](https://img.shields.io/badge/Version-0.64.0-informational?style=flat-square) ![AppVersion: v0.64.0](https://img.shields.io/badge/AppVersion-v0.64.0-informational?style=flat-square) Transformation service: to compute on-demand features @@ -13,7 +13,7 @@ Transformation service: to compute on-demand features | envOverrides | object | `{}` | Extra environment variables to set | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | | image.repository | string | `"quay.io/feastdev/feature-transformation-server"` | Docker image for Transformation Server repository | -| image.tag | string | `"0.61.0"` | Image tag | +| image.tag | string | `"0.64.0"` | Image tag | | nodeSelector | object | `{}` | Node labels for pod assignment | | podLabels | object | `{}` | Labels to be added to Feast Serving pods | | replicaCount | int | `1` | Number of pods that will be created | diff --git a/infra/charts/feast/charts/transformation-service/values.yaml b/infra/charts/feast/charts/transformation-service/values.yaml index dc401c66627..af34cfa486d 100644 --- a/infra/charts/feast/charts/transformation-service/values.yaml +++ b/infra/charts/feast/charts/transformation-service/values.yaml @@ -5,7 +5,7 @@ image: # image.repository -- Docker image for Transformation Server repository repository: quay.io/feastdev/feature-transformation-server # image.tag -- Image tag - tag: 0.61.0 + tag: 0.64.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 23bd7bc36d3..8f610567ded 100644 --- a/infra/charts/feast/requirements.yaml +++ b/infra/charts/feast/requirements.yaml @@ -1,12 +1,12 @@ dependencies: - name: feature-server alias: feature-server - version: 0.61.0 + version: 0.64.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.61.0 + version: 0.64.0 condition: transformation-service.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: redis diff --git a/infra/feast-operator/.golangci.bck.yml b/infra/feast-operator/.golangci.bck.yml new file mode 100644 index 00000000000..6c104980d43 --- /dev/null +++ b/infra/feast-operator/.golangci.bck.yml @@ -0,0 +1,55 @@ +run: + timeout: 5m + allow-parallel-runners: true + +issues: + # don't skip warning about doc comments + # don't exclude the default set of lint + exclude-use-default: false + # restore some of the defaults + # (fill in the rest as needed) + exclude-rules: + - path: "api/*" + linters: + - lll + - path: "internal/*" + linters: + - dupl + - lll + - path: "test/*" + linters: + - lll + - path: "upgrade/*" + linters: + - lll + - path: "previous-version/*" + linters: + - lll +linters: + disable-all: true + enable: + - dupl + - errcheck + - goconst + - gocyclo + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - lll + - misspell + - nakedret + - ginkgolinter + - prealloc + - revive + - staticcheck + - typecheck + - unconvert + - unparam + - unused + +linters-settings: + revive: + rules: + - name: comment-spacings diff --git a/infra/feast-operator/.golangci.yml b/infra/feast-operator/.golangci.yml index 6c104980d43..95be6d14177 100644 --- a/infra/feast-operator/.golangci.yml +++ b/infra/feast-operator/.golangci.yml @@ -1,55 +1,67 @@ +version: "2" run: - timeout: 5m allow-parallel-runners: true - -issues: - # don't skip warning about doc comments - # don't exclude the default set of lint - exclude-use-default: false - # restore some of the defaults - # (fill in the rest as needed) - exclude-rules: - - path: "api/*" - linters: - - lll - - path: "internal/*" - linters: - - dupl - - lll - - path: "test/*" - linters: - - lll - - path: "upgrade/*" - linters: - - lll - - path: "previous-version/*" - linters: - - lll linters: - disable-all: true + default: none enable: - dupl - errcheck + - ginkgolinter - goconst - gocyclo - - gofmt - - goimports - - gosimple - govet - ineffassign - lll - misspell - nakedret - - ginkgolinter - prealloc - revive - staticcheck - - typecheck - unconvert - unparam - unused - -linters-settings: - revive: + settings: + revive: + rules: + - name: comment-spacings + staticcheck: + checks: + - "all" + - "-QF*" + - "-ST*" + exclusions: + generated: lax + presets: [] rules: - - name: comment-spacings + - linters: + - lll + path: api/* + - linters: + - dupl + - goconst + - lll + path: internal/* + - linters: + - goconst + - lll + path: test/* + - linters: + - lll + path: upgrade/* + - linters: + - lll + path: previous-version/* + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/infra/feast-operator/Dockerfile b/infra/feast-operator/Dockerfile index f0814b25576..811c4d31c84 100644 --- a/infra/feast-operator/Dockerfile +++ b/infra/feast-operator/Dockerfile @@ -1,19 +1,20 @@ # Build the manager binary -FROM registry.access.redhat.com/ubi9/go-toolset:1.22.9 AS builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.25 AS builder ARG TARGETOS ARG TARGETARCH +ENV GOTOOLCHAIN=auto # Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum +COPY --chown=1001:0 go.mod go.mod +COPY --chown=1001:0 go.sum go.sum # cache deps before building and copying source so that we don't need to re-download as much # and so that source changes don't invalidate our downloaded layer RUN go mod download # Copy the go source -COPY cmd/main.go cmd/main.go -COPY api/ api/ -COPY internal/controller/ internal/controller/ +COPY --chown=1001:0 cmd/main.go cmd/main.go +COPY --chown=1001:0 api/ api/ +COPY --chown=1001:0 internal/controller/ internal/controller/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command @@ -22,7 +23,7 @@ COPY internal/controller/ internal/controller/ # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.8 WORKDIR / COPY --from=builder /opt/app-root/src/manager . USER 65532:65532 diff --git a/infra/feast-operator/Makefile b/infra/feast-operator/Makefile index bff19a5f979..5b470437397 100644 --- a/infra/feast-operator/Makefile +++ b/infra/feast-operator/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.61.0 +VERSION ?= 0.64.0 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") @@ -48,7 +48,7 @@ endif # Set the Operator SDK version to use. By default, what is installed on the system is used. # This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit. -OPERATOR_SDK_VERSION ?= v1.38.0 +OPERATOR_SDK_VERSION ?= v1.41.0 # Image URL to use all building/pushing image targets # During development and testing, and before make deploy we need to export FS_IMG to point to # the dev image generated using command `make build-feature-server-dev-docker` @@ -56,7 +56,7 @@ IMG ?= $(IMAGE_TAG_BASE):$(VERSION) FS_IMG ?= quay.io/feastdev/feature-server:$(VERSION) CJ_IMG ?= quay.io/openshift/origin-cli:4.17 # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.30.0 +ENVTEST_K8S_VERSION = 1.31.0 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -116,7 +116,7 @@ vet: ## Run go vet against code. .PHONY: test test: build-installer vet lint envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path --use-deprecated-gcs=false)" go test $$(go list ./... | grep -v test/e2e | grep -v test/data-source-types | grep -v test/upgrade | grep -v test/previous-version) -coverprofile cover.out + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" GOTOOLCHAIN=go$(shell go env GOVERSION | sed 's/^go//') go test $$(go list ./... | grep -v test/e2e | grep -v test/data-source-types | grep -v test/upgrade | grep -v test/previous-version) -coverprofile cover.out # Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors. .PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up. @@ -239,11 +239,11 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ENVSUBST = $(LOCALBIN)/envsubst ## Tool Versions -KUSTOMIZE_VERSION ?= v5.4.2 -CONTROLLER_TOOLS_VERSION ?= v0.15.0 -CRD_REF_DOCS_VERSION ?= v0.1.0 -ENVTEST_VERSION ?= release-0.18 -GOLANGCI_LINT_VERSION ?= v1.63.4 +KUSTOMIZE_VERSION ?= v5.4.3 +CONTROLLER_TOOLS_VERSION ?= v0.18.0 +CRD_REF_DOCS_VERSION ?= v0.2.0 +ENVTEST_VERSION ?= release-0.21 +GOLANGCI_LINT_VERSION ?= v2.12.2 ENVSUBST_VERSION ?= v1.4.2 .PHONY: kustomize @@ -264,7 +264,7 @@ $(ENVTEST): $(LOCALBIN) .PHONY: golangci-lint golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(GOLANGCI_LINT): $(LOCALBIN) - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) .PHONY: envsubst envsubst: $(ENVSUBST) ## Download envsubst locally if necessary. @@ -338,7 +338,7 @@ ifeq (,$(shell which opm 2>/dev/null)) set -e ;\ mkdir -p $(dir $(OPM)) ;\ OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.55.0/$${OS}-$${ARCH}-opm ;\ chmod +x $(OPM) ;\ } else diff --git a/infra/feast-operator/README.md b/infra/feast-operator/README.md index 9f530ad19a6..c639be54fde 100644 --- a/infra/feast-operator/README.md +++ b/infra/feast-operator/README.md @@ -3,6 +3,18 @@ This is a K8s Operator that can be used to deploy and manage **Feast**, an open ### **[FeatureStore CR API Reference](docs/api/markdown/ref.md)** +### **[Operator Configuration Guides](https://docs.feast.dev/how-to-guides/feast-operator)** + +| Guide | Topic | +|-------|-------| +| [1 — Project Provisioning](https://docs.feast.dev/how-to-guides/feast-operator/01-project-provisioning) | `feastProjectDir`: git clone vs `feast init` templates | +| [2 — Persistence](https://docs.feast.dev/how-to-guides/feast-operator/02-persistence) | File (path + PVC) vs DB store for offline/online/registry; Secret format | +| [3 — Serving & Observability](https://docs.feast.dev/how-to-guides/feast-operator/03-serving-and-observability) | Workers, log level, Prometheus metrics, offline push batching, MCP | +| [4 — Registry Topology](https://docs.feast.dev/how-to-guides/feast-operator/04-registry-topology) | Local, remote, cross-namespace `feastRef` | +| [5 — Security](https://docs.feast.dev/how-to-guides/feast-operator/05-security) | Kubernetes RBAC roles vs OIDC auth; TLS for all servers | +| [6 — Batch & Jobs](https://docs.feast.dev/how-to-guides/feast-operator/06-batch-and-jobs) | `batchEngine` ConfigMap, `cronJob` for scheduled materialization | +| [7 — OpenLineage & Materialization](https://docs.feast.dev/how-to-guides/feast-operator/07-openlineage-and-materialization) | Lineage transports, API key Secret, materialization batch size | + ## Getting Started ### Prerequisites diff --git a/infra/feast-operator/api/feastversion/version.go b/infra/feast-operator/api/feastversion/version.go index 621154918f3..742ede75fd5 100644 --- a/infra/feast-operator/api/feastversion/version.go +++ b/infra/feast-operator/api/feastversion/version.go @@ -17,4 +17,4 @@ limitations under the License. package feastversion // Feast release version. Keep on line #20, this is critical to release CI -const FeastVersion = "0.61.0" +const FeastVersion = "0.64.0" diff --git a/infra/feast-operator/api/v1/featurestore_types.go b/infra/feast-operator/api/v1/featurestore_types.go index 026e5f4a92c..3dd68311245 100644 --- a/infra/feast-operator/api/v1/featurestore_types.go +++ b/infra/feast-operator/api/v1/featurestore_types.go @@ -52,6 +52,7 @@ const ( ClientFailedReason = "ClientDeploymentFailed" CronJobFailedReason = "CronJobDeploymentFailed" KubernetesAuthzFailedReason = "KubernetesAuthorizationDeploymentFailed" + OidcAuthzFailedReason = "OidcAuthorizationDeploymentFailed" // Feast condition messages: ReadyMessage = "FeatureStore installation complete" @@ -62,12 +63,56 @@ const ( ClientReadyMessage = "Client installation complete" CronJobReadyMessage = "CronJob installation complete" KubernetesAuthzReadyMessage = "Kubernetes authorization installation complete" + OidcAuthzReadyMessage = "OIDC authorization installation complete" DeploymentNotAvailableMessage = "Deployment is not available" // entity_key_serialization_version SerializationVersion = 3 ) +// MaterializationConfig controls feature materialization behavior written into feature_store.yaml. +type MaterializationConfig struct { + // Number of rows per batch when writing to the online store during materialization. + // Prevents OOM for large feature views. Supported engines: local, spark, ray. + // If unset, all rows are written in a single batch. + // +kubebuilder:validation:Minimum=1 + // +optional + OnlineWriteBatchSize *int32 `json:"onlineWriteBatchSize,omitempty"` + // ExtraConfig passes additional materialization key-value settings inline into + // feature_store.yaml. + // +optional + ExtraConfig map[string]string `json:"extraConfig,omitempty"` +} + +// OpenLineageConfig enables OpenLineage data lineage tracking for Feast operations. +// Lineage events are emitted during feast apply and materialization when enabled. +type OpenLineageConfig struct { + // Enable OpenLineage integration. + Enabled bool `json:"enabled"` + // Transport type for lineage events. + // +kubebuilder:validation:Enum=http;console;file;kafka + // +optional + TransportType *string `json:"transportType,omitempty"` + // URL for HTTP transport (e.g. http://marquez:5000). Required when transportType is "http". + // +optional + TransportUrl *string `json:"transportUrl,omitempty"` + // API endpoint path appended to transportUrl. Defaults to "api/v1/lineage". + // +optional + TransportEndpoint *string `json:"transportEndpoint,omitempty"` + // Reference to a Secret containing the key "api_key" for lineage server authentication. + // +optional + ApiKeySecretRef *corev1.LocalObjectReference `json:"apiKeySecretRef,omitempty"` + // ExtraConfig holds additional OpenLineage key-value settings written inline into + // the openlineage block of feature_store.yaml alongside the typed fields above. + // Use this for non-core settings (e.g. namespace, producer, emit_on_apply, + // emit_on_materialize) and transport-specific options (e.g. kafka + // bootstrap_servers, topic; file path). Boolean values ("true"/"false") and + // integer values are automatically coerced to their native YAML types. + // Keys must be valid Feast OpenLineageConfig YAML field names. + // +optional + ExtraConfig map[string]string `json:"extraConfig,omitempty"` +} + // FeatureStoreSpec defines the desired state of FeatureStore // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 || !has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)",message="replicas > 1 and services.scaling.autoscaling are mutually exclusive." // +kubebuilder:validation:XValidation:rule="self.replicas <= 1 && (!has(self.services) || !has(self.services.scaling) || !has(self.services.scaling.autoscaling)) || (has(self.services) && has(self.services.onlineStore) && has(self.services.onlineStore.persistence) && has(self.services.onlineStore.persistence.store))",message="Scaling requires DB-backed persistence for the online store. Configure services.onlineStore.persistence.store when using replicas > 1 or autoscaling." @@ -82,11 +127,22 @@ type FeatureStoreSpec struct { AuthzConfig *AuthzConfig `json:"authz,omitempty"` CronJob *FeastCronJob `json:"cronJob,omitempty"` BatchEngine *BatchEngineConfig `json:"batchEngine,omitempty"` + // DataQualityMonitoring configures Data Quality Monitoring behaviour. + // +optional + DataQualityMonitoring *DataQualityMonitoringConfig `json:"dataQualityMonitoring,omitempty"` // Replicas is the desired number of pod replicas. Used by the scale sub-resource. // Mutually exclusive with services.scaling.autoscaling. // +kubebuilder:default=1 // +kubebuilder:validation:Minimum=1 - Replicas *int32 `json:"replicas"` + Replicas *int32 `json:"replicas,omitempty"` + // Materialization controls feature materialization behavior (batch size, pull strategy). + // Written into feature_store.yaml for all service pods. + // +optional + Materialization *MaterializationConfig `json:"materialization,omitempty"` + // OpenLineage enables OpenLineage data lineage tracking for Feast operations. + // Written into feature_store.yaml for all service pods. + // +optional + OpenLineage *OpenLineageConfig `json:"openlineage,omitempty"` } // FeastProjectDir defines how to create the feast project directory. @@ -117,7 +173,7 @@ type GitCloneOptions struct { type FeastInitOptions struct { Minimal bool `json:"minimal,omitempty"` // Template for the created project - // +kubebuilder:validation:Enum=local;gcp;aws;snowflake;spark;postgres;hbase;cassandra;hazelcast;couchbase;clickhouse + // +kubebuilder:validation:Enum=local;gcp;aws;snowflake;spark;postgres;hbase;cassandra;hazelcast;couchbase;clickhouse;milvus;ray;ray_rag;pytorch_nlp Template string `json:"template,omitempty"` } @@ -176,6 +232,13 @@ type BatchEngineConfig struct { ConfigMapKey string `json:"configMapKey,omitempty"` } +// DataQualityMonitoringConfig defines the Data Quality Monitoring configuration. +type DataQualityMonitoringConfig struct { + // AutoBaseline controls whether baseline distribution is computed automatically on feast apply. Defaults to true. + // +kubebuilder:default=true + AutoBaseline *bool `json:"autoBaseline,omitempty"` +} + // JobSpec describes how the job execution will look like. type JobSpec struct { // PodTemplateAnnotations are annotations to be applied to the CronJob's PodTemplate @@ -308,8 +371,15 @@ type FeatureStoreServices struct { UI *ServerConfigs `json:"ui,omitempty"` DeploymentStrategy *appsv1.DeploymentStrategy `json:"deploymentStrategy,omitempty"` SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // PodAnnotations are annotations to be applied to the Deployment's PodTemplate metadata. + // This enables annotation-driven integrations like OpenTelemetry auto-instrumentation, + // Istio sidecar injection, Vault agent injection, etc. + // +optional + PodAnnotations map[string]string `json:"podAnnotations,omitempty"` // Disable the 'feast repo initialization' initContainer DisableInitContainers bool `json:"disableInitContainers,omitempty"` + // Runs feast apply on pod start to populate the registry. Defaults to true. Ignored when DisableInitContainers is true. + RunFeastApplyOnInit *bool `json:"runFeastApplyOnInit,omitempty"` // Volumes specifies the volumes to mount in the FeatureStore deployment. A corresponding `VolumeMount` should be added to whichever feast service(s) require access to said volume(s). Volumes []corev1.Volume `json:"volumes,omitempty"` // Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -330,6 +400,17 @@ type FeatureStoreServices struct { // pod anti-affinity rule to prefer spreading pods across nodes. // +optional Affinity *corev1.Affinity `json:"affinity,omitempty"` + // ResourceClaims defines which ResourceClaims must be allocated + // and reserved before the Pod is allowed to start. The resources + // will be made available to those containers which consume them + // by name. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ResourceClaims []corev1.PodResourceClaim `json:"resourceClaims,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` } // ScalingConfig configures horizontal scaling for the FeatureStore deployment. @@ -430,6 +511,71 @@ type OnlineStore struct { // Creates a feature server container Server *ServerConfigs `json:"server,omitempty"` Persistence *OnlineStorePersistence `json:"persistence,omitempty"` + // Serving configures the Feast feature_server section written into feature_store.yaml for the online serve pod. + // Controls metrics granularity, offline push batching, and MCP. + // +optional + Serving *ServingConfig `json:"serving,omitempty"` +} + +// ServingConfig configures the feature_server section of the generated feature_store.yaml. +// When Mcp is set, the feature server type is switched to "mcp"; otherwise "local" is used. +type ServingConfig struct { + // Metrics configures per-category Prometheus metrics for the feature server. + // Coexists with the server.metrics bool flag — both can be set simultaneously. + // +optional + Metrics *ServingMetricsConfig `json:"metrics,omitempty"` + // OfflinePushBatching batches writes to the offline store via the /push endpoint. + // +optional + OfflinePushBatching *OfflinePushBatchingConfig `json:"offlinePushBatching,omitempty"` + // Mcp enables MCP (Model Context Protocol) server support. When set, feature server type is "mcp". + // +optional + Mcp *McpConfig `json:"mcp,omitempty"` +} + +// ServingMetricsConfig controls per-category Prometheus metrics for the feature server. +// Setting Enabled to true activates the metrics HTTP server on port 8000. +// All metric categories default to true when enabled; use Categories to selectively disable them. +type ServingMetricsConfig struct { + // Enable the Prometheus metrics endpoint on port 8000. + Enabled bool `json:"enabled"` + // Categories selectively enables or disables individual Feast metric categories. + // Keys are Feast MetricsConfig field names (e.g. "resource", "request", + // "online_features", "push", "materialization", "freshness"). Omitted keys + // default to true when metrics is enabled. + // +optional + Categories map[string]bool `json:"categories,omitempty"` +} + +// OfflinePushBatchingConfig controls batching of writes to the offline store via the /push endpoint. +// Recommended for high-throughput push workloads (streaming pipelines, IoT) to prevent OOM. +type OfflinePushBatchingConfig struct { + // Enable offline push batching. + Enabled bool `json:"enabled"` + // Maximum number of rows per offline write batch. + // +kubebuilder:validation:Minimum=1 + // +optional + BatchSize *int32 `json:"batchSize,omitempty"` + // Seconds between batch flushes to the offline store. + // +kubebuilder:validation:Minimum=1 + // +optional + BatchIntervalSeconds *int32 `json:"batchIntervalSeconds,omitempty"` +} + +// McpConfig enables MCP (Model Context Protocol) server support in the feature server. +// When this field is set on ServingConfig, the feature server type is switched to "mcp". +type McpConfig struct { + // Enable the MCP server. + Enabled bool `json:"enabled"` + // MCP server name for identification. Defaults to "feast-mcp-server". + // +optional + ServerName *string `json:"serverName,omitempty"` + // MCP server version string. Defaults to "1.0.0". + // +optional + ServerVersion *string `json:"serverVersion,omitempty"` + // MCP transport protocol. + // +kubebuilder:validation:Enum=sse;http + // +optional + Transport *string `json:"transport,omitempty"` } // OnlineStorePersistence configures the persistence settings for the online store service @@ -645,6 +791,7 @@ type WorkerConfigs struct { // RegistryServerConfigs creates a registry server for the feast service, with specified container configurations. // +kubebuilder:validation:XValidation:rule="self.restAPI == true || self.grpc == true || !has(self.grpc)", message="At least one of restAPI or grpc must be true" +// +kubebuilder:validation:XValidation:rule="!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) && self.restAPI == true)", message="MCP requires restAPI to be true" type RegistryServerConfigs struct { ServerConfigs `json:",inline"` @@ -653,6 +800,11 @@ type RegistryServerConfigs struct { // Enable gRPC registry server. Defaults to true if unset. GRPC *bool `json:"grpc,omitempty"` + + // Mcp enables MCP (Model Context Protocol) on the REST registry server. + // Requires restAPI to be true. Reuses the same McpConfig struct as the online store. + // +optional + Mcp *McpConfig `json:"mcp,omitempty"` } // CronJobContainerConfigs k8s container settings for the CronJob @@ -706,7 +858,34 @@ type KubernetesAuthz struct { // OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. // https://auth0.com/docs/authenticate/protocols/openid-connect-protocol type OidcAuthz struct { - SecretRef corev1.LocalObjectReference `json:"secretRef"` + // OIDC issuer URL. The operator appends /.well-known/openid-configuration to derive the discovery endpoint. + // +optional + // +kubebuilder:validation:Pattern=`^https://\S+$` + IssuerUrl string `json:"issuerUrl,omitempty"` + // Secret with OIDC properties (auth_discovery_url, client_id, client_secret). issuerUrl takes precedence. + // +optional + SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"` + // Key in the Secret containing all OIDC properties as a YAML value. If unset, each key is a property. + // +optional + SecretKeyName string `json:"secretKeyName,omitempty"` + // Env var name for client pods to read an OIDC token from. Sets token_env_var in client config. + // +optional + TokenEnvVar *string `json:"tokenEnvVar,omitempty"` + // Verify SSL certificates for the OIDC provider. Defaults to true. + // +optional + VerifySSL *bool `json:"verifySSL,omitempty"` + // ConfigMap with the CA certificate for self-signed OIDC providers. Auto-detected on RHOAI/ODH. + // +optional + CACertConfigMap *OidcCACertConfigMap `json:"caCertConfigMap,omitempty"` +} + +// OidcCACertConfigMap references a ConfigMap containing a CA certificate for OIDC provider TLS. +type OidcCACertConfigMap struct { + // ConfigMap name. + Name string `json:"name"` + // Key in the ConfigMap holding the PEM certificate. Defaults to "ca-bundle.crt". + // +optional + Key string `json:"key,omitempty"` } // TlsConfigs configures server TLS for a feast service. in an openshift cluster, this is configured by default using service serving certificates. diff --git a/infra/feast-operator/api/v1/zz_generated.deepcopy.go b/infra/feast-operator/api/v1/zz_generated.deepcopy.go index 63500266f02..9402f95e34a 100644 --- a/infra/feast-operator/api/v1/zz_generated.deepcopy.go +++ b/infra/feast-operator/api/v1/zz_generated.deepcopy.go @@ -41,7 +41,7 @@ func (in *AuthzConfig) DeepCopyInto(out *AuthzConfig) { if in.OidcAuthz != nil { in, out := &in.OidcAuthz, &out.OidcAuthz *out = new(OidcAuthz) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -145,6 +145,26 @@ func (in *CronJobContainerConfigs) DeepCopy() *CronJobContainerConfigs { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DataQualityMonitoringConfig) DeepCopyInto(out *DataQualityMonitoringConfig) { + *out = *in + if in.AutoBaseline != nil { + in, out := &in.AutoBaseline, &out.AutoBaseline + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataQualityMonitoringConfig. +func (in *DataQualityMonitoringConfig) DeepCopy() *DataQualityMonitoringConfig { + if in == nil { + return nil + } + out := new(DataQualityMonitoringConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DefaultCtrConfigs) DeepCopyInto(out *DefaultCtrConfigs) { *out = *in @@ -369,6 +389,18 @@ func (in *FeatureStoreServices) DeepCopyInto(out *FeatureStoreServices) { *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } + if in.PodAnnotations != nil { + in, out := &in.PodAnnotations, &out.PodAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.RunFeastApplyOnInit != nil { + in, out := &in.RunFeastApplyOnInit, &out.RunFeastApplyOnInit + *out = new(bool) + **out = **in + } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]corev1.Volume, len(*in)) @@ -398,6 +430,13 @@ func (in *FeatureStoreServices) DeepCopyInto(out *FeatureStoreServices) { *out = new(corev1.Affinity) (*in).DeepCopyInto(*out) } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]corev1.PodResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureStoreServices. @@ -438,11 +477,26 @@ func (in *FeatureStoreSpec) DeepCopyInto(out *FeatureStoreSpec) { *out = new(BatchEngineConfig) (*in).DeepCopyInto(*out) } + if in.DataQualityMonitoring != nil { + in, out := &in.DataQualityMonitoring, &out.DataQualityMonitoring + *out = new(DataQualityMonitoringConfig) + (*in).DeepCopyInto(*out) + } if in.Replicas != nil { in, out := &in.Replicas, &out.Replicas *out = new(int32) **out = **in } + if in.Materialization != nil { + in, out := &in.Materialization, &out.Materialization + *out = new(MaterializationConfig) + (*in).DeepCopyInto(*out) + } + if in.OpenLineage != nil { + in, out := &in.OpenLineage, &out.OpenLineage + *out = new(OpenLineageConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureStoreSpec. @@ -650,6 +704,88 @@ func (in *LocalRegistryConfig) DeepCopy() *LocalRegistryConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MaterializationConfig) DeepCopyInto(out *MaterializationConfig) { + *out = *in + if in.OnlineWriteBatchSize != nil { + in, out := &in.OnlineWriteBatchSize, &out.OnlineWriteBatchSize + *out = new(int32) + **out = **in + } + if in.ExtraConfig != nil { + in, out := &in.ExtraConfig, &out.ExtraConfig + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MaterializationConfig. +func (in *MaterializationConfig) DeepCopy() *MaterializationConfig { + if in == nil { + return nil + } + out := new(MaterializationConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *McpConfig) DeepCopyInto(out *McpConfig) { + *out = *in + if in.ServerName != nil { + in, out := &in.ServerName, &out.ServerName + *out = new(string) + **out = **in + } + if in.ServerVersion != nil { + in, out := &in.ServerVersion, &out.ServerVersion + *out = new(string) + **out = **in + } + if in.Transport != nil { + in, out := &in.Transport, &out.Transport + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new McpConfig. +func (in *McpConfig) DeepCopy() *McpConfig { + if in == nil { + return nil + } + out := new(McpConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OfflinePushBatchingConfig) DeepCopyInto(out *OfflinePushBatchingConfig) { + *out = *in + if in.BatchSize != nil { + in, out := &in.BatchSize, &out.BatchSize + *out = new(int32) + **out = **in + } + if in.BatchIntervalSeconds != nil { + in, out := &in.BatchIntervalSeconds, &out.BatchIntervalSeconds + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OfflinePushBatchingConfig. +func (in *OfflinePushBatchingConfig) DeepCopy() *OfflinePushBatchingConfig { + if in == nil { + return nil + } + out := new(OfflinePushBatchingConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OfflineStore) DeepCopyInto(out *OfflineStore) { *out = *in @@ -739,7 +875,26 @@ func (in *OfflineStorePersistence) DeepCopy() *OfflineStorePersistence { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OidcAuthz) DeepCopyInto(out *OidcAuthz) { *out = *in - out.SecretRef = in.SecretRef + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(corev1.LocalObjectReference) + **out = **in + } + if in.TokenEnvVar != nil { + in, out := &in.TokenEnvVar, &out.TokenEnvVar + *out = new(string) + **out = **in + } + if in.VerifySSL != nil { + in, out := &in.VerifySSL, &out.VerifySSL + *out = new(bool) + **out = **in + } + if in.CACertConfigMap != nil { + in, out := &in.CACertConfigMap, &out.CACertConfigMap + *out = new(OidcCACertConfigMap) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OidcAuthz. @@ -752,6 +907,21 @@ func (in *OidcAuthz) DeepCopy() *OidcAuthz { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OidcCACertConfigMap) DeepCopyInto(out *OidcCACertConfigMap) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OidcCACertConfigMap. +func (in *OidcCACertConfigMap) DeepCopy() *OidcCACertConfigMap { + if in == nil { + return nil + } + out := new(OidcCACertConfigMap) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OnlineStore) DeepCopyInto(out *OnlineStore) { *out = *in @@ -765,6 +935,11 @@ func (in *OnlineStore) DeepCopyInto(out *OnlineStore) { *out = new(OnlineStorePersistence) (*in).DeepCopyInto(*out) } + if in.Serving != nil { + in, out := &in.Serving, &out.Serving + *out = new(ServingConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OnlineStore. @@ -838,6 +1013,48 @@ func (in *OnlineStorePersistence) DeepCopy() *OnlineStorePersistence { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenLineageConfig) DeepCopyInto(out *OpenLineageConfig) { + *out = *in + if in.TransportType != nil { + in, out := &in.TransportType, &out.TransportType + *out = new(string) + **out = **in + } + if in.TransportUrl != nil { + in, out := &in.TransportUrl, &out.TransportUrl + *out = new(string) + **out = **in + } + if in.TransportEndpoint != nil { + in, out := &in.TransportEndpoint, &out.TransportEndpoint + *out = new(string) + **out = **in + } + if in.ApiKeySecretRef != nil { + in, out := &in.ApiKeySecretRef, &out.ApiKeySecretRef + *out = new(corev1.LocalObjectReference) + **out = **in + } + if in.ExtraConfig != nil { + in, out := &in.ExtraConfig, &out.ExtraConfig + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenLineageConfig. +func (in *OpenLineageConfig) DeepCopy() *OpenLineageConfig { + if in == nil { + return nil + } + out := new(OpenLineageConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OptionalCtrConfigs) DeepCopyInto(out *OptionalCtrConfigs) { *out = *in @@ -1093,6 +1310,11 @@ func (in *RegistryServerConfigs) DeepCopyInto(out *RegistryServerConfigs) { *out = new(bool) **out = **in } + if in.Mcp != nil { + in, out := &in.Mcp, &out.Mcp + *out = new(McpConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryServerConfigs. @@ -1243,6 +1465,58 @@ func (in *ServiceHostnames) DeepCopy() *ServiceHostnames { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServingConfig) DeepCopyInto(out *ServingConfig) { + *out = *in + if in.Metrics != nil { + in, out := &in.Metrics, &out.Metrics + *out = new(ServingMetricsConfig) + (*in).DeepCopyInto(*out) + } + if in.OfflinePushBatching != nil { + in, out := &in.OfflinePushBatching, &out.OfflinePushBatching + *out = new(OfflinePushBatchingConfig) + (*in).DeepCopyInto(*out) + } + if in.Mcp != nil { + in, out := &in.Mcp, &out.Mcp + *out = new(McpConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServingConfig. +func (in *ServingConfig) DeepCopy() *ServingConfig { + if in == nil { + return nil + } + out := new(ServingConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServingMetricsConfig) DeepCopyInto(out *ServingMetricsConfig) { + *out = *in + if in.Categories != nil { + in, out := &in.Categories, &out.Categories + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServingMetricsConfig. +func (in *ServingMetricsConfig) DeepCopy() *ServingMetricsConfig { + if in == nil { + return nil + } + out := new(ServingMetricsConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TlsConfigs) DeepCopyInto(out *TlsConfigs) { *out = *in diff --git a/infra/feast-operator/api/v1alpha1/featurestore_types.go b/infra/feast-operator/api/v1alpha1/featurestore_types.go index 23af949390c..87d13003805 100644 --- a/infra/feast-operator/api/v1alpha1/featurestore_types.go +++ b/infra/feast-operator/api/v1alpha1/featurestore_types.go @@ -105,7 +105,7 @@ type GitCloneOptions struct { type FeastInitOptions struct { Minimal bool `json:"minimal,omitempty"` // Template for the created project - // +kubebuilder:validation:Enum=local;gcp;aws;snowflake;spark;postgres;hbase;cassandra;hazelcast;couchbase;clickhouse + // +kubebuilder:validation:Enum=local;gcp;aws;snowflake;spark;postgres;hbase;cassandra;hazelcast;couchbase;clickhouse;milvus;ray;ray_rag;pytorch_nlp Template string `json:"template,omitempty"` } @@ -289,6 +289,8 @@ type FeatureStoreServices struct { SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` // Disable the 'feast repo initialization' initContainer DisableInitContainers bool `json:"disableInitContainers,omitempty"` + // Runs feast apply on pod start to populate the registry. Defaults to true. Ignored when DisableInitContainers is true. + RunFeastApplyOnInit *bool `json:"runFeastApplyOnInit,omitempty"` // Volumes specifies the volumes to mount in the FeatureStore deployment. A corresponding `VolumeMount` should be added to whichever feast service(s) require access to said volume(s). Volumes []corev1.Volume `json:"volumes,omitempty"` } diff --git a/infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go b/infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go index fa7c6f210dd..4033c368c8b 100644 --- a/infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go @@ -315,6 +315,11 @@ func (in *FeatureStoreServices) DeepCopyInto(out *FeatureStoreServices) { *out = new(v1.PodSecurityContext) (*in).DeepCopyInto(*out) } + if in.RunFeastApplyOnInit != nil { + in, out := &in.RunFeastApplyOnInit, &out.RunFeastApplyOnInit + *out = new(bool) + **out = **in + } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]v1.Volume, len(*in)) diff --git a/infra/feast-operator/bundle.Dockerfile b/infra/feast-operator/bundle.Dockerfile index 685b137b92a..eda73b6494e 100644 --- a/infra/feast-operator/bundle.Dockerfile +++ b/infra/feast-operator/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=feast-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.38.0 +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.41.0 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 diff --git a/infra/feast-operator/bundle/manifests/feast-operator-featurestore-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/infra/feast-operator/bundle/manifests/feast-operator-featurestore-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml index aff4d1f9840..b1f88ff62c3 100644 --- a/infra/feast-operator/bundle/manifests/feast-operator-featurestore-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/infra/feast-operator/bundle/manifests/feast-operator-featurestore-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -5,6 +5,8 @@ metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: feast-operator + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" name: feast-operator-featurestore-editor-role rules: - apiGroups: diff --git a/infra/feast-operator/bundle/manifests/feast-operator-featurestore-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/infra/feast-operator/bundle/manifests/feast-operator-featurestore-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml index bcf9699fc1a..c64d255eed7 100644 --- a/infra/feast-operator/bundle/manifests/feast-operator-featurestore-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/infra/feast-operator/bundle/manifests/feast-operator-featurestore-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -5,6 +5,7 @@ metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: feast-operator + rbac.authorization.k8s.io/aggregate-to-view: "true" name: feast-operator-featurestore-viewer-role rules: - apiGroups: diff --git a/infra/feast-operator/bundle/manifests/feast-operator.clusterserviceversion.yaml b/infra/feast-operator/bundle/manifests/feast-operator.clusterserviceversion.yaml index 64e6886444f..82e1bc57b36 100644 --- a/infra/feast-operator/bundle/manifests/feast-operator.clusterserviceversion.yaml +++ b/infra/feast-operator/bundle/manifests/feast-operator.clusterserviceversion.yaml @@ -4,6 +4,35 @@ metadata: annotations: alm-examples: |- [ + { + "apiVersion": "feast.dev/v1", + "kind": "FeatureStore", + "metadata": { + "name": "sample-materialization-openlineage", + "namespace": "feast" + }, + "spec": { + "feastProject": "my_project", + "materialization": { + "onlineWriteBatchSize": 10000 + }, + "openlineage": { + "apiKeySecretRef": { + "name": "openlineage-secret" + }, + "enabled": true, + "extraConfig": { + "emit_on_apply": "true", + "emit_on_materialize": "true", + "namespace": "my-feast-project", + "producer": "feast-operator" + }, + "transportEndpoint": "api/v1/lineage", + "transportType": "http", + "transportUrl": "http://marquez.feast.svc.cluster.local:5000" + } + } + }, { "apiVersion": "feast.dev/v1", "kind": "FeatureStore", @@ -14,6 +43,39 @@ metadata: "feastProject": "my_project" } }, + { + "apiVersion": "feast.dev/v1", + "kind": "FeatureStore", + "metadata": { + "name": "sample-mcp" + }, + "spec": { + "feastProject": "my_project", + "services": { + "onlineStore": { + "server": {}, + "serving": { + "mcp": { + "enabled": true, + "serverName": "feast-mcp-server", + "serverVersion": "1.0.0", + "transport": "sse" + } + } + }, + "registry": { + "local": { + "server": { + "mcp": { + "enabled": true + }, + "restAPI": true + } + } + } + } + } + }, { "apiVersion": "feast.dev/v1", "kind": "FeatureStore", @@ -35,6 +97,41 @@ metadata: } } }, + { + "apiVersion": "feast.dev/v1", + "kind": "FeatureStore", + "metadata": { + "name": "sample-serving" + }, + "spec": { + "feastProject": "my_project", + "services": { + "onlineStore": { + "server": {}, + "serving": { + "metrics": { + "categories": { + "audit_logging": false, + "freshness": false, + "materialization": true, + "offline_features": true, + "online_features": true, + "push": true, + "request": true, + "resource": true + }, + "enabled": true + }, + "offlinePushBatching": { + "batchIntervalSeconds": 10, + "batchSize": 1000, + "enabled": true + } + } + } + } + } + }, { "apiVersion": "feast.dev/v1", "kind": "FeatureStore", @@ -50,10 +147,10 @@ metadata: } ] capabilities: Basic Install - createdAt: "2026-03-10T20:00:10Z" - operators.operatorframework.io/builder: operator-sdk-v1.38.0 + createdAt: "2026-06-13T11:22:06Z" + operators.operatorframework.io/builder: operator-sdk-v1.41.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 - name: feast-operator.v0.61.0 + name: feast-operator.v0.64.0 namespace: placeholder spec: apiservicedefinitions: {} @@ -79,9 +176,12 @@ spec: clusterPermissions: - rules: - apiGroups: - - apps + - "" resources: - - deployments + - configmaps + - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - delete @@ -90,65 +190,62 @@ spec: - update - watch - apiGroups: - - authentication.k8s.io + - "" resources: - - tokenreviews + - namespaces + - pods + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - pods/exec verbs: - create - apiGroups: - - autoscaling + - apps resources: - - horizontalpodautoscalers + - deployments verbs: - create - delete - get - list - - patch - update - watch - apiGroups: - - batch + - authentication.k8s.io resources: - - cronjobs + - tokenreviews verbs: - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - - "" + - autoscaling resources: - - configmaps - - persistentvolumeclaims - - serviceaccounts - - services + - horizontalpodautoscalers verbs: - create - delete - get - list + - patch - update - watch - apiGroups: - - "" + - batch resources: - - namespaces - - pods - - secrets + - cronjobs verbs: + - create + - delete - get - list + - patch + - update - watch - - apiGroups: - - "" - resources: - - pods/exec - verbs: - - create - apiGroups: - feast.dev resources: @@ -175,6 +272,17 @@ spec: - get - patch - update + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - watch - apiGroups: - policy resources: @@ -256,10 +364,13 @@ spec: - /manager env: - name: RELATED_IMAGE_FEATURE_SERVER - value: quay.io/feastdev/feature-server:0.61.0 + value: quay.io/feastdev/feature-server:0.64.0 - name: RELATED_IMAGE_CRON_JOB value: quay.io/openshift/origin-cli:4.17 - image: quay.io/feastdev/feast-operator:0.61.0 + - name: GOMEMLIMIT + value: 230MiB + - name: OIDC_ISSUER_URL + image: quay.io/feastdev/feast-operator:0.64.0 livenessProbe: httpGet: path: /healthz @@ -349,8 +460,8 @@ spec: name: Feast Community url: https://lf-aidata.atlassian.net/wiki/spaces/FEAST/ relatedImages: - - image: quay.io/feastdev/feature-server:0.61.0 + - image: quay.io/feastdev/feature-server:0.64.0 name: feature-server - image: quay.io/openshift/origin-cli:4.17 name: cron-job - version: 0.61.0 + version: 0.64.0 diff --git a/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml b/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml index 884b1291264..d8791ae8a26 100644 --- a/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml +++ b/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.18.0 creationTimestamp: null name: featurestores.feast.dev spec: @@ -62,10 +62,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM certificate. + Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -76,8 +98,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -139,8 +167,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -239,7 +266,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -258,8 +285,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -305,6 +332,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -346,7 +377,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -498,6 +529,16 @@ spec: description: The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -529,8 +570,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -629,7 +669,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -648,8 +688,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -705,12 +745,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -734,7 +845,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -820,9 +931,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -911,7 +1022,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1036,7 +1147,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1054,13 +1165,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1177,7 +1288,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1190,9 +1301,9 @@ spec: (e.g. avoid putting this pod in the same node, zone, etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule pods - to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1317,7 +1428,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1335,13 +1446,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the pod - will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1458,7 +1569,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1656,8 +1767,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -1757,7 +1867,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -1776,8 +1886,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -1839,6 +1949,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2166,8 +2280,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2267,7 +2380,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2286,8 +2399,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2349,6 +2462,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2507,6 +2624,81 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server section + written into feature_store.yaml for the online serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. Defaults + to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults to + "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or disables + individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to the + offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to the + offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline write + batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied to the + Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -2718,8 +2910,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2822,7 +3013,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2841,8 +3032,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2883,6 +3075,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -2908,6 +3125,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -3073,6 +3294,9 @@ spec: x-kubernetes-validations: - message: At least one of restAPI or grpc must be true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -3129,6 +3353,41 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -3185,9 +3444,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -3232,9 +3500,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -3249,12 +3526,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the container @@ -3269,10 +3546,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3319,10 +3595,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3373,10 +3648,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3442,10 +3716,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3496,10 +3769,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3535,7 +3807,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target metric @@ -3546,10 +3818,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3600,10 +3871,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3638,7 +3908,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -3649,10 +3919,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3746,6 +4015,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -3784,13 +4057,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -3901,7 +4179,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -3937,8 +4215,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -4037,7 +4314,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -4056,8 +4333,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -4118,6 +4395,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -4286,7 +4567,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -4328,6 +4609,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -4336,9 +4618,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -4369,7 +4652,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -4417,7 +4700,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -4463,7 +4746,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -4503,7 +4786,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -4515,7 +4798,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -4577,7 +4860,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -4826,9 +5109,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -4863,7 +5146,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -4884,7 +5167,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -4894,7 +5177,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -4923,7 +5206,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4941,9 +5224,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -4983,6 +5265,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -5008,6 +5306,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -5098,7 +5397,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5115,7 +5414,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -5145,10 +5444,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -5228,7 +5530,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -5299,7 +5601,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -5348,7 +5650,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5414,7 +5716,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -5429,12 +5731,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -5450,9 +5752,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -5464,6 +5765,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -5478,6 +5780,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5505,6 +5808,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5519,6 +5823,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -5556,6 +5861,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -5590,7 +5896,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5665,7 +5971,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -5695,7 +6001,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -5754,10 +6059,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM + certificate. Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -5768,8 +6095,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -5833,8 +6166,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -5934,7 +6266,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5953,8 +6285,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6001,6 +6333,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -6042,7 +6378,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -6196,6 +6532,16 @@ spec: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -6228,8 +6574,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -6329,7 +6674,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -6348,8 +6693,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6406,12 +6751,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -6435,7 +6851,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -6522,9 +6938,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector @@ -6613,7 +7029,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -6741,7 +7157,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6759,13 +7175,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -6882,7 +7298,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6896,9 +7312,9 @@ spec: etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule - pods to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7026,7 +7442,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7044,13 +7460,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -7167,7 +7583,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7368,8 +7784,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7472,7 +7887,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -7491,8 +7906,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -7554,6 +7970,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -7886,8 +8306,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7990,7 +8409,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8009,8 +8428,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8072,6 +8492,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8231,6 +8655,83 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server + section written into feature_store.yaml for the online + serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is + "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or + disables individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to + the offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to + the offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline + write batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied + to the Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -8450,8 +8951,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -8556,7 +9056,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8575,9 +9075,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8618,6 +9118,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -8643,6 +9168,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8814,6 +9343,9 @@ spec: true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -8871,6 +9403,42 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -8928,9 +9496,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -8976,9 +9553,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -8993,12 +9579,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the @@ -9013,10 +9599,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9063,10 +9648,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9117,10 +9701,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9187,10 +9770,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9241,10 +9823,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9280,7 +9861,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target @@ -9291,10 +9872,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9345,10 +9925,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9383,7 +9962,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -9394,10 +9973,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9491,6 +10069,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -9530,13 +10113,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -9650,7 +10238,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -9686,8 +10274,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -9787,7 +10374,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -9806,8 +10393,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -9869,6 +10456,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -10037,7 +10628,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -10079,6 +10670,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -10087,9 +10679,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -10120,7 +10713,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -10169,7 +10762,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -10215,7 +10808,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -10255,7 +10848,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -10268,7 +10861,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -10332,7 +10925,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -10584,9 +11177,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -10621,7 +11214,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -10642,7 +11235,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -10652,7 +11245,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -10681,7 +11274,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10699,9 +11292,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -10741,6 +11333,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -10766,6 +11374,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -10857,7 +11466,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10874,7 +11483,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -10904,10 +11513,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -10988,7 +11600,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -11061,7 +11673,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -11110,7 +11722,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11176,7 +11788,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -11191,12 +11803,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -11212,9 +11824,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -11226,6 +11837,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -11240,6 +11852,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11267,6 +11880,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11281,6 +11895,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -11318,6 +11933,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -11352,7 +11968,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11427,7 +12043,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -11458,7 +12074,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -11533,10 +12148,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -11707,8 +12319,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -11807,7 +12418,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -11826,8 +12437,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -11873,6 +12484,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -11914,7 +12529,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -12097,8 +12712,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -12197,7 +12811,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12216,8 +12830,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12273,6 +12887,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -12471,8 +13089,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -12572,7 +13189,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12591,8 +13208,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12654,6 +13271,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -12981,8 +13602,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13082,7 +13702,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13101,8 +13721,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13164,6 +13784,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -13509,8 +14133,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13613,7 +14236,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13632,8 +14255,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13699,6 +14323,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -13920,6 +14548,10 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -13965,6 +14597,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -14003,13 +14639,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -14066,8 +14707,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -14166,7 +14806,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -14185,8 +14825,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -14247,6 +14887,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -14415,7 +15059,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -14457,6 +15101,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -14465,9 +15110,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -14498,7 +15144,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -14546,7 +15192,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -14592,7 +15238,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -14632,7 +15278,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -14644,7 +15290,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -14706,7 +15352,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -14955,9 +15601,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -14992,7 +15638,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -15013,7 +15659,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -15023,7 +15669,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -15052,7 +15698,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15070,9 +15716,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -15112,6 +15757,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -15137,6 +15798,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -15227,7 +15889,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15244,7 +15906,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -15274,10 +15936,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -15357,7 +16022,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -15428,7 +16093,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -15477,7 +16142,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15543,7 +16208,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -15558,12 +16223,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -15579,9 +16244,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -15593,6 +16257,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -15607,6 +16272,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15634,6 +16300,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15648,6 +16315,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -15685,6 +16353,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -15719,7 +16388,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15794,7 +16463,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -15910,8 +16579,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16011,7 +16679,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16030,8 +16698,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16078,6 +16746,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -16119,7 +16791,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -16305,8 +16977,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16406,7 +17077,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16425,8 +17096,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16483,6 +17154,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -16684,8 +17359,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16788,7 +17462,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16807,8 +17481,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16870,6 +17545,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17202,8 +17881,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -17306,7 +17984,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17325,8 +18003,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17388,6 +18067,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17742,8 +18425,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -17848,7 +18530,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17867,9 +18549,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17935,6 +18617,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -18163,6 +18849,11 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -18208,6 +18899,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -18247,13 +18943,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -18311,8 +19012,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -18412,7 +19112,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -18431,8 +19131,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -18494,6 +19194,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -18662,7 +19366,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -18704,6 +19408,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -18712,9 +19417,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -18745,7 +19451,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -18794,7 +19500,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -18840,7 +19546,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -18880,7 +19586,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -18893,7 +19599,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -18957,7 +19663,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19209,9 +19915,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -19246,7 +19952,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -19267,7 +19973,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -19277,7 +19983,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -19306,7 +20012,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19324,9 +20030,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -19366,6 +20071,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -19391,6 +20112,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -19482,7 +20204,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19499,7 +20221,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -19529,10 +20251,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -19613,7 +20338,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -19686,7 +20411,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19735,7 +20460,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -19801,7 +20526,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -19816,12 +20541,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -19837,9 +20562,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -19851,6 +20575,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -19865,6 +20590,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19892,6 +20618,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19906,6 +20633,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -19943,6 +20671,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -19977,7 +20706,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -20052,7 +20781,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -20126,10 +20855,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string diff --git a/infra/feast-operator/bundle/manifests/openlineage-secret_v1_secret.yaml b/infra/feast-operator/bundle/manifests/openlineage-secret_v1_secret.yaml new file mode 100644 index 00000000000..85d09af493c --- /dev/null +++ b/infra/feast-operator/bundle/manifests/openlineage-secret_v1_secret.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Secret +metadata: + name: openlineage-secret +stringData: + api_key: your-marquez-api-key # pragma: allowlist secret diff --git a/infra/feast-operator/bundle/metadata/annotations.yaml b/infra/feast-operator/bundle/metadata/annotations.yaml index 5e280a43e24..2c6d3383343 100644 --- a/infra/feast-operator/bundle/metadata/annotations.yaml +++ b/infra/feast-operator/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: feast-operator operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.38.0 + operators.operatorframework.io.metrics.builder: operator-sdk-v1.41.0 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 diff --git a/infra/feast-operator/cmd/main.go b/infra/feast-operator/cmd/main.go index 4be1777ac72..0e5565cce2b 100644 --- a/infra/feast-operator/cmd/main.go +++ b/infra/feast-operator/cmd/main.go @@ -25,11 +25,18 @@ import ( // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" + appsv1 "k8s.io/api/apps/v1" + autoscalingv2 "k8s.io/api/autoscaling/v2" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -42,6 +49,7 @@ import ( routev1 "github.com/openshift/api/route/v1" "github.com/feast-dev/feast/infra/feast-operator/internal/controller" + feastmetrics "github.com/feast-dev/feast/infra/feast-operator/internal/controller/metrics" "github.com/feast-dev/feast/infra/feast-operator/internal/controller/services" // +kubebuilder:scaffold:imports ) @@ -59,12 +67,36 @@ func init() { // +kubebuilder:scaffold:scheme } +func newCacheOptions() cache.Options { + managedBySelector := labels.SelectorFromSet(labels.Set{ + services.ManagedByLabelKey: services.ManagedByLabelValue, + }) + managedByFilter := cache.ByObject{Label: managedBySelector} + + return cache.Options{ + DefaultTransform: cache.TransformStripManagedFields(), + ByObject: map[client.Object]cache.ByObject{ + &corev1.ConfigMap{}: managedByFilter, + &appsv1.Deployment{}: managedByFilter, + &corev1.Service{}: managedByFilter, + &corev1.ServiceAccount{}: managedByFilter, + &corev1.PersistentVolumeClaim{}: managedByFilter, + &rbacv1.RoleBinding{}: managedByFilter, + &rbacv1.Role{}: managedByFilter, + &batchv1.CronJob{}: managedByFilter, + &autoscalingv2.HorizontalPodAutoscaler{}: managedByFilter, + &policyv1.PodDisruptionBudget{}: managedByFilter, + }, + } +} + func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string var secureMetrics bool var enableHTTP2 bool + var featureStoreMetrics bool var tlsOpts []func(*tls.Config) flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") @@ -76,6 +108,9 @@ func main() { "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") + flag.BoolVar(&featureStoreMetrics, "feature-store-metrics", true, + "Enable Prometheus gauges exposing online/offline store and registry configuration per FeatureStore. "+ + "Disable with --feature-store-metrics=false.") opts := zap.Options{ Development: true, } @@ -105,7 +140,7 @@ func main() { // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. // More info: - // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.18.4/pkg/metrics/server + // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server // - https://book.kubebuilder.io/reference/metrics.html metricsServerOptions := metricsserver.Options{ BindAddress: metricsAddr, @@ -123,7 +158,7 @@ func main() { // FilterProvider is used to protect the metrics endpoint with authn/authz. // These configurations ensure that only authorized users and service accounts // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: - // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.18.4/pkg/metrics/filters#WithAuthenticationAndAuthorization + // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization } @@ -145,11 +180,26 @@ func main() { // if you are doing or is intended to do any operation such as perform cleanups // after the manager stops then its usage might be unsafe. // LeaderElectionReleaseOnCancel: true, + Cache: newCacheOptions(), Client: client.Options{ Cache: &client.CacheOptions{ + // Bypass the label-filtered informer cache for all reads so that + // pre-existing resources without the managed-by label are still + // visible to the reconciler. The ByObject cache filter above still + // restricts the watch to managed-by-labeled objects, limiting + // memory usage while avoiding upgrade deadlocks. DisableFor: []client.Object{ &corev1.ConfigMap{}, &corev1.Secret{}, + &appsv1.Deployment{}, + &corev1.Service{}, + &corev1.ServiceAccount{}, + &corev1.PersistentVolumeClaim{}, + &rbacv1.RoleBinding{}, + &rbacv1.Role{}, + &batchv1.CronJob{}, + &autoscalingv2.HorizontalPodAutoscaler{}, + &policyv1.PodDisruptionBudget{}, }, }, }, @@ -161,9 +211,19 @@ func main() { services.SetIsOpenShift(mgr.GetConfig()) + var fsMetrics *feastmetrics.FeatureStoreMetrics + if featureStoreMetrics { + fsMetrics = feastmetrics.NewFeatureStoreMetrics() + fsMetrics.Register() + setupLog.Info("FeatureStore installation metrics enabled") + } else { + setupLog.Info("FeatureStore installation metrics disabled (--feature-store-metrics=false)") + } + if err = (&controller.FeatureStoreReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Metrics: fsMetrics, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "FeatureStore") os.Exit(1) diff --git a/infra/feast-operator/config/component_metadata.yaml b/infra/feast-operator/config/component_metadata.yaml index 0d4272ae6af..129d6029155 100644 --- a/infra/feast-operator/config/component_metadata.yaml +++ b/infra/feast-operator/config/component_metadata.yaml @@ -1,5 +1,5 @@ # This file is required to configure Feast release information for ODH/RHOAI Operator releases: - name: Feast - version: 0.61.0 + version: 0.64.0 repoUrl: https://github.com/feast-dev/feast diff --git a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml index c2f5fc3eb20..0851b9abf96 100644 --- a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml +++ b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.18.0 name: featurestores.feast.dev spec: group: feast.dev @@ -62,10 +62,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM certificate. + Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -76,8 +98,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -139,8 +167,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -239,7 +266,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -258,8 +285,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -305,6 +332,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -346,7 +377,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -498,6 +529,16 @@ spec: description: The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -529,8 +570,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -629,7 +669,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -648,8 +688,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -705,12 +745,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -734,7 +845,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -820,9 +931,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -911,7 +1022,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1036,7 +1147,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1054,13 +1165,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1177,7 +1288,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1190,9 +1301,9 @@ spec: (e.g. avoid putting this pod in the same node, zone, etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule pods - to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1317,7 +1428,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1335,13 +1446,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the pod - will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1458,7 +1569,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1656,8 +1767,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -1757,7 +1867,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -1776,8 +1886,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -1839,6 +1949,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2166,8 +2280,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2267,7 +2380,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2286,8 +2399,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2349,6 +2462,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2507,6 +2624,81 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server section + written into feature_store.yaml for the online serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. Defaults + to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults to + "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or disables + individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to the + offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to the + offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline write + batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied to the + Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -2718,8 +2910,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2822,7 +3013,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2841,8 +3032,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2883,6 +3075,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -2908,6 +3125,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -3073,6 +3294,9 @@ spec: x-kubernetes-validations: - message: At least one of restAPI or grpc must be true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -3129,6 +3353,41 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -3185,9 +3444,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -3232,9 +3500,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -3249,12 +3526,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the container @@ -3269,10 +3546,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3319,10 +3595,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3373,10 +3648,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3442,10 +3716,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3496,10 +3769,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3535,7 +3807,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target metric @@ -3546,10 +3818,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3600,10 +3871,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3638,7 +3908,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -3649,10 +3919,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3746,6 +4015,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -3784,13 +4057,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -3901,7 +4179,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -3937,8 +4215,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -4037,7 +4314,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -4056,8 +4333,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -4118,6 +4395,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -4286,7 +4567,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -4328,6 +4609,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -4336,9 +4618,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -4369,7 +4652,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -4417,7 +4700,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -4463,7 +4746,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -4503,7 +4786,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -4515,7 +4798,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -4577,7 +4860,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -4826,9 +5109,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -4863,7 +5146,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -4884,7 +5167,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -4894,7 +5177,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -4923,7 +5206,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4941,9 +5224,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -4983,6 +5265,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -5008,6 +5306,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -5098,7 +5397,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5115,7 +5414,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -5145,10 +5444,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -5228,7 +5530,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -5299,7 +5601,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -5348,7 +5650,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5414,7 +5716,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -5429,12 +5731,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -5450,9 +5752,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -5464,6 +5765,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -5478,6 +5780,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5505,6 +5808,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5519,6 +5823,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -5556,6 +5861,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -5590,7 +5896,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5665,7 +5971,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -5695,7 +6001,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -5754,10 +6059,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM + certificate. Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -5768,8 +6095,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -5833,8 +6166,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -5934,7 +6266,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5953,8 +6285,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6001,6 +6333,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -6042,7 +6378,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -6196,6 +6532,16 @@ spec: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -6228,8 +6574,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -6329,7 +6674,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -6348,8 +6693,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6406,12 +6751,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -6435,7 +6851,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -6522,9 +6938,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector @@ -6613,7 +7029,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -6741,7 +7157,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6759,13 +7175,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -6882,7 +7298,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6896,9 +7312,9 @@ spec: etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule - pods to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7026,7 +7442,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7044,13 +7460,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -7167,7 +7583,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7368,8 +7784,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7472,7 +7887,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -7491,8 +7906,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -7554,6 +7970,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -7886,8 +8306,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7990,7 +8409,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8009,8 +8428,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8072,6 +8492,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8231,6 +8655,83 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server + section written into feature_store.yaml for the online + serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is + "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or + disables individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to + the offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to + the offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline + write batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied + to the Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -8450,8 +8951,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -8556,7 +9056,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8575,9 +9075,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8618,6 +9118,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -8643,6 +9168,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8814,6 +9343,9 @@ spec: true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -8871,6 +9403,42 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -8928,9 +9496,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -8976,9 +9553,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -8993,12 +9579,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the @@ -9013,10 +9599,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9063,10 +9648,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9117,10 +9701,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9187,10 +9770,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9241,10 +9823,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9280,7 +9861,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target @@ -9291,10 +9872,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9345,10 +9925,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9383,7 +9962,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -9394,10 +9973,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9491,6 +10069,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -9530,13 +10113,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -9650,7 +10238,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -9686,8 +10274,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -9787,7 +10374,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -9806,8 +10393,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -9869,6 +10456,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -10037,7 +10628,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -10079,6 +10670,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -10087,9 +10679,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -10120,7 +10713,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -10169,7 +10762,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -10215,7 +10808,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -10255,7 +10848,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -10268,7 +10861,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -10332,7 +10925,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -10584,9 +11177,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -10621,7 +11214,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -10642,7 +11235,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -10652,7 +11245,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -10681,7 +11274,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10699,9 +11292,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -10741,6 +11333,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -10766,6 +11374,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -10857,7 +11466,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10874,7 +11483,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -10904,10 +11513,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -10988,7 +11600,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -11061,7 +11673,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -11110,7 +11722,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11176,7 +11788,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -11191,12 +11803,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -11212,9 +11824,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -11226,6 +11837,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -11240,6 +11852,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11267,6 +11880,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11281,6 +11895,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -11318,6 +11933,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -11352,7 +11968,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11427,7 +12043,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -11458,7 +12074,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -11533,10 +12148,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -11707,8 +12319,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -11807,7 +12418,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -11826,8 +12437,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -11873,6 +12484,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -11914,7 +12529,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -12097,8 +12712,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -12197,7 +12811,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12216,8 +12830,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12273,6 +12887,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -12471,8 +13089,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -12572,7 +13189,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12591,8 +13208,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12654,6 +13271,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -12981,8 +13602,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13082,7 +13702,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13101,8 +13721,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13164,6 +13784,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -13509,8 +14133,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13613,7 +14236,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13632,8 +14255,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13699,6 +14323,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -13920,6 +14548,10 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -13965,6 +14597,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -14003,13 +14639,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -14066,8 +14707,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -14166,7 +14806,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -14185,8 +14825,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -14247,6 +14887,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -14415,7 +15059,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -14457,6 +15101,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -14465,9 +15110,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -14498,7 +15144,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -14546,7 +15192,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -14592,7 +15238,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -14632,7 +15278,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -14644,7 +15290,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -14706,7 +15352,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -14955,9 +15601,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -14992,7 +15638,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -15013,7 +15659,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -15023,7 +15669,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -15052,7 +15698,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15070,9 +15716,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -15112,6 +15757,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -15137,6 +15798,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -15227,7 +15889,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15244,7 +15906,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -15274,10 +15936,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -15357,7 +16022,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -15428,7 +16093,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -15477,7 +16142,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15543,7 +16208,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -15558,12 +16223,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -15579,9 +16244,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -15593,6 +16257,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -15607,6 +16272,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15634,6 +16300,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15648,6 +16315,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -15685,6 +16353,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -15719,7 +16388,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15794,7 +16463,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -15910,8 +16579,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16011,7 +16679,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16030,8 +16698,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16078,6 +16746,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -16119,7 +16791,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -16305,8 +16977,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16406,7 +17077,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16425,8 +17096,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16483,6 +17154,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -16684,8 +17359,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16788,7 +17462,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16807,8 +17481,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16870,6 +17545,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17202,8 +17881,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -17306,7 +17984,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17325,8 +18003,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17388,6 +18067,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17742,8 +18425,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -17848,7 +18530,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17867,9 +18549,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17935,6 +18617,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -18163,6 +18849,11 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -18208,6 +18899,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -18247,13 +18943,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -18311,8 +19012,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -18412,7 +19112,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -18431,8 +19131,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -18494,6 +19194,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -18662,7 +19366,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -18704,6 +19408,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -18712,9 +19417,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -18745,7 +19451,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -18794,7 +19500,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -18840,7 +19546,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -18880,7 +19586,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -18893,7 +19599,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -18957,7 +19663,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19209,9 +19915,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -19246,7 +19952,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -19267,7 +19973,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -19277,7 +19983,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -19306,7 +20012,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19324,9 +20030,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -19366,6 +20071,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -19391,6 +20112,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -19482,7 +20204,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19499,7 +20221,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -19529,10 +20251,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -19613,7 +20338,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -19686,7 +20411,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19735,7 +20460,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -19801,7 +20526,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -19816,12 +20541,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -19837,9 +20562,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -19851,6 +20575,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -19865,6 +20590,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19892,6 +20618,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19906,6 +20633,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -19943,6 +20671,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -19977,7 +20706,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -20052,7 +20781,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -20126,10 +20855,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string diff --git a/infra/feast-operator/config/default/related_image_fs_patch.tmpl b/infra/feast-operator/config/default/related_image_fs_patch.tmpl index 23bf80c98ba..11e127dab39 100644 --- a/infra/feast-operator/config/default/related_image_fs_patch.tmpl +++ b/infra/feast-operator/config/default/related_image_fs_patch.tmpl @@ -1,10 +1,14 @@ -- op: replace - path: "/spec/template/spec/containers/0/env/0" - value: - name: RELATED_IMAGE_FEATURE_SERVER - value: ${FS_IMG} -- op: replace - path: "/spec/template/spec/containers/0/env/1" - value: - name: RELATED_IMAGE_CRON_JOB - value: ${CJ_IMG} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager +spec: + template: + spec: + containers: + - name: manager + env: + - name: RELATED_IMAGE_FEATURE_SERVER + value: ${FS_IMG} + - name: RELATED_IMAGE_CRON_JOB + value: ${CJ_IMG} diff --git a/infra/feast-operator/config/default/related_image_fs_patch.yaml b/infra/feast-operator/config/default/related_image_fs_patch.yaml index afc1c3d7c63..4e314795de2 100644 --- a/infra/feast-operator/config/default/related_image_fs_patch.yaml +++ b/infra/feast-operator/config/default/related_image_fs_patch.yaml @@ -1,10 +1,14 @@ -- op: replace - path: "/spec/template/spec/containers/0/env/0" - value: - name: RELATED_IMAGE_FEATURE_SERVER - value: quay.io/feastdev/feature-server:0.61.0 -- op: replace - path: "/spec/template/spec/containers/0/env/1" - value: - name: RELATED_IMAGE_CRON_JOB - value: quay.io/openshift/origin-cli:4.17 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager +spec: + template: + spec: + containers: + - name: manager + env: + - name: RELATED_IMAGE_FEATURE_SERVER + value: quay.io/feastdev/feature-server:0.64.0 + - name: RELATED_IMAGE_CRON_JOB + value: quay.io/openshift/origin-cli:4.17 diff --git a/infra/feast-operator/config/manager/kustomization.yaml b/infra/feast-operator/config/manager/kustomization.yaml index 4a0a78531bb..c713f0fe470 100644 --- a/infra/feast-operator/config/manager/kustomization.yaml +++ b/infra/feast-operator/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: quay.io/feastdev/feast-operator - newTag: 0.61.0 + newTag: 0.64.0 diff --git a/infra/feast-operator/config/manager/manager.yaml b/infra/feast-operator/config/manager/manager.yaml index 8107749fce5..4213787e075 100644 --- a/infra/feast-operator/config/manager/manager.yaml +++ b/infra/feast-operator/config/manager/manager.yaml @@ -73,10 +73,16 @@ spec: drop: - "ALL" env: + - name: GOMEMLIMIT + value: "230MiB" - name: RELATED_IMAGE_FEATURE_SERVER value: feast:latest - name: RELATED_IMAGE_CRON_JOB value: origin-cli:latest + # Injected from params.env via kustomize replacements (ODH/RHOAI overlays). + # Open Data Hub operator sets this from GatewayConfig when the cluster uses external OIDC. + - name: OIDC_ISSUER_URL + value: "" livenessProbe: httpGet: path: /healthz diff --git a/infra/feast-operator/config/overlays/odh/kustomization.yaml b/infra/feast-operator/config/overlays/odh/kustomization.yaml index cf751d178bd..044614f01fe 100644 --- a/infra/feast-operator/config/overlays/odh/kustomization.yaml +++ b/infra/feast-operator/config/overlays/odh/kustomization.yaml @@ -52,3 +52,13 @@ replacements: name: controller-manager fieldPaths: - spec.template.spec.containers.[name=manager].env.[name=RELATED_IMAGE_CRON_JOB].value + - source: + kind: ConfigMap + name: feast-operator-parameters + fieldPath: data.OIDC_ISSUER_URL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=OIDC_ISSUER_URL].value diff --git a/infra/feast-operator/config/overlays/odh/params.env b/infra/feast-operator/config/overlays/odh/params.env index d7b0233b998..49bbac59c71 100644 --- a/infra/feast-operator/config/overlays/odh/params.env +++ b/infra/feast-operator/config/overlays/odh/params.env @@ -1,3 +1,5 @@ -RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.61.0 -RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.61.0 +RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.64.0 +RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.64.0 RELATED_IMAGE_CRON_JOB=quay.io/openshift/origin-cli:4.17 +# Set at deploy time by the Open Data Hub operator from GatewayConfig (external OIDC). +OIDC_ISSUER_URL= diff --git a/infra/feast-operator/config/overlays/rhoai/kustomization.yaml b/infra/feast-operator/config/overlays/rhoai/kustomization.yaml index 4917579ef28..b9d075bdf39 100644 --- a/infra/feast-operator/config/overlays/rhoai/kustomization.yaml +++ b/infra/feast-operator/config/overlays/rhoai/kustomization.yaml @@ -52,3 +52,13 @@ replacements: name: controller-manager fieldPaths: - spec.template.spec.containers.[name=manager].env.[name=RELATED_IMAGE_CRON_JOB].value + - source: + kind: ConfigMap + name: feast-operator-parameters + fieldPath: data.OIDC_ISSUER_URL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=OIDC_ISSUER_URL].value diff --git a/infra/feast-operator/config/overlays/rhoai/params.env b/infra/feast-operator/config/overlays/rhoai/params.env index ce50a9f1412..92e02fb51b3 100644 --- a/infra/feast-operator/config/overlays/rhoai/params.env +++ b/infra/feast-operator/config/overlays/rhoai/params.env @@ -1,3 +1,5 @@ -RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.61.0 -RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.61.0 -RELATED_IMAGE_CRON_JOB=registry.redhat.io/openshift4/ose-cli@sha256:bc35a9fc663baf0d6493cc57e89e77a240a36c43cf38fb78d8e61d3b87cf5cc5 \ No newline at end of file +RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.64.0 +RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.64.0 +RELATED_IMAGE_CRON_JOB=registry.redhat.io/openshift4/ose-cli@sha256:bc35a9fc663baf0d6493cc57e89e77a240a36c43cf38fb78d8e61d3b87cf5cc5 +# Set at deploy time by the Open Data Hub operator from GatewayConfig (external OIDC). +OIDC_ISSUER_URL= \ No newline at end of file diff --git a/infra/feast-operator/config/rbac/featurestore_editor_role.yaml b/infra/feast-operator/config/rbac/featurestore_editor_role.yaml index 37c38e6f618..e2e3acf1b60 100644 --- a/infra/feast-operator/config/rbac/featurestore_editor_role.yaml +++ b/infra/feast-operator/config/rbac/featurestore_editor_role.yaml @@ -5,6 +5,8 @@ metadata: labels: app.kubernetes.io/name: feast-operator app.kubernetes.io/managed-by: kustomize + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" name: featurestore-editor-role rules: - apiGroups: diff --git a/infra/feast-operator/config/rbac/featurestore_viewer_role.yaml b/infra/feast-operator/config/rbac/featurestore_viewer_role.yaml index b4444cbe60a..bca67d9788d 100644 --- a/infra/feast-operator/config/rbac/featurestore_viewer_role.yaml +++ b/infra/feast-operator/config/rbac/featurestore_viewer_role.yaml @@ -5,6 +5,7 @@ metadata: labels: app.kubernetes.io/name: feast-operator app.kubernetes.io/managed-by: kustomize + rbac.authorization.k8s.io/aggregate-to-view: "true" name: featurestore-viewer-role rules: - apiGroups: diff --git a/infra/feast-operator/config/rbac/role.yaml b/infra/feast-operator/config/rbac/role.yaml index dca06c870e4..0c1bd7be84b 100644 --- a/infra/feast-operator/config/rbac/role.yaml +++ b/infra/feast-operator/config/rbac/role.yaml @@ -5,9 +5,12 @@ metadata: name: manager-role rules: - apiGroups: - - apps + - "" resources: - - deployments + - configmaps + - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - delete @@ -16,65 +19,62 @@ rules: - update - watch - apiGroups: - - authentication.k8s.io + - "" resources: - - tokenreviews + - namespaces + - pods + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods/exec verbs: - create - apiGroups: - - autoscaling + - apps resources: - - horizontalpodautoscalers + - deployments verbs: - create - delete - get - list - - patch - update - watch - apiGroups: - - batch + - authentication.k8s.io resources: - - cronjobs + - tokenreviews verbs: - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - - "" + - autoscaling resources: - - configmaps - - persistentvolumeclaims - - serviceaccounts - - services + - horizontalpodautoscalers verbs: - create - delete - get - list + - patch - update - watch - apiGroups: - - "" + - batch resources: - - namespaces - - pods - - secrets + - cronjobs verbs: + - create + - delete - get - list + - patch + - update - watch -- apiGroups: - - "" - resources: - - pods/exec - verbs: - - create - apiGroups: - feast.dev resources: @@ -101,6 +101,17 @@ rules: - get - patch - update +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - watch - apiGroups: - policy resources: diff --git a/infra/feast-operator/config/samples/kustomization.yaml b/infra/feast-operator/config/samples/kustomization.yaml index 127bd5894b4..65061a2b265 100644 --- a/infra/feast-operator/config/samples/kustomization.yaml +++ b/infra/feast-operator/config/samples/kustomization.yaml @@ -3,4 +3,7 @@ resources: - v1_featurestore.yaml - v1_featurestore_with_ui.yaml - v1_featurestore_all_remote_servers.yaml +- v1_featurestore_serving.yaml +- v1_featurestore_mcp.yaml +- v1_featurestore_materialization_openlineage.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/infra/feast-operator/config/samples/v1_featurestore_materialization_openlineage.yaml b/infra/feast-operator/config/samples/v1_featurestore_materialization_openlineage.yaml new file mode 100644 index 00000000000..f2fa585b1f8 --- /dev/null +++ b/infra/feast-operator/config/samples/v1_featurestore_materialization_openlineage.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Secret +metadata: + name: openlineage-secret + namespace: feast +stringData: + # api_key is read from this Secret and written into feature_store.yaml + api_key: "your-marquez-api-key" #pragma: allowlist secret +--- +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-materialization-openlineage + namespace: feast +spec: + feastProject: my_project + # materialization controls how features are written to the online store. + # Written into feature_store.yaml for all service pods. + materialization: + # onlineWriteBatchSize limits rows per batch to prevent OOM during materialization. + # Supported by local, Spark, and Ray engines. + onlineWriteBatchSize: 10000 + # extraConfig passes additional materialization settings inline into feature_store.yaml. + # Use for fields not typed above (e.g. pull_latest_features) or fields added + # in newer Feast SDK versions without waiting for an operator update. + # Boolean ("true"/"false") and integer strings are coerced to native YAML types. + # extraConfig: + # pull_latest_features: "false" + # openlineage emits data lineage events during feast apply and materialization. + openlineage: + enabled: true + transportType: http + # transportUrl is the base URL of your Marquez or OpenLineage-compatible server. + transportUrl: "http://marquez.feast.svc.cluster.local:5000" + transportEndpoint: "api/v1/lineage" + # apiKeySecretRef references a Secret with key "api_key" for bearer auth. + apiKeySecretRef: + name: openlineage-secret + # extraConfig passes any additional OpenLineage settings inline into feature_store.yaml. + # Use it for non-core options (namespace, producer, emit_on_apply, + # emit_on_materialize) and transport-specific settings (e.g. kafka + # bootstrap_servers, topic, sasl_mechanism; file path). + # Boolean values ("true"/"false") and integers are automatically coerced to + # their native YAML types so Feast Pydantic validators accept them. + extraConfig: + namespace: "my-feast-project" + producer: "feast-operator" + emit_on_apply: "true" + emit_on_materialize: "true" + # kafka transport example: + # bootstrap_servers: "kafka.svc:9092" + # topic: "openlineage" + # sasl_mechanism: "PLAIN" diff --git a/infra/feast-operator/config/samples/v1_featurestore_mcp.yaml b/infra/feast-operator/config/samples/v1_featurestore_mcp.yaml new file mode 100644 index 00000000000..67dd1c6947d --- /dev/null +++ b/infra/feast-operator/config/samples/v1_featurestore_mcp.yaml @@ -0,0 +1,26 @@ +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-mcp +spec: + feastProject: my_project + services: + onlineStore: + server: {} + # serving.mcp switches the feature server to MCP (Model Context Protocol) mode. + # When mcp is set, the feature_server type in feature_store.yaml is "mcp". + # MCP enables LLM-friendly tool-based access to Feast feature views. + serving: + mcp: + enabled: true + serverName: feast-mcp-server + serverVersion: "1.0.0" + # transport can be "sse" (default) or "http" + transport: sse + registry: + local: + server: + # MCP on the registry requires REST API to be enabled. + restAPI: true + mcp: + enabled: true diff --git a/infra/feast-operator/config/samples/v1_featurestore_serving.yaml b/infra/feast-operator/config/samples/v1_featurestore_serving.yaml new file mode 100644 index 00000000000..412499412e6 --- /dev/null +++ b/infra/feast-operator/config/samples/v1_featurestore_serving.yaml @@ -0,0 +1,34 @@ +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-serving +spec: + feastProject: my_project + services: + onlineStore: + server: {} + # serving configures the Feast feature_server section in feature_store.yaml. + # It controls fine-grained metrics and offline push batching. + # This section only applies to the online feature server (feast serve). + serving: + metrics: + enabled: true + # categories selectively enables or disables Feast metric categories. + # All categories default to true when metrics is enabled. + # Keys must match Feast MetricsConfig field names for your SDK version. + # When a newer Feast SDK adds a metric category you can toggle it here + # immediately — no operator update needed, the key passes through to + # feature_store.yaml and is validated by the running Feast SDK. + categories: + resource: true # CPU / memory gauges + request: true # per-endpoint latency and request counters + online_features: true # online feature retrieval metrics + push: true # push/write request counters + materialization: true # materialization counters and duration histograms + freshness: false # feature freshness gauges (can be expensive at scale) + offline_features: true # offline store retrieval counters, latency, row count + audit_logging: false # structured JSON audit logs via the feast.audit logger + offlinePushBatching: + enabled: true + batchSize: 1000 # max rows per offline write batch + batchIntervalSeconds: 10 # flush batch every 10 s diff --git a/infra/feast-operator/dist/install.yaml b/infra/feast-operator/dist/install.yaml index f0057be966e..a6453c3e6a3 100644 --- a/infra/feast-operator/dist/install.yaml +++ b/infra/feast-operator/dist/install.yaml @@ -11,7 +11,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.18.0 name: featurestores.feast.dev spec: group: feast.dev @@ -70,10 +70,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM certificate. + Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -84,8 +106,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -147,8 +175,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -247,7 +274,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -266,8 +293,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -313,6 +340,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -354,7 +385,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -506,6 +537,16 @@ spec: description: The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -537,8 +578,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -637,7 +677,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -656,8 +696,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -713,12 +753,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -742,7 +853,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -828,9 +939,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector terms. @@ -919,7 +1030,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1044,7 +1155,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1062,13 +1173,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified by - this field are not met at\nscheduling time, the pod - will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1185,7 +1296,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1198,9 +1309,9 @@ spec: (e.g. avoid putting this pod in the same node, zone, etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule pods - to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1325,7 +1436,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1343,13 +1454,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the pod - will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those matching - the labelSelector\nrelative to the given namespace(s)) - that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -1466,7 +1577,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -1664,8 +1775,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -1765,7 +1875,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -1784,8 +1894,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -1847,6 +1957,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2174,8 +2288,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2275,7 +2388,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2294,8 +2407,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2357,6 +2470,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -2515,6 +2632,81 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server section + written into feature_store.yaml for the online serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. Defaults + to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults to + "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or disables + individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to the + offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to the + offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline write + batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied to the + Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -2726,8 +2918,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -2830,7 +3021,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -2849,8 +3040,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -2891,6 +3083,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -2916,6 +3133,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -3081,6 +3302,9 @@ spec: x-kubernetes-validations: - message: At least one of restAPI or grpc must be true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -3137,6 +3361,41 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -3193,9 +3452,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -3240,9 +3508,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -3257,12 +3534,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the container @@ -3277,10 +3554,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3327,10 +3603,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3381,10 +3656,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3450,10 +3724,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3504,10 +3777,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3543,7 +3815,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target metric @@ -3554,10 +3826,9 @@ spec: metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label selector - for the given metric\nWhen set, it is - passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is a list @@ -3608,10 +3879,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3646,7 +3916,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -3657,10 +3927,9 @@ spec: for the given metric properties: averageUtilization: - description: "averageUtilization is the - target value of the average of the\nresource - metric across all relevant pods, represented - as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -3754,6 +4023,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -3792,13 +4065,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -3909,7 +4187,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -3945,8 +4223,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -4045,7 +4322,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -4064,8 +4341,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -4126,6 +4403,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -4294,7 +4575,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -4336,6 +4617,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -4344,9 +4626,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -4377,7 +4660,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -4425,7 +4708,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -4471,7 +4754,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -4511,7 +4794,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -4523,7 +4806,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -4585,7 +4868,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -4834,9 +5117,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -4871,7 +5154,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -4892,7 +5175,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -4902,7 +5185,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -4931,7 +5214,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4949,9 +5232,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -4991,6 +5273,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -5016,6 +5314,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -5106,7 +5405,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5123,7 +5422,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -5153,10 +5452,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -5236,7 +5538,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -5307,7 +5609,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -5356,7 +5658,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5422,7 +5724,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -5437,12 +5739,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -5458,9 +5760,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -5472,6 +5773,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -5486,6 +5788,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5513,6 +5816,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5527,6 +5831,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -5564,6 +5869,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -5598,7 +5904,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -5673,7 +5979,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -5703,7 +6009,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -5762,10 +6067,32 @@ spec: OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider. https://auth0. properties: + caCertConfigMap: + description: ConfigMap with the CA certificate for self-signed + OIDC providers. Auto-detected on RHOAI/ODH. + properties: + key: + description: Key in the ConfigMap holding the PEM + certificate. Defaults to "ca-bundle.crt". + type: string + name: + description: ConfigMap name. + type: string + required: + - name + type: object + issuerUrl: + description: OIDC issuer URL. The operator appends /.well-known/openid-configuration + to derive the discovery endpoint. + pattern: ^https://\S+$ + type: string + secretKeyName: + description: Key in the Secret containing all OIDC properties + as a YAML value. If unset, each key is a property. + type: string secretRef: - description: |- - LocalObjectReference contains enough information to let you locate the - referenced object inside the same namespace. + description: Secret with OIDC properties (auth_discovery_url, + client_id, client_secret). issuerUrl takes precedence. properties: name: default: "" @@ -5776,8 +6103,14 @@ spec: type: string type: object x-kubernetes-map-type: atomic - required: - - secretRef + tokenEnvVar: + description: Env var name for client pods to read an OIDC + token from. Sets token_env_var in client config. + type: string + verifySSL: + description: Verify SSL certificates for the OIDC provider. + Defaults to true. + type: boolean type: object type: object x-kubernetes-validations: @@ -5841,8 +6174,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -5942,7 +6274,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -5961,8 +6293,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6009,6 +6341,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -6050,7 +6386,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -6204,6 +6540,16 @@ spec: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. type: string type: object + dataQualityMonitoring: + description: DataQualityMonitoring configures Data Quality Monitoring + behaviour. + properties: + autoBaseline: + default: true + description: AutoBaseline controls whether baseline distribution + is computed automatically on feast apply. Defaults to true. + type: boolean + type: object feastProject: description: FeastProject is the Feast project id. pattern: ^[A-Za-z0-9][A-Za-z0-9_-]*$ @@ -6236,8 +6582,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -6337,7 +6682,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -6356,8 +6701,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -6414,12 +6759,83 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object x-kubernetes-validations: - message: One selection required between init or git. rule: '[has(self.git), has(self.init)].exists_one(c, c)' + materialization: + description: |- + Materialization controls feature materialization behavior (batch size, pull strategy). + Written into feature_store. + properties: + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig passes additional materialization key-value settings inline into + feature_store.yaml. + type: object + onlineWriteBatchSize: + description: |- + Number of rows per batch when writing to the online store during materialization. + Prevents OOM for large feature views. + format: int32 + minimum: 1 + type: integer + type: object + openlineage: + description: |- + OpenLineage enables OpenLineage data lineage tracking for Feast operations. + Written into feature_store. + properties: + apiKeySecretRef: + description: Reference to a Secret containing the key "api_key" + for lineage server authentication. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. + type: string + type: object + x-kubernetes-map-type: atomic + enabled: + description: Enable OpenLineage integration. + type: boolean + extraConfig: + additionalProperties: + type: string + description: |- + ExtraConfig holds additional OpenLineage key-value settings written inline into + the openlineage block of feature_store. + type: object + transportEndpoint: + description: API endpoint path appended to transportUrl. Defaults + to "api/v1/lineage". + type: string + transportType: + description: Transport type for lineage events. + enum: + - http + - console + - file + - kafka + type: string + transportUrl: + description: URL for HTTP transport (e.g. http://marquez:5000). + Required when transportType is "http". + type: string + required: + - enabled + type: object replicas: default: 1 description: |- @@ -6443,7 +6859,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: |- An empty preferred scheduling term matches all objects with implicit weight 0 @@ -6530,9 +6946,9 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... properties: nodeSelectorTerms: description: Required. A list of node selector @@ -6621,7 +7037,7 @@ spec: preferredDuringSchedulingIgnoredDuringExecution: description: |- The scheduler will prefer to schedule pods to nodes that satisfy - the affinity expressions specified by this field, but i + the affinity expressions specified by this field, but... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -6749,7 +7165,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6767,13 +7183,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled onto " + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -6890,7 +7306,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -6904,9 +7320,9 @@ spec: etc. properties: preferredDuringSchedulingIgnoredDuringExecution: - description: "The scheduler will prefer to schedule - pods to nodes that satisfy\nthe anti-affinity expressions - specified by this field, " + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field,... items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7034,7 +7450,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7052,13 +7468,13 @@ spec: type: array x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: - description: "If the anti-affinity requirements specified - by this field are not met at\nscheduling time, the - pod will not be scheduled " + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled... items: - description: "Defines a set of pods (namely those - matching the labelSelector\nrelative to the given - namespace(s)) that this pod should " + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should... properties: labelSelector: description: |- @@ -7175,7 +7591,7 @@ spec: topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - the labelSelector in t + the labelSelector in... type: string required: - topologyKey @@ -7376,8 +7792,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7480,7 +7895,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -7499,8 +7914,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -7562,6 +7978,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -7894,8 +8314,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -7998,7 +8417,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8017,8 +8436,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8080,6 +8500,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8239,6 +8663,83 @@ spec: type: integer type: object type: object + serving: + description: Serving configures the Feast feature_server + section written into feature_store.yaml for the online + serve pod. + properties: + mcp: + description: Mcp enables MCP (Model Context Protocol) + server support. When set, feature server type is + "mcp". + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object + metrics: + description: |- + Metrics configures per-category Prometheus metrics for the feature server. + Coexists with the server. + properties: + categories: + additionalProperties: + type: boolean + description: Categories selectively enables or + disables individual Feast metric categories. + type: object + enabled: + description: Enable the Prometheus metrics endpoint + on port 8000. + type: boolean + required: + - enabled + type: object + offlinePushBatching: + description: OfflinePushBatching batches writes to + the offline store via the /push endpoint. + properties: + batchIntervalSeconds: + description: Seconds between batch flushes to + the offline store. + format: int32 + minimum: 1 + type: integer + batchSize: + description: Maximum number of rows per offline + write batch. + format: int32 + minimum: 1 + type: integer + enabled: + description: Enable offline push batching. + type: boolean + required: + - enabled + type: object + type: object + type: object + podAnnotations: + additionalProperties: + type: string + description: PodAnnotations are annotations to be applied + to the Deployment's PodTemplate metadata. type: object podDisruptionBudgets: description: PodDisruptionBudgets configures a PodDisruptionBudget @@ -8458,8 +8959,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -8564,7 +9064,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -8583,9 +9083,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -8626,6 +9126,31 @@ spec: - error - critical type: string + mcp: + description: |- + Mcp enables MCP (Model Context Protocol) on the REST registry server. + Requires restAPI to be true. + properties: + enabled: + description: Enable the MCP server. + type: boolean + serverName: + description: MCP server name for identification. + Defaults to "feast-mcp-server". + type: string + serverVersion: + description: MCP server version string. Defaults + to "1.0.0". + type: string + transport: + description: MCP transport protocol. + enum: + - sse + - http + type: string + required: + - enabled + type: object metrics: description: Metrics exposes Prometheus-compatible metrics for the Feast server when enabled. @@ -8651,6 +9176,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -8822,6 +9351,9 @@ spec: true rule: self.restAPI == true || self.grpc == true || !has(self.grpc) + - message: MCP requires restAPI to be true + rule: '!has(self.mcp) || !self.mcp.enabled || (has(self.restAPI) + && self.restAPI == true)' type: object remote: description: RemoteRegistryConfig points to a remote feast @@ -8879,6 +9411,42 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim, either directly + or by naming a ResourceClaimTemplate which is... + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean scaling: description: Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). @@ -8936,9 +9504,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object scaleUp: description: scaleUp is scaling policy for scaling @@ -8984,9 +9561,18 @@ spec: stabilizationWindowSeconds: description: |- stabilizationWindowSeconds is the number of seconds for which past recommendations should be - considered while scaling up + considered while scaling... format: int32 type: integer + tolerance: + anyOf: + - type: integer + - type: string + description: |- + tolerance is the tolerance on the ratio between the current and desired + metric value under which no updates are made to... + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true type: object type: object maxReplicas: @@ -9001,12 +9587,12 @@ spec: items: description: |- MetricSpec specifies how to scale based on a single metric - (only `type` and one other matching field should be set at on + (only `type` and one other matching field should be set at... properties: containerResource: description: |- containerResource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes descr + requests and limits) known to Kubernetes... properties: container: description: container is the name of the @@ -9021,10 +9607,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9071,10 +9656,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9125,10 +9709,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9195,10 +9778,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9249,10 +9831,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9288,7 +9869,7 @@ spec: pods: description: |- pods refers to a metric describing each pod in the current scale target - (for example, transactions-processed-per-second) + (for example,... properties: metric: description: metric identifies the target @@ -9299,10 +9880,9 @@ spec: given metric type: string selector: - description: "selector is the string-encoded - form of a standard kubernetes label - selector for the given metric\nWhen - set, it is passed " + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed... properties: matchExpressions: description: matchExpressions is @@ -9353,10 +9933,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9391,7 +9970,7 @@ spec: resource: description: |- resource refers to a resource metric (such as those specified in - requests and limits) known to Kubernetes describing eac + requests and limits) known to Kubernetes describing... properties: name: description: name is the name of the resource @@ -9402,10 +9981,9 @@ spec: value for the given metric properties: averageUtilization: - description: "averageUtilization is - the target value of the average of - the\nresource metric across all relevant - pods, represented as a " + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a... format: int32 type: integer averageValue: @@ -9499,6 +10077,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -9538,13 +10121,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -9658,7 +10246,7 @@ spec: nodeAffinityPolicy: description: |- NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector - when calculating pod topology spread skew + when calculating pod topology spread... type: string nodeTaintsPolicy: description: |- @@ -9694,8 +10282,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -9795,7 +10382,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -9814,8 +10401,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -9877,6 +10464,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -10045,7 +10636,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -10087,6 +10678,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -10095,9 +10687,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -10128,7 +10721,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -10177,7 +10770,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -10223,7 +10816,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -10263,7 +10856,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -10276,7 +10869,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -10340,7 +10933,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -10592,9 +11185,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -10629,7 +11222,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -10650,7 +11243,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -10660,7 +11253,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -10689,7 +11282,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10707,9 +11300,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -10749,6 +11341,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -10774,6 +11382,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -10865,7 +11474,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10882,7 +11491,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -10912,10 +11521,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -10996,7 +11608,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -11069,7 +11681,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -11118,7 +11730,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11184,7 +11796,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -11199,12 +11811,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -11220,9 +11832,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -11234,6 +11845,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -11248,6 +11860,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11275,6 +11888,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11289,6 +11903,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -11326,6 +11941,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -11360,7 +11976,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -11435,7 +12051,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -11466,7 +12082,6 @@ spec: type: object required: - feastProject - - replicas type: object x-kubernetes-validations: - message: replicas > 1 and services.scaling.autoscaling are mutually @@ -11541,10 +12156,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -11715,8 +12327,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -11815,7 +12426,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -11834,8 +12445,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -11881,6 +12492,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -11922,7 +12537,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -12105,8 +12720,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -12205,7 +12819,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12224,8 +12838,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12281,6 +12895,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -12479,8 +13097,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -12580,7 +13197,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -12599,8 +13216,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -12662,6 +13279,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -12989,8 +13610,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13090,7 +13710,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13109,8 +13729,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13172,6 +13792,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -13517,8 +14141,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -13621,7 +14244,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -13640,8 +14263,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -13707,6 +14331,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -13928,6 +14556,10 @@ spec: x-kubernetes-validations: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the registry. + Defaults to true. Ignored when DisableInitContainers is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -13973,6 +14605,10 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. properties: @@ -14011,13 +14647,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -14074,8 +14715,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's value. @@ -14174,7 +14814,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of a set - of ConfigMaps + of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -14193,8 +14833,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name of + each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -14255,6 +14895,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for a request + in the referenced claim. + type: string required: - name type: object @@ -14423,7 +15067,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the volume @@ -14465,6 +15109,7 @@ spec: blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -14473,9 +15118,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -14506,7 +15152,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: monitors: description: |- @@ -14554,7 +15200,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -14600,7 +15246,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -14640,7 +15286,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver that @@ -14652,7 +15298,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -14714,7 +15360,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -14963,9 +15609,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide identifiers - (wwids)\nEither wwids or combination of targetWWNs - and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -15000,7 +15646,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -15021,7 +15667,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -15031,7 +15677,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -15060,7 +15706,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15078,9 +15724,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount on the + host that shares a pod's lifetime. properties: endpoints: description: |- @@ -15120,6 +15765,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -15145,6 +15806,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -15235,7 +15897,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15252,7 +15914,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -15282,10 +15944,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected along - with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod to @@ -15365,7 +16030,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -15436,7 +16101,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -15485,7 +16150,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15551,7 +16216,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime + that shares a pod's lifetime. properties: group: description: |- @@ -15566,12 +16231,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -15587,9 +16252,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount on + the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the volume @@ -15601,6 +16265,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -15615,6 +16280,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15642,6 +16308,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15656,6 +16323,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -15693,6 +16361,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -15727,7 +16396,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -15802,7 +16471,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine + and mounted on kubelets host machine. properties: fsType: description: |- @@ -15918,8 +16587,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16019,7 +16687,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16038,8 +16706,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16086,6 +16754,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -16127,7 +16799,7 @@ spec: activeDeadlineSeconds: description: |- Specifies the duration in seconds relative to the startTime that the job - may be continuously active before the system tr + may be continuously active before the system... format: int64 type: integer backoffLimit: @@ -16313,8 +16985,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16414,7 +17085,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16433,8 +17104,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16491,6 +17162,10 @@ spec: - hazelcast - couchbase - clickhouse + - milvus + - ray + - ray_rag + - pytorch_nlp type: string type: object type: object @@ -16692,8 +17367,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -16796,7 +17470,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -16815,8 +17489,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -16878,6 +17553,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17210,8 +17889,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -17314,7 +17992,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17333,8 +18011,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the + name of each environment variable. Must be + a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17396,6 +18075,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -17750,8 +18433,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment @@ -17856,7 +18538,7 @@ spec: envFrom: items: description: EnvFromSource represents the source - of a set of ConfigMaps + of a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -17875,9 +18557,9 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend - to each key in the ConfigMap. Must be - a C_IDENTIFIER. + description: Optional text to prepend to + the name of each environment variable. + Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -17943,6 +18625,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen + for a request in the referenced claim. + type: string required: - name type: object @@ -18171,6 +18857,11 @@ spec: - message: One selection required. rule: '[has(self.local), has(self.remote)].exists_one(c, c)' + runFeastApplyOnInit: + description: Runs feast apply on pod start to populate the + registry. Defaults to true. Ignored when DisableInitContainers + is true. + type: boolean securityContext: description: PodSecurityContext holds pod-level security attributes and common container settings. @@ -18216,6 +18907,11 @@ spec: Defaults to user specified in image metadata if unspecified. format: int64 type: integer + seLinuxChangePolicy: + description: seLinuxChangePolicy defines how the container's + SELinux label is applied to all volumes used by the + Pod. + type: string seLinuxOptions: description: The SELinux context to be applied to all containers. @@ -18255,13 +18951,18 @@ spec: type: object supplementalGroups: description: |- - A list of groups applied to the first process run in each container, in addition - to the container's primary GID, the fsG + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and... items: format: int64 type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". + type: string sysctls: description: Sysctls hold a list of namespaced sysctls used for the pod. @@ -18319,8 +19020,7 @@ spec: value: description: |- Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any + using the previously defined environment variables in the container and... type: string valueFrom: description: Source for the environment variable's @@ -18420,7 +19120,7 @@ spec: envFrom: items: description: EnvFromSource represents the source of - a set of ConfigMaps + a set of ConfigMaps or Secrets properties: configMapRef: description: The ConfigMap to select from @@ -18439,8 +19139,8 @@ spec: type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. + description: Optional text to prepend to the name + of each environment variable. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -18502,6 +19202,10 @@ spec: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. type: string + request: + description: Request is the name chosen for + a request in the referenced claim. + type: string required: - name type: object @@ -18670,7 +19374,7 @@ spec: awsElasticBlockStore: description: |- awsElasticBlockStore represents an AWS Disk resource that is attached to a - kubelet's host machine and then exposed to th + kubelet's host machine and then exposed to... properties: fsType: description: fsType is the filesystem type of the @@ -18712,6 +19416,7 @@ spec: the blob storage type: string fsType: + default: ext4 description: |- fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -18720,9 +19425,10 @@ spec: kind: description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single - blob disk per storage accoun' + blob disk per storage...' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -18753,7 +19459,7 @@ spec: type: object cephfs: description: cephFS represents a Ceph FS mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: monitors: description: |- @@ -18802,7 +19508,7 @@ spec: cinder: description: |- cinder represents a cinder volume attached and mounted on kubelets host machine. - More info: https://examples.k8s. + Deprecated: Cinder is deprecated. properties: fsType: description: |- @@ -18848,7 +19554,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -18888,7 +19594,7 @@ spec: csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external - CSI drivers (Beta fea + CSI drivers. properties: driver: description: driver is the name of the CSI driver @@ -18901,7 +19607,7 @@ spec: nodePublishSecretRef: description: |- nodePublishSecretRef is a reference to the secret object containing - sensitive information to pass to the CSI driver to c + sensitive information to pass to the CSI driver to... properties: name: default: "" @@ -18965,7 +19671,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19217,9 +19923,9 @@ spec: type: array x-kubernetes-list-type: atomic wwids: - description: "wwids Optional: FC volume world wide - identifiers (wwids)\nEither wwids or combination - of targetWWNs and lun must be set, " + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set,... items: type: string type: array @@ -19254,7 +19960,7 @@ spec: secretRef: description: |- secretRef is Optional: secretRef is reference to the secret object containing - sensitive information to pass to the plugi + sensitive information to pass to the... properties: name: default: "" @@ -19275,7 +19981,7 @@ spec: datasetName: description: |- datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker - should be considered as depreca + should be considered as... type: string datasetUUID: description: datasetUUID is the UUID of the dataset. @@ -19285,7 +19991,7 @@ spec: gcePersistentDisk: description: |- gcePersistentDisk represents a GCE Disk resource that is attached to a - kubelet's host machine and then exposed to the po + kubelet's host machine and then exposed to the... properties: fsType: description: fsType is filesystem type of the volume @@ -19314,7 +20020,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19332,9 +20038,8 @@ spec: - repository type: object glusterfs: - description: |- - glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: glusterfs represents a Glusterfs mount + on the host that shares a pod's lifetime. properties: endpoints: description: |- @@ -19374,6 +20079,22 @@ spec: required: - path type: object + image: + description: image represents an OCI object (a container + image or artifact) pulled and mounted on the kubelet's + host machine. + properties: + pullPolicy: + description: |- + Policy for pulling OCI objects. Possible values are: + Always: the kubelet always attempts to pull the reference. + type: string + reference: + description: |- + Required: Image or artifact reference to be used. + Behaves in the same way as pod.spec.containers[*].image. + type: string + type: object iscsi: description: |- iscsi represents an ISCSI Disk resource that is attached to a @@ -19399,6 +20120,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -19490,7 +20212,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19507,7 +20229,7 @@ spec: type: object portworxVolume: description: portworxVolume represents a portworx volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -19537,10 +20259,13 @@ spec: format: int32 type: integer sources: - description: sources is the list of volume projections + description: |- + sources is the list of volume projections. Each entry in this list + handles one source. items: - description: Projection that may be projected - along with other supported volume types + description: |- + Projection that may be projected along with other supported volume types. + Exactly one of these fields must be set. properties: clusterTrustBundle: description: ClusterTrustBundle allows a pod @@ -19621,7 +20346,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - ConfigMap will be projected into the volum + ConfigMap will be projected into the... items: description: Maps a string key to a path within a volume. @@ -19694,7 +20419,7 @@ spec: mode: description: |- Optional: mode bits used to set permissions on this file, must be an octal value - between 0000 and 0777 or a decimal valu + between 0000 and 0777 or a decimal... format: int32 type: integer path: @@ -19743,7 +20468,7 @@ spec: items: description: |- items if unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -19809,7 +20534,7 @@ spec: type: object quobyte: description: quobyte represents a Quobyte mount on the - host that shares a pod's lifetime + host that shares a pod's lifetime. properties: group: description: |- @@ -19824,12 +20549,12 @@ spec: registry: description: |- registry represents a single or multiple Quobyte Registry services - specified as a string as host:port pair (multiple ent + specified as a string as host:port pair (multiple... type: string tenant: description: |- tenant owning the given Quobyte volume in the Backend - Used with dynamically provisioned Quobyte volumes, value is set by + Used with dynamically provisioned Quobyte volumes, value is set... type: string user: description: |- @@ -19845,9 +20570,8 @@ spec: - volume type: object rbd: - description: |- - rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. - More info: https://examples.k8s. + description: rbd represents a Rados Block Device mount + on the host that shares a pod's lifetime. properties: fsType: description: fsType is the filesystem type of the @@ -19859,6 +20583,7 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it type: string keyring: + default: /etc/ceph/keyring description: |- keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. @@ -19873,6 +20598,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19900,6 +20626,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19914,6 +20641,7 @@ spec: volume attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -19951,6 +20679,7 @@ spec: communication with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. type: string @@ -19985,7 +20714,7 @@ spec: items: description: |- items If unspecified, each key-value pair in the Data field of the referenced - Secret will be projected into the volume a + Secret will be projected into the volume... items: description: Maps a string key to a path within a volume. @@ -20060,7 +20789,7 @@ spec: type: object vsphereVolume: description: vsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine + attached and mounted on kubelets host machine. properties: fsType: description: |- @@ -20134,10 +20863,7 @@ spec: - Unknown type: string type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - --- - Many .condition. + description: type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -20234,6 +20960,8 @@ metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: feast-operator + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" name: feast-operator-featurestore-editor-role rules: - apiGroups: @@ -20261,6 +20989,7 @@ metadata: labels: app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: feast-operator + rbac.authorization.k8s.io/aggregate-to-view: "true" name: feast-operator-featurestore-viewer-role rules: - apiGroups: @@ -20284,9 +21013,12 @@ metadata: name: feast-operator-manager-role rules: - apiGroups: - - apps + - "" resources: - - deployments + - configmaps + - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - delete @@ -20295,65 +21027,62 @@ rules: - update - watch - apiGroups: - - authentication.k8s.io + - "" resources: - - tokenreviews + - namespaces + - pods + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods/exec verbs: - create - apiGroups: - - autoscaling + - apps resources: - - horizontalpodautoscalers + - deployments verbs: - create - delete - get - list - - patch - update - watch - apiGroups: - - batch + - authentication.k8s.io resources: - - cronjobs + - tokenreviews verbs: - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - - "" + - autoscaling resources: - - configmaps - - persistentvolumeclaims - - serviceaccounts - - services + - horizontalpodautoscalers verbs: - create - delete - get - list + - patch - update - watch - apiGroups: - - "" + - batch resources: - - namespaces - - pods - - secrets + - cronjobs verbs: + - create + - delete - get - list + - patch + - update - watch -- apiGroups: - - "" - resources: - - pods/exec - verbs: - - create - apiGroups: - feast.dev resources: @@ -20380,6 +21109,17 @@ rules: - get - patch - update +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - watch - apiGroups: - policy resources: @@ -20553,10 +21293,14 @@ spec: - /manager env: - name: RELATED_IMAGE_FEATURE_SERVER - value: quay.io/feastdev/feature-server:0.61.0 + value: quay.io/feastdev/feature-server:0.64.0 - name: RELATED_IMAGE_CRON_JOB value: quay.io/openshift/origin-cli:4.17 - image: quay.io/feastdev/feast-operator:0.61.0 + - name: GOMEMLIMIT + value: 230MiB + - name: OIDC_ISSUER_URL + value: "" + image: quay.io/feastdev/feast-operator:0.64.0 livenessProbe: httpGet: path: /healthz diff --git a/infra/feast-operator/dist/operator-e2e-tests b/infra/feast-operator/dist/operator-e2e-tests index 48c66b9be7c..cb65e549ff8 100755 Binary files a/infra/feast-operator/dist/operator-e2e-tests and b/infra/feast-operator/dist/operator-e2e-tests differ diff --git a/infra/feast-operator/docs/api/markdown/ref.md b/infra/feast-operator/docs/api/markdown/ref.md index 698c3f6bbe3..dd7acf55fb3 100644 --- a/infra/feast-operator/docs/api/markdown/ref.md +++ b/infra/feast-operator/docs/api/markdown/ref.md @@ -104,6 +104,20 @@ _Appears in:_ Defaults to "feast apply" & "feast materialize-incremental $(date -u +'%Y-%m-%dT%H:%M:%S')" | +#### DataQualityMonitoringConfig + + + +DataQualityMonitoringConfig defines the Data Quality Monitoring configuration. + +_Appears in:_ +- [FeatureStoreSpec](#featurestorespec) + +| Field | Description | +| --- | --- | +| `autoBaseline` _boolean_ | AutoBaseline controls whether baseline distribution is computed automatically on feast apply. Defaults to true. | + + #### DefaultCtrConfigs @@ -150,7 +164,6 @@ time for any reason. Missed jobs executions will be counted as failed ones. | | `concurrencyPolicy` _[ConcurrencyPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#concurrencypolicy-v1-batch)_ | Specifies how to treat concurrent executions of a Job. Valid values are: - - "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - "Replace": cancels currently running job and replaces it with a new one | @@ -239,7 +252,11 @@ _Appears in:_ | `ui` _[ServerConfigs](#serverconfigs)_ | Creates a UI server container | | `deploymentStrategy` _[DeploymentStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#deploymentstrategy-v1-apps)_ | | | `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#podsecuritycontext-v1-core)_ | | +| `podAnnotations` _object (keys:string, values:string)_ | PodAnnotations are annotations to be applied to the Deployment's PodTemplate metadata. +This enables annotation-driven integrations like OpenTelemetry auto-instrumentation, +Istio sidecar injection, Vault agent injection, etc. | | `disableInitContainers` _boolean_ | Disable the 'feast repo initialization' initContainer | +| `runFeastApplyOnInit` _boolean_ | Runs feast apply on pod start to populate the registry. Defaults to true. Ignored when DisableInitContainers is true. | | `volumes` _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volume-v1-core) array_ | Volumes specifies the volumes to mount in the FeatureStore deployment. A corresponding `VolumeMount` should be added to whichever feast service(s) require access to said volume(s). | | `scaling` _[ScalingConfig](#scalingconfig)_ | Scaling configures horizontal scaling for the FeatureStore deployment (e.g. HPA autoscaling). For static replicas, use spec.replicas instead. | @@ -252,6 +269,10 @@ Set to an empty array to disable auto-injection. | | `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#affinity-v1-core)_ | Affinity defines the pod scheduling constraints for the FeatureStore deployment. When scaling is enabled and this is not set, the operator auto-injects a soft pod anti-affinity rule to prefer spreading pods across nodes. | +| `resourceClaims` _[PodResourceClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#podresourceclaim-v1-core) array_ | ResourceClaims defines which ResourceClaims must be allocated +and reserved before the Pod is allowed to start. The resources +will be made available to those containers which consume them +by name. | #### FeatureStoreSpec @@ -272,8 +293,13 @@ _Appears in:_ | `authz` _[AuthzConfig](#authzconfig)_ | | | `cronJob` _[FeastCronJob](#feastcronjob)_ | | | `batchEngine` _[BatchEngineConfig](#batchengineconfig)_ | | +| `dataQualityMonitoring` _[DataQualityMonitoringConfig](#dataqualitymonitoringconfig)_ | DataQualityMonitoring configures Data Quality Monitoring behaviour. | | `replicas` _integer_ | Replicas is the desired number of pod replicas. Used by the scale sub-resource. Mutually exclusive with services.scaling.autoscaling. | +| `materialization` _[MaterializationConfig](#materializationconfig)_ | Materialization controls feature materialization behavior (batch size, pull strategy). +Written into feature_store.yaml for all service pods. | +| `openlineage` _[OpenLineageConfig](#openlineageconfig)_ | OpenLineage enables OpenLineage data lineage tracking for Feast operations. +Written into feature_store.yaml for all service pods. | #### FeatureStoreStatus @@ -358,7 +384,6 @@ represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure. - This field is beta-level. It can be used when the `JobPodFailurePolicy` feature gate is enabled (enabled by default). | | `backoffLimit` _integer_ | Specifies the number of retries before marking this job failed. | @@ -390,12 +415,10 @@ the Job becomes eligible to be deleted immediately after it finishes. | | `completionMode` _[CompletionMode](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#completionmode-v1-batch)_ | completionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`. - `NonIndexed` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other. - `Indexed` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. @@ -407,7 +430,6 @@ In addition, The Pod name takes the form `$(job-name)-$(index)-$(random-string)`, the Pod hostname takes the form `$(job-name)-$(index)`. - More completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, which is possible during upgrades due to version skew, the controller @@ -426,7 +448,6 @@ Possible values are: - Failed means to wait until a previously created Pod is fully terminated (has phase Failed or Succeeded) before creating a replacement Pod. - When using podFailurePolicy, Failed is the the only allowed value. TerminatingOrFailed and Failed are allowed values when podFailurePolicy is not in use. This is an beta field. To use this, enable the JobPodReplacementPolicy feature toggle. @@ -468,6 +489,60 @@ _Appears in:_ | `persistence` _[RegistryPersistence](#registrypersistence)_ | | +#### MaterializationConfig + + + +MaterializationConfig controls feature materialization behavior written into feature_store.yaml. + +_Appears in:_ +- [FeatureStoreSpec](#featurestorespec) + +| Field | Description | +| --- | --- | +| `onlineWriteBatchSize` _integer_ | Number of rows per batch when writing to the online store during materialization. +Prevents OOM for large feature views. Supported engines: local, spark, ray. +If unset, all rows are written in a single batch. | +| `extraConfig` _object (keys:string, values:string)_ | ExtraConfig passes additional materialization key-value settings inline into +feature_store.yaml. | + + +#### McpConfig + + + +McpConfig enables MCP (Model Context Protocol) server support in the feature server. +When this field is set on ServingConfig, the feature server type is switched to "mcp". + +_Appears in:_ +- [RegistryServerConfigs](#registryserverconfigs) +- [ServingConfig](#servingconfig) + +| Field | Description | +| --- | --- | +| `enabled` _boolean_ | Enable the MCP server. | +| `serverName` _string_ | MCP server name for identification. Defaults to "feast-mcp-server". | +| `serverVersion` _string_ | MCP server version string. Defaults to "1.0.0". | +| `transport` _string_ | MCP transport protocol. | + + +#### OfflinePushBatchingConfig + + + +OfflinePushBatchingConfig controls batching of writes to the offline store via the /push endpoint. +Recommended for high-throughput push workloads (streaming pipelines, IoT) to prevent OOM. + +_Appears in:_ +- [ServingConfig](#servingconfig) + +| Field | Description | +| --- | --- | +| `enabled` _boolean_ | Enable offline push batching. | +| `batchSize` _integer_ | Maximum number of rows per offline write batch. | +| `batchIntervalSeconds` _integer_ | Seconds between batch flushes to the offline store. | + + #### OfflineStore @@ -541,7 +616,27 @@ _Appears in:_ | Field | Description | | --- | --- | -| `secretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core)_ | | +| `issuerUrl` _string_ | OIDC issuer URL. The operator appends /.well-known/openid-configuration to derive the discovery endpoint. | +| `secretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core)_ | Secret with OIDC properties (auth_discovery_url, client_id, client_secret). issuerUrl takes precedence. | +| `secretKeyName` _string_ | Key in the Secret containing all OIDC properties as a YAML value. If unset, each key is a property. | +| `tokenEnvVar` _string_ | Env var name for client pods to read an OIDC token from. Sets token_env_var in client config. | +| `verifySSL` _boolean_ | Verify SSL certificates for the OIDC provider. Defaults to true. | +| `caCertConfigMap` _[OidcCACertConfigMap](#oidccacertconfigmap)_ | ConfigMap with the CA certificate for self-signed OIDC providers. Auto-detected on RHOAI/ODH. | + + +#### OidcCACertConfigMap + + + +OidcCACertConfigMap references a ConfigMap containing a CA certificate for OIDC provider TLS. + +_Appears in:_ +- [OidcAuthz](#oidcauthz) + +| Field | Description | +| --- | --- | +| `name` _string_ | ConfigMap name. | +| `key` _string_ | Key in the ConfigMap holding the PEM certificate. Defaults to "ca-bundle.crt". | #### OnlineStore @@ -557,6 +652,8 @@ _Appears in:_ | --- | --- | | `server` _[ServerConfigs](#serverconfigs)_ | Creates a feature server container | | `persistence` _[OnlineStorePersistence](#onlinestorepersistence)_ | | +| `serving` _[ServingConfig](#servingconfig)_ | Serving configures the Feast feature_server section written into feature_store.yaml for the online serve pod. +Controls metrics granularity, offline push batching, and MCP. | #### OnlineStoreDBStorePersistence @@ -605,6 +702,32 @@ _Appears in:_ | `store` _[OnlineStoreDBStorePersistence](#onlinestoredbstorepersistence)_ | | +#### OpenLineageConfig + + + +OpenLineageConfig enables OpenLineage data lineage tracking for Feast operations. +Lineage events are emitted during feast apply and materialization when enabled. + +_Appears in:_ +- [FeatureStoreSpec](#featurestorespec) + +| Field | Description | +| --- | --- | +| `enabled` _boolean_ | Enable OpenLineage integration. | +| `transportType` _string_ | Transport type for lineage events. | +| `transportUrl` _string_ | URL for HTTP transport (e.g. http://marquez:5000). Required when transportType is "http". | +| `transportEndpoint` _string_ | API endpoint path appended to transportUrl. Defaults to "api/v1/lineage". | +| `apiKeySecretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core)_ | Reference to a Secret containing the key "api_key" for lineage server authentication. | +| `extraConfig` _object (keys:string, values:string)_ | ExtraConfig holds additional OpenLineage key-value settings written inline into +the openlineage block of feature_store.yaml alongside the typed fields above. +Use this for non-core settings (e.g. namespace, producer, emit_on_apply, +emit_on_materialize) and transport-specific options (e.g. kafka +bootstrap_servers, topic; file path). Boolean values ("true"/"false") and +integer values are automatically coerced to their native YAML types. +Keys must be valid Feast OpenLineageConfig YAML field names. | + + #### OptionalCtrConfigs @@ -780,6 +903,8 @@ volume definition in the Volumes field. | These options are primarily used for production deployments to optimize performance. | | `restAPI` _boolean_ | Enable REST API registry server. | | `grpc` _boolean_ | Enable gRPC registry server. Defaults to true if unset. | +| `mcp` _[McpConfig](#mcpconfig)_ | Mcp enables MCP (Model Context Protocol) on the REST registry server. +Requires restAPI to be true. Reuses the same McpConfig struct as the online store. | #### RemoteRegistryConfig @@ -894,6 +1019,44 @@ _Appears in:_ | `ui` _string_ | | +#### ServingConfig + + + +ServingConfig configures the feature_server section of the generated feature_store.yaml. +When Mcp is set, the feature server type is switched to "mcp"; otherwise "local" is used. + +_Appears in:_ +- [OnlineStore](#onlinestore) + +| Field | Description | +| --- | --- | +| `metrics` _[ServingMetricsConfig](#servingmetricsconfig)_ | Metrics configures per-category Prometheus metrics for the feature server. +Coexists with the server.metrics bool flag — both can be set simultaneously. | +| `offlinePushBatching` _[OfflinePushBatchingConfig](#offlinepushbatchingconfig)_ | OfflinePushBatching batches writes to the offline store via the /push endpoint. | +| `mcp` _[McpConfig](#mcpconfig)_ | Mcp enables MCP (Model Context Protocol) server support. When set, feature server type is "mcp". | + + +#### ServingMetricsConfig + + + +ServingMetricsConfig controls per-category Prometheus metrics for the feature server. +Setting Enabled to true activates the metrics HTTP server on port 8000. +All metric categories default to true when enabled; use Categories to selectively disable them. + +_Appears in:_ +- [ServingConfig](#servingconfig) + +| Field | Description | +| --- | --- | +| `enabled` _boolean_ | Enable the Prometheus metrics endpoint on port 8000. | +| `categories` _object (keys:string, values:boolean)_ | Categories selectively enables or disables individual Feast metric categories. +Keys are Feast MetricsConfig field names (e.g. "resource", "request", +"online_features", "push", "materialization", "freshness"). Omitted keys +default to true when metrics is enabled. | + + #### TlsConfigs diff --git a/infra/feast-operator/docs/odh-operator-parameters.md b/infra/feast-operator/docs/odh-operator-parameters.md new file mode 100644 index 00000000000..8b29d4d1ca8 --- /dev/null +++ b/infra/feast-operator/docs/odh-operator-parameters.md @@ -0,0 +1,15 @@ +# Open Data Hub / RHOAI operator parameters + +These values are supplied through the Feast operator **`params.env`** files in the **ODH** and **RHOAI** overlays (`config/overlays/odh/params.env`, `config/overlays/rhoai/params.env`). The Open Data Hub operator updates keys in `params.env` before rendering; Kustomize **`replacements`** copy them into the controller Deployment. + +## `OIDC_ISSUER_URL` + +**Purpose:** OIDC issuer URL when the OpenShift cluster uses external OIDC (for example Keycloak). The Feast operator process receives it as the **`OIDC_ISSUER_URL`** environment variable. An empty value means the cluster is not using external OIDC in this integration path (OpenShift OAuth / default behavior). + +**Manifest parameter:** `OIDC_ISSUER_URL` in `params.env`. + +**Injected into:** `controller-manager` Deployment, `manager` container. + +**Set by:** Open Data Hub operator (Feast component reconcile), from `GatewayConfig.spec.oidc.issuerURL` when cluster authentication is OIDC. + +**Consumption:** Operator code should read `os.Getenv("OIDC_ISSUER_URL")` (or equivalent) where JWKS / OIDC discovery is required for managed workloads. diff --git a/infra/feast-operator/go.mod b/infra/feast-operator/go.mod index 3e41f468d68..021e1a1b020 100644 --- a/infra/feast-operator/go.mod +++ b/infra/feast-operator/go.mod @@ -1,97 +1,103 @@ module github.com/feast-dev/feast/infra/feast-operator -go 1.22.9 +go 1.25.0 require ( - github.com/onsi/ginkgo/v2 v2.17.1 - github.com/onsi/gomega v1.32.0 + github.com/onsi/ginkgo/v2 v2.22.2 + github.com/onsi/gomega v1.36.2 github.com/openshift/api v0.0.0-20240912201240-0a8800162826 // release-4.17 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.30.1 - k8s.io/apimachinery v0.30.1 - k8s.io/client-go v0.30.1 - sigs.k8s.io/controller-runtime v0.18.4 + k8s.io/api v0.33.1 + k8s.io/apimachinery v0.33.1 + k8s.io/client-go v0.33.1 + sigs.k8s.io/controller-runtime v0.21.0 ) require ( - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/prometheus-operator/prometheus-operator/pkg/client v0.83.0 + github.com/prometheus/client_golang v1.22.0 + github.com/prometheus/client_model v0.6.1 + k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 +) + +require ( + cel.dev/expr v0.25.1 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/fxamacker/cbor/v2 v2.8.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.17.8 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.23.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.83.0 // indirect + github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/sdk v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/proto/otlp v1.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/net v0.55.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/term v0.43.0 // indirect + golang.org/x/text v0.37.0 // indirect + golang.org/x/time v0.11.0 // indirect + golang.org/x/tools v0.44.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.30.1 // indirect - k8s.io/apiserver v0.30.1 // indirect - k8s.io/component-base v0.30.1 // indirect - k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/apiextensions-apiserver v0.33.1 // indirect + k8s.io/apiserver v0.33.1 // indirect + k8s.io/component-base v0.33.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/infra/feast-operator/go.sum b/infra/feast-operator/go.sum index ef5d6204916..6c80ee96e61 100644 --- a/infra/feast-operator/go.sum +++ b/infra/feast-operator/go.sum @@ -1,90 +1,87 @@ -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= +github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= -github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= +github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -92,162 +89,171 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/openshift/api v0.0.0-20240912201240-0a8800162826 h1:A8D9SN/hJUwAbdO0rPCVTqmuBOctdgurr53gK701SYo= github.com/openshift/api v0.0.0-20240912201240-0a8800162826/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.83.0 h1:j9Ce3W6X6Tzi0QnSap+YzGwpqJLJGP/7xV6P9f86jjM= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.83.0/go.mod h1:sSxwdmprUfmRfTknPc4KIjUd2ZIc/kirw4UdXNhOauM= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.83.0 h1:odshP0+Jo6iUNGpK8MOFA6p5Yj0QOV4yLgiqFU5MVuI= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.83.0/go.mod h1:6Ndhfow0psSp7dV1qp9zK5h++CDKz4eSFWPbrHd5Iic= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= +go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= -google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= -google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= -k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= -k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= -k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= -k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= -k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/apiserver v0.30.1 h1:BEWEe8bzS12nMtDKXzCF5Q5ovp6LjjYkSp8qOPk8LZ8= -k8s.io/apiserver v0.30.1/go.mod h1:i87ZnQ+/PGAmSbD/iEKM68bm1D5reX8fO4Ito4B01mo= -k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= -k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= -k8s.io/component-base v0.30.1 h1:bvAtlPh1UrdaZL20D9+sWxsJljMi0QZ3Lmw+kmZAaxQ= -k8s.io/component-base v0.30.1/go.mod h1:e/X9kDiOebwlI41AvBHuWdqFriSRrX50CdwA9TFaHLI= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= -sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= -sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +k8s.io/api v0.33.1 h1:tA6Cf3bHnLIrUK4IqEgb2v++/GYUtqiu9sRVk3iBXyw= +k8s.io/api v0.33.1/go.mod h1:87esjTn9DRSRTD4fWMXamiXxJhpOIREjWOSjsW1kEHw= +k8s.io/apiextensions-apiserver v0.33.1 h1:N7ccbSlRN6I2QBcXevB73PixX2dQNIW0ZRuguEE91zI= +k8s.io/apiextensions-apiserver v0.33.1/go.mod h1:uNQ52z1A1Gu75QSa+pFK5bcXc4hq7lpOXbweZgi4dqA= +k8s.io/apimachinery v0.33.1 h1:mzqXWV8tW9Rw4VeW9rEkqvnxj59k1ezDUl20tFK/oM4= +k8s.io/apimachinery v0.33.1/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.1 h1:yLgLUPDVC6tHbNcw5uE9mo1T6ELhJj7B0geifra3Qdo= +k8s.io/apiserver v0.33.1/go.mod h1:VMbE4ArWYLO01omz+k8hFjAdYfc3GVAYPrhP2tTKccs= +k8s.io/client-go v0.33.1 h1:ZZV/Ks2g92cyxWkRRnfUDsnhNn28eFpt26aGc8KbXF4= +k8s.io/client-go v0.33.1/go.mod h1:JAsUrl1ArO7uRVFWfcj6kOomSlCv+JpvIsp6usAGefA= +k8s.io/component-base v0.33.1 h1:EoJ0xA+wr77T+G8p6T3l4efT2oNwbqBVKR71E0tBIaI= +k8s.io/component-base v0.33.1/go.mod h1:guT/w/6piyPfTgq7gfvgetyXMIh10zuXA6cRRm3rDuY= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg= +k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= +sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/infra/feast-operator/internal/controller/authz/authz.go b/infra/feast-operator/internal/controller/authz/authz.go index 9cb5b7c9554..9ab8d10c55c 100644 --- a/infra/feast-operator/internal/controller/authz/authz.go +++ b/infra/feast-operator/internal/controller/authz/authz.go @@ -15,16 +15,41 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) +const ( + authenticationAPIGroup = "authentication.k8s.io" + verbCreate = "create" +) + // Deploy the feast authorization func (authz *FeastAuthorization) Deploy() error { if authz.isKubernetesAuth() { + authz.cleanupOidcRbac() return authz.deployKubernetesAuth() } + // Clean up namespace-scoped Kubernetes auth resources authz.removeOrphanedRoles() _ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRole()) _ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRoleBinding()) apimeta.RemoveStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastKubernetesAuthConditions[metav1.ConditionTrue].Type) + + // Clean up cluster-scoped Kubernetes auth CRB (handles Kubernetes→OIDC or Kubernetes→no-auth transitions) + authz.cleanupKubernetesClusterRbac() + + if authz.isOidcAuth() { + if err := authz.createOidcClusterRole(); err != nil { + return authz.setFeastOidcAuthCondition(err) + } + if err := authz.createOidcClusterRoleBinding(); err != nil { + return authz.setFeastOidcAuthCondition(err) + } + return authz.setFeastOidcAuthCondition(nil) + } + + // No auth - clean up OIDC RBAC and remove condition + authz.cleanupOidcRbac() + apimeta.RemoveStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastOidcAuthConditions[metav1.ConditionTrue].Type) + return nil } @@ -33,6 +58,11 @@ func (authz *FeastAuthorization) isKubernetesAuth() bool { return authzConfig != nil && authzConfig.KubernetesAuthz != nil } +func (authz *FeastAuthorization) isOidcAuth() bool { + authzConfig := authz.Handler.FeatureStore.Status.Applied.AuthzConfig + return authzConfig != nil && authzConfig.OidcAuthz != nil +} + func (authz *FeastAuthorization) deployKubernetesAuth() error { if authz.isKubernetesAuth() { authz.removeOrphanedRoles() @@ -127,32 +157,32 @@ func (authz *FeastAuthorization) setFeastClusterRole(clusterRole *rbacv1.Cluster { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"rolebindings"}, - Verbs: []string{"list"}, + Verbs: []string{verbList}, }, { - APIGroups: []string{"authentication.k8s.io"}, - Resources: []string{"tokenreviews"}, - Verbs: []string{"create"}, + APIGroups: []string{authenticationAPIGroup}, + Resources: []string{resourceTokenReviews}, + Verbs: []string{verbCreate}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"subjectaccessreviews"}, - Verbs: []string{"create"}, + Verbs: []string{verbCreate}, }, { APIGroups: []string{""}, Resources: []string{"namespaces"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{verbGet, verbList, verbWatch}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"clusterroles"}, - Verbs: []string{"get", "list"}, + Verbs: []string{verbGet, verbList}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"clusterrolebindings"}, - Verbs: []string{"get", "list"}, + Verbs: []string{verbGet, verbList}, }, } // Don't set controller reference for shared ClusterRole @@ -213,32 +243,32 @@ func (authz *FeastAuthorization) setFeastRole(role *rbacv1.Role) error { { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"roles", "rolebindings"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{verbGet, verbList, verbWatch}, }, { - APIGroups: []string{"authentication.k8s.io"}, - Resources: []string{"tokenreviews"}, - Verbs: []string{"create"}, + APIGroups: []string{authenticationAPIGroup}, + Resources: []string{resourceTokenReviews}, + Verbs: []string{verbCreate}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"subjectaccessreviews"}, - Verbs: []string{"create"}, + Verbs: []string{verbCreate}, }, { APIGroups: []string{""}, Resources: []string{"namespaces"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{verbGet, verbList, verbWatch}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"clusterroles"}, - Verbs: []string{"get", "list"}, + Verbs: []string{verbGet, verbList}, }, { APIGroups: []string{rbacv1.GroupName}, Resources: []string{"clusterrolebindings"}, - Verbs: []string{"get", "list"}, + Verbs: []string{verbGet, verbList}, }, } @@ -312,24 +342,120 @@ func (authz *FeastAuthorization) setAuthRole(role *rbacv1.Role) error { return controllerutil.SetControllerReference(authz.Handler.FeatureStore, role, authz.Handler.Scheme) } +func (authz *FeastAuthorization) createOidcClusterRole() error { + logger := log.FromContext(authz.Handler.Context) + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{Name: authz.getOidcClusterRoleName()}, + } + clusterRole.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("ClusterRole")) + if op, err := controllerutil.CreateOrUpdate(authz.Handler.Context, authz.Handler.Client, clusterRole, controllerutil.MutateFn(func() error { + clusterRole.Labels = authz.getSharedOidcClusterRoleLabels() + clusterRole.Rules = []rbacv1.PolicyRule{ + { + APIGroups: []string{authenticationAPIGroup}, + Resources: []string{resourceTokenReviews}, + Verbs: []string{verbCreate}, + }, + } + return nil + })); err != nil { + return err + } else if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated { + logger.Info("Successfully reconciled", "ClusterRole", clusterRole.Name, "operation", op) + } + return nil +} + +func (authz *FeastAuthorization) createOidcClusterRoleBinding() error { + logger := log.FromContext(authz.Handler.Context) + crb := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: authz.getOidcClusterRoleBindingName()}, + } + crb.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("ClusterRoleBinding")) + if op, err := controllerutil.CreateOrUpdate(authz.Handler.Context, authz.Handler.Client, crb, controllerutil.MutateFn(func() error { + crb.Labels = authz.getLabels() + crb.Subjects = []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: authz.getFeastServiceAccountName(), + Namespace: authz.Handler.FeatureStore.Namespace, + }, + } + crb.RoleRef = rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: authz.getOidcClusterRoleName(), + } + return nil + })); err != nil { + return err + } else if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated { + logger.Info("Successfully reconciled", "ClusterRoleBinding", crb.Name, "operation", op) + } + return nil +} + +func (authz *FeastAuthorization) cleanupOidcRbac() { + crb := &rbacv1.ClusterRoleBinding{ObjectMeta: metav1.ObjectMeta{Name: authz.getOidcClusterRoleBindingName()}} + crb.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("ClusterRoleBinding")) + _ = authz.Handler.Client.Delete(authz.Handler.Context, crb) +} + +func (authz *FeastAuthorization) cleanupKubernetesClusterRbac() { + crb := &rbacv1.ClusterRoleBinding{ObjectMeta: metav1.ObjectMeta{Name: authz.getFeastClusterRoleBindingName()}} + crb.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("ClusterRoleBinding")) + if err := authz.Handler.Client.Get(authz.Handler.Context, client.ObjectKeyFromObject(crb), crb); err != nil { + return + } + _ = authz.Handler.Client.Delete(authz.Handler.Context, crb) +} + +func (authz *FeastAuthorization) getOidcClusterRoleName() string { + return "feast-oidc-token-review" +} + +func (authz *FeastAuthorization) getOidcClusterRoleBindingName() string { + return services.GetFeastName(authz.Handler.FeatureStore) + "-oidc-token-review" +} + func (authz *FeastAuthorization) getLabels() map[string]string { return map[string]string{ services.NameLabelKey: authz.Handler.FeatureStore.Name, services.ServiceTypeLabelKey: string(services.AuthzFeastType), + services.ManagedByLabelKey: services.ManagedByLabelValue, + } +} + +func (authz *FeastAuthorization) getSharedOidcClusterRoleLabels() map[string]string { + return map[string]string{ + services.ServiceTypeLabelKey: string(services.AuthzFeastType), + services.ManagedByLabelKey: services.ManagedByLabelValue, } } +func (authz *FeastAuthorization) setFeastOidcAuthCondition(err error) error { + if err != nil { + logger := log.FromContext(authz.Handler.Context) + cond := feastOidcAuthConditions[metav1.ConditionFalse] + cond.Message = services.ErrorMessagePrefix + err.Error() + apimeta.SetStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, cond) + logger.Error(err, "Error deploying the OIDC authorization") + return err + } + apimeta.SetStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastOidcAuthConditions[metav1.ConditionTrue]) + return nil +} + func (authz *FeastAuthorization) setFeastKubernetesAuthCondition(err error) error { if err != nil { logger := log.FromContext(authz.Handler.Context) cond := feastKubernetesAuthConditions[metav1.ConditionFalse] - cond.Message = "Error: " + err.Error() + cond.Message = services.ErrorMessagePrefix + err.Error() apimeta.SetStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, cond) logger.Error(err, "Error deploying the Kubernetes authorization") return err - } else { - apimeta.SetStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastKubernetesAuthConditions[metav1.ConditionTrue]) } + apimeta.SetStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastKubernetesAuthConditions[metav1.ConditionTrue]) return nil } diff --git a/infra/feast-operator/internal/controller/authz/authz_types.go b/infra/feast-operator/internal/controller/authz/authz_types.go index aea5e5f7a65..388ab179e7e 100644 --- a/infra/feast-operator/internal/controller/authz/authz_types.go +++ b/infra/feast-operator/internal/controller/authz/authz_types.go @@ -11,6 +11,16 @@ type FeastAuthorization struct { Handler handler.FeastHandler } +const ( + // RBAC verbs + verbGet = "get" + verbList = "list" + verbWatch = "watch" + + // RBAC resources + resourceTokenReviews = "tokenreviews" +) + var ( feastKubernetesAuthConditions = map[metav1.ConditionStatus]metav1.Condition{ metav1.ConditionTrue: { @@ -25,4 +35,17 @@ var ( Reason: feastdevv1.KubernetesAuthzFailedReason, }, } + feastOidcAuthConditions = map[metav1.ConditionStatus]metav1.Condition{ + metav1.ConditionTrue: { + Type: feastdevv1.AuthorizationReadyType, + Status: metav1.ConditionTrue, + Reason: feastdevv1.ReadyReason, + Message: feastdevv1.OidcAuthzReadyMessage, + }, + metav1.ConditionFalse: { + Type: feastdevv1.AuthorizationReadyType, + Status: metav1.ConditionFalse, + Reason: feastdevv1.OidcAuthzFailedReason, + }, + } ) diff --git a/infra/feast-operator/internal/controller/featurestore_controller.go b/infra/feast-operator/internal/controller/featurestore_controller.go index 6f67852a601..ae877447ddb 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller.go +++ b/infra/feast-operator/internal/controller/featurestore_controller.go @@ -30,7 +30,9 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -41,6 +43,7 @@ import ( feastdevv1 "github.com/feast-dev/feast/infra/feast-operator/api/v1" "github.com/feast-dev/feast/infra/feast-operator/internal/controller/authz" feasthandler "github.com/feast-dev/feast/infra/feast-operator/internal/controller/handler" + feastmetrics "github.com/feast-dev/feast/infra/feast-operator/internal/controller/metrics" "github.com/feast-dev/feast/infra/feast-operator/internal/controller/services" routev1 "github.com/openshift/api/route/v1" ) @@ -53,7 +56,8 @@ const ( // FeatureStoreReconciler reconciles a FeatureStore object type FeatureStoreReconciler struct { client.Client - Scheme *runtime.Scheme + Scheme *runtime.Scheme + Metrics *feastmetrics.FeatureStoreMetrics } // +kubebuilder:rbac:groups=feast.dev,resources=featurestores,verbs=get;list;watch;create;update;patch;delete @@ -69,6 +73,7 @@ type FeatureStoreReconciler struct { // +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=policy,resources=poddisruptionbudgets,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;list;watch;create;patch;delete // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -84,6 +89,9 @@ func (r *FeatureStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request if apierrors.IsNotFound(err) { // CR deleted since request queued, child objects getting GC'd, no requeue logger.V(1).Info("FeatureStore CR not found, has been deleted") + if r.Metrics != nil { + r.Metrics.DeleteFeatureStore(req.NamespacedName.Namespace, req.NamespacedName.Name) + } // Clean up namespace registry entry even if the CR is not found if err := r.cleanupNamespaceRegistry(ctx, &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{ @@ -104,6 +112,9 @@ func (r *FeatureStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request // Handle deletion - clean up namespace registry entry if cr.DeletionTimestamp != nil { logger.Info("FeatureStore is being deleted, cleaning up namespace registry entry") + if r.Metrics != nil { + r.Metrics.DeleteFeatureStore(cr.Namespace, cr.Name) + } if err := r.cleanupNamespaceRegistry(ctx, cr); err != nil { logger.Error(err, "Failed to clean up namespace registry entry") return ctrl.Result{}, err @@ -112,6 +123,9 @@ func (r *FeatureStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request } result, recErr = r.deployFeast(ctx, cr) + if recErr == nil && r.Metrics != nil { + r.Metrics.RecordFeatureStore(cr) + } if cr.DeletionTimestamp == nil && !reflect.DeepEqual(currentStatus, cr.Status) { if err = r.Client.Status().Update(ctx, cr); err != nil { if apierrors.IsConflict(err) { @@ -196,11 +210,15 @@ func (r *FeatureStoreReconciler) deployFeast(ctx context.Context, cr *feastdevv1 } else { isDeployAvailable := services.IsDeploymentAvailable(deployment.Status.Conditions) if !isDeployAvailable { + msg := feastdevv1.DeploymentNotAvailableMessage + if podMsg := feast.GetPodContainerFailureMessage(deployment); podMsg != "" { + msg = msg + ": " + podMsg + } condition = metav1.Condition{ Type: feastdevv1.ReadyType, Status: metav1.ConditionUnknown, Reason: feastdevv1.DeploymentNotAvailableReason, - Message: feastdevv1.DeploymentNotAvailableMessage, + Message: msg, } result = errResult @@ -240,6 +258,15 @@ func (r *FeatureStoreReconciler) SetupWithManager(mgr ctrl.Manager) error { if services.IsOpenShift() { bldr = bldr.Owns(&routev1.Route{}) } + if services.HasServiceMonitorCRD() { + sm := &unstructured.Unstructured{} + sm.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "monitoring.coreos.com", + Version: "v1", + Kind: "ServiceMonitor", + }) + bldr = bldr.Owns(sm) + } return bldr.Complete(r) diff --git a/infra/feast-operator/internal/controller/featurestore_controller_cronjob_test.go b/infra/feast-operator/internal/controller/featurestore_controller_cronjob_test.go index c329d70f06d..11ae2af7777 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_cronjob_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_cronjob_test.go @@ -98,6 +98,8 @@ var _ = Describe("FeatureStore Controller - Feast CronJob", func() { Expect(resource.Status).NotTo(BeNil()) Expect(resource.Status.CronJob).To(Equal(objMeta.Name)) Expect(resource.Status.Applied.CronJob.Schedule).NotTo(BeEmpty()) + Expect(resource.Status.Applied.Services.RunFeastApplyOnInit).NotTo(BeNil()) + Expect(*resource.Status.Applied.Services.RunFeastApplyOnInit).To(BeTrue()) Expect(resource.Status.Conditions).NotTo(BeEmpty()) cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1.CronJobReadyType) diff --git a/infra/feast-operator/internal/controller/featurestore_controller_db_store_test.go b/infra/feast-operator/internal/controller/featurestore_controller_db_store_test.go index d17bffb2377..08276293032 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_db_store_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_db_store_test.go @@ -132,22 +132,22 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { typeNamespacedName := types.NamespacedName{ Name: resourceName, - Namespace: "default", + Namespace: services.DefaultNs, } offlineSecretNamespacedName := types.NamespacedName{ - Name: "offline-store-secret", - Namespace: "default", + Name: services.OfflineStoreSecretName, + Namespace: services.DefaultNs, } onlineSecretNamespacedName := types.NamespacedName{ - Name: "online-store-secret", - Namespace: "default", + Name: services.OnlineStoreSecretName, + Namespace: services.DefaultNs, } registrySecretNamespacedName := types.NamespacedName{ - Name: "registry-store-secret", - Namespace: "default", + Name: services.RegistryStoreSecretName, + Namespace: services.DefaultNs, } featurestore := &feastdevv1.FeatureStore{} @@ -212,7 +212,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { DBPersistence: &feastdevv1.OfflineStoreDBStorePersistence{ Type: string(offlineType), SecretRef: corev1.LocalObjectReference{ - Name: "offline-store-secret", + Name: services.OfflineStoreSecretName, }, }, } @@ -220,7 +220,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{ Type: string(onlineType), SecretRef: corev1.LocalObjectReference{ - Name: "online-store-secret", + Name: services.OnlineStoreSecretName, }, }, } @@ -228,7 +228,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { DBPersistence: &feastdevv1.RegistryDBStorePersistence{ Type: string(registryType), SecretRef: corev1.LocalObjectReference{ - Name: "registry-store-secret", + Name: services.RegistryStoreSecretName, }, SecretKeyName: "sql_custom_registry_key", }, @@ -291,7 +291,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { err = k8sClient.Get(ctx, typeNamespacedName, resource) Expect(err).NotTo(HaveOccurred()) - resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: "online-store-secret"} + resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: services.OnlineStoreSecretName} // pragma: allowlist secret resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretKeyName = "invalid.secret.key" Expect(k8sClient.Update(ctx, resource)).To(Succeed()) resource = &feastdevv1.FeatureStore{} @@ -316,7 +316,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { secret.Data[string(services.OnlineDBPersistenceCassandraConfigType)] = []byte(invalidSecretTypeYamlString) Expect(k8sClient.Update(ctx, secret)).To(Succeed()) - resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: "online-store-secret"} + resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: services.OnlineStoreSecretName} // pragma: allowlist secret resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretKeyName = "" Expect(k8sClient.Update(ctx, resource)).To(Succeed()) resource = &feastdevv1.FeatureStore{} @@ -364,7 +364,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { Expect(resource.Status.Applied.Services.OfflineStore.Persistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.OfflineStore.Persistence.DBPersistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.OfflineStore.Persistence.DBPersistence.Type).To(Equal(string(offlineType))) - Expect(resource.Status.Applied.Services.OfflineStore.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: "offline-store-secret"})) + Expect(resource.Status.Applied.Services.OfflineStore.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: services.OfflineStoreSecretName})) Expect(resource.Status.Applied.Services.OfflineStore.Server.ImagePullPolicy).To(BeNil()) Expect(resource.Status.Applied.Services.OfflineStore.Server.Resources).To(BeNil()) Expect(resource.Status.Applied.Services.OfflineStore.Server.Image).To(Equal(&services.DefaultImage)) @@ -372,7 +372,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { Expect(resource.Status.Applied.Services.OnlineStore.Persistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.OnlineStore.Persistence.DBPersistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.OnlineStore.Persistence.DBPersistence.Type).To(Equal(string(onlineType))) - Expect(resource.Status.Applied.Services.OnlineStore.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: "online-store-secret"})) + Expect(resource.Status.Applied.Services.OnlineStore.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: services.OnlineStoreSecretName})) Expect(resource.Status.Applied.Services.OnlineStore.Server.ImagePullPolicy).To(Equal(&pullPolicy)) Expect(resource.Status.Applied.Services.OnlineStore.Server.Resources).NotTo(BeNil()) Expect(resource.Status.Applied.Services.OnlineStore.Server.Image).To(Equal(&image)) @@ -381,7 +381,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { Expect(resource.Status.Applied.Services.Registry.Local.Persistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.Registry.Local.Persistence.DBPersistence).NotTo(BeNil()) Expect(resource.Status.Applied.Services.Registry.Local.Persistence.DBPersistence.Type).To(Equal(string(registryType))) - Expect(resource.Status.Applied.Services.Registry.Local.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: "registry-store-secret"})) + Expect(resource.Status.Applied.Services.Registry.Local.Persistence.DBPersistence.SecretRef).To(Equal(corev1.LocalObjectReference{Name: services.RegistryStoreSecretName})) Expect(resource.Status.Applied.Services.Registry.Local.Persistence.DBPersistence.SecretKeyName).To(Equal("sql_custom_registry_key")) Expect(resource.Status.Applied.Services.Registry.Local.Server.ImagePullPolicy).To(BeNil()) Expect(resource.Status.Applied.Services.Registry.Local.Server.Resources).To(BeNil()) @@ -461,7 +461,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { secret.Data[string(services.OnlineDBPersistenceCassandraConfigType)] = []byte(secretContainingValidTypeYamlString) Expect(k8sClient.Update(ctx, secret)).To(Succeed()) - resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: "online-store-secret"} + resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: services.OnlineStoreSecretName} // pragma: allowlist secret resource.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretKeyName = "" Expect(k8sClient.Update(ctx, resource)).To(Succeed()) resource = &feastdevv1.FeatureStore{} @@ -492,7 +492,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { secret.Data[string(services.RegistryDBPersistenceSQLConfigType)] = []byte(invalidSecretRegistryTypeYamlString) Expect(k8sClient.Update(ctx, secret)).To(Succeed()) - resource.Spec.Services.Registry.Local.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: "registry-store-secret"} + resource.Spec.Services.Registry.Local.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: services.RegistryStoreSecretName} // pragma: allowlist secret resource.Spec.Services.Registry.Local.Persistence.DBPersistence.SecretKeyName = "" Expect(k8sClient.Update(ctx, resource)).To(Succeed()) resource = &feastdevv1.FeatureStore{} @@ -676,7 +676,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() { // change paths and reconcile resourceNew := resource.DeepCopy() - newOnlineSecretName := "offline-store-secret" + newOnlineSecretName := services.OfflineStoreSecretName // pragma: allowlist secret newOnlineDBPersistenceType := services.OnlineDBPersistenceSnowflakeConfigType resourceNew.Spec.Services.OnlineStore.Persistence.DBPersistence.Type = string(newOnlineDBPersistenceType) resourceNew.Spec.Services.OnlineStore.Persistence.DBPersistence.SecretRef = corev1.LocalObjectReference{Name: newOnlineSecretName} diff --git a/infra/feast-operator/internal/controller/featurestore_controller_objectstore_test.go b/infra/feast-operator/internal/controller/featurestore_controller_objectstore_test.go index 37d22094147..a326752a78f 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_objectstore_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_objectstore_test.go @@ -185,7 +185,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() { Expect(err).NotTo(HaveOccurred()) Expect(deploy.Spec.Replicas).To(Equal(int32Ptr(1))) Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue()) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(2)) Expect(services.GetRegistryContainer(*deploy)).NotTo(BeNil()) Expect(services.GetOnlineContainer(*deploy)).NotTo(BeNil()) diff --git a/infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go b/infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go index bb5cc4fb4b2..e15f8ecfa8a 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go @@ -77,7 +77,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() { if err != nil && errors.IsNotFound(err) { resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{}, withEnvFrom()) resource.Spec.AuthzConfig = &feastdevv1.AuthzConfig{OidcAuthz: &feastdevv1.OidcAuthz{ - SecretRef: corev1.LocalObjectReference{ + SecretRef: &corev1.LocalObjectReference{ Name: oidcSecretName, }, }} @@ -134,7 +134,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() { Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject)) expectedAuthzConfig := &feastdevv1.AuthzConfig{ OidcAuthz: &feastdevv1.OidcAuthz{ - SecretRef: corev1.LocalObjectReference{ + SecretRef: &corev1.LocalObjectReference{ Name: oidcSecretName, }, }, @@ -179,7 +179,10 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() { Expect(cond.Message).To(Equal(feastdevv1.DeploymentNotAvailableMessage)) cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1.AuthorizationReadyType) - Expect(cond).To(BeNil()) + Expect(cond).ToNot(BeNil()) + Expect(cond.Status).To(Equal(metav1.ConditionTrue)) + Expect(cond.Reason).To(Equal(feastdevv1.ReadyReason)) + Expect(cond.Message).To(Equal(feastdevv1.OidcAuthzReadyMessage)) cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1.RegistryReadyType) Expect(cond).ToNot(BeNil()) @@ -221,7 +224,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() { Expect(err).NotTo(HaveOccurred()) Expect(deploy.Spec.Replicas).To(Equal(int32Ptr(1))) Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue()) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(4)) Expect(deploy.Spec.Template.Spec.Volumes).To(HaveLen(1)) Expect(services.GetOfflineContainer(*deploy).VolumeMounts).To(HaveLen(1)) @@ -476,7 +479,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() { Expect(cond.Status).To(Equal(metav1.ConditionFalse)) Expect(cond.Reason).To(Equal(feastdevv1.FailedReason)) Expect(cond.Type).To(Equal(feastdevv1.ReadyType)) - Expect(cond.Message).To(ContainSubstring("missing OIDC")) + Expect(cond.Message).To(ContainSubstring("OIDC discovery URL")) }) }) }) @@ -496,12 +499,6 @@ func expectedServerOidcAuthorizConfig() services.AuthzConfig { func expectedClientOidcAuthorizConfig() services.AuthzConfig { return services.AuthzConfig{ Type: services.OidcAuthType, - OidcParameters: map[string]interface{}{ - string(services.OidcClientId): "client-id", - string(services.OidcAuthDiscoveryUrl): "auth-discovery-url", - string(services.OidcClientSecret): "client-secret", - string(services.OidcUsername): "username", - string(services.OidcPassword): "password"}, } } @@ -529,7 +526,7 @@ func createValidOidcSecret(secretName string) *corev1.Secret { func createInvalidOidcSecret(secretName string) *corev1.Secret { oidcProperties := validOidcSecretMap() - delete(oidcProperties, string(services.OidcClientId)) + delete(oidcProperties, string(services.OidcAuthDiscoveryUrl)) secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, diff --git a/infra/feast-operator/internal/controller/featurestore_controller_test.go b/infra/feast-operator/internal/controller/featurestore_controller_test.go index a70cd476679..a9ac5235eda 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_test.go @@ -19,6 +19,7 @@ package controller import ( "context" "encoding/base64" + "encoding/json" "fmt" "reflect" "strings" @@ -210,8 +211,10 @@ var _ = Describe("FeatureStore Controller", func() { Expect(deploy.Spec.Replicas).To(Equal(int32Ptr(1))) Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue()) Expect(deploy.Spec.Template.Spec.ServiceAccountName).To(Equal(deploy.Name)) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(deploy.Spec.Template.Spec.InitContainers[0].Args[0]).To(ContainSubstring("feast init")) + Expect(deploy.Spec.Template.Spec.InitContainers[1].Name).To(Equal("feast-apply")) + Expect(deploy.Spec.Template.Spec.InitContainers[1].Command).To(Equal([]string{"feast", "apply"})) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1)) deploy.Spec.Replicas = int32Ptr(3) @@ -264,7 +267,7 @@ var _ = Describe("FeatureStore Controller", func() { }, deploy) Expect(err).NotTo(HaveOccurred()) Expect(deploy.Spec.Replicas).To(Equal(int32Ptr(1))) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(deploy.Spec.Template.Spec.InitContainers[0].Args[0]).To(ContainSubstring("git -c http.sslVerify=false clone")) Expect(deploy.Spec.Template.Spec.InitContainers[0].Args[0]).To(ContainSubstring("git checkout " + ref)) Expect(deploy.Spec.Template.Spec.InitContainers[0].Args[0]).To(ContainSubstring(featureRepoPath)) @@ -294,7 +297,7 @@ var _ = Describe("FeatureStore Controller", func() { Namespace: objMeta.Namespace, }, deploy) Expect(err).NotTo(HaveOccurred()) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(deploy.Spec.Template.Spec.InitContainers[0].Args[0]).To(ContainSubstring("feast init -t spark")) }) @@ -737,6 +740,12 @@ var _ = Describe("FeatureStore Controller", func() { }, deploy) Expect(err).NotTo(HaveOccurred()) Expect(deploy.Spec.Template.Spec.ServiceAccountName).To(Equal(deploy.Name)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) + Expect(deploy.Spec.Template.Spec.InitContainers[1].Name).To(Equal("feast-apply")) + Expect(deploy.Spec.Template.Spec.InitContainers[1].Env).To(ContainElements( + corev1.EnvVar{Name: testEnvVarName, Value: testEnvVarValue}, + )) + Expect(deploy.Spec.Template.Spec.InitContainers[1].EnvFrom).NotTo(BeEmpty()) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(4)) registryContainer := services.GetRegistryContainer(*deploy) Expect(registryContainer.Env).To(HaveLen(1)) @@ -1145,7 +1154,7 @@ var _ = Describe("FeatureStore Controller", func() { Namespace: objMeta.Namespace, }, deploy) Expect(err).NotTo(HaveOccurred()) - Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(deploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) // check client config cm := &corev1.ConfigMap{} @@ -1225,6 +1234,127 @@ var _ = Describe("FeatureStore Controller", func() { Expect(cond.Message).To(Equal("Error: Remote feast registry of referenced FeatureStore '" + referencedRegistry.Name + "' is not ready")) }) + It("should allow cross-project registry references with different feastProject names", func() { + By("Reconciling the primary local registry FeatureStore") + controllerReconciler := &FeatureStoreReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + } + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) + + primaryStore := &feastdevv1.FeatureStore{} + err = k8sClient.Get(ctx, typeNamespacedName, primaryStore) + Expect(err).NotTo(HaveOccurred()) + Expect(primaryStore.Status.Applied.FeastProject).To(Equal(feastProject)) + + By("Creating a second FeatureStore with a DIFFERENT feastProject name referencing the first") + crossProjectName := "cross-project-ref" + crossProjectFeastName := "different_project" + crossProjectResource := &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: crossProjectName, + Namespace: primaryStore.Namespace, + }, + Spec: feastdevv1.FeatureStoreSpec{ + FeastProject: crossProjectFeastName, + Services: &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Server: &feastdevv1.ServerConfigs{}, + }, + Registry: &feastdevv1.Registry{ + Remote: &feastdevv1.RemoteRegistryConfig{ + FeastRef: &feastdevv1.FeatureStoreRef{ + Name: primaryStore.Name, + }, + }, + }, + }, + }, + } + crossProjectResource.SetGroupVersionKind(feastdevv1.GroupVersion.WithKind("FeatureStore")) + crossProjectNsName := client.ObjectKeyFromObject(crossProjectResource) + err = k8sClient.Create(ctx, crossProjectResource) + Expect(err).NotTo(HaveOccurred()) + + By("Reconciling the cross-project FeatureStore — should succeed without error") + _, err = controllerReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: crossProjectNsName, + }) + Expect(err).NotTo(HaveOccurred()) + + err = k8sClient.Get(ctx, crossProjectNsName, crossProjectResource) + Expect(err).NotTo(HaveOccurred()) + + By("Verifying the cross-project FeatureStore is ready and uses its own project name") + Expect(crossProjectResource.Status.Applied.FeastProject).To(Equal(crossProjectFeastName)) + Expect(crossProjectResource.Status.ServiceHostnames.Registry).To(Equal(primaryStore.Status.ServiceHostnames.Registry)) + Expect(apimeta.IsStatusConditionTrue(crossProjectResource.Status.Conditions, feastdevv1.OnlineStoreReadyType)).To(BeTrue()) + + By("Verifying the cross-project client ConfigMap uses the correct project name and shared registry") + crossFeast := services.FeastServices{ + Handler: handler.FeastHandler{ + Client: controllerReconciler.Client, + Context: ctx, + Scheme: controllerReconciler.Scheme, + FeatureStore: crossProjectResource, + }, + } + crossCm := &corev1.ConfigMap{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: crossFeast.GetFeastServiceName(services.ClientFeastType), + Namespace: crossProjectResource.Namespace, + }, crossCm) + Expect(err).NotTo(HaveOccurred()) + crossRepoConfig := &services.RepoConfig{} + err = yaml.Unmarshal([]byte(crossCm.Data[services.FeatureStoreYamlCmKey]), crossRepoConfig) + Expect(err).NotTo(HaveOccurred()) + Expect(crossRepoConfig.Project).To(Equal(crossProjectFeastName)) + Expect(crossRepoConfig.Registry.Path).To(ContainSubstring(primaryStore.Name)) + + By("Verifying the primary store client ConfigMap still uses its own project name") + primaryFeast := services.FeastServices{ + Handler: handler.FeastHandler{ + Client: controllerReconciler.Client, + Context: ctx, + Scheme: controllerReconciler.Scheme, + FeatureStore: primaryStore, + }, + } + primaryCm := &corev1.ConfigMap{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: primaryFeast.GetFeastServiceName(services.ClientFeastType), + Namespace: primaryStore.Namespace, + }, primaryCm) + Expect(err).NotTo(HaveOccurred()) + primaryRepoConfig := &services.RepoConfig{} + err = yaml.Unmarshal([]byte(primaryCm.Data[services.FeatureStoreYamlCmKey]), primaryRepoConfig) + Expect(err).NotTo(HaveOccurred()) + Expect(primaryRepoConfig.Project).To(Equal(feastProject)) + + By("Verifying both stores share the same registry path") + Expect(crossRepoConfig.Registry.Path).To(Equal(primaryRepoConfig.Registry.Path)) + + By("Verifying the namespace registry ConfigMap lists both client configs") + registryCm := &corev1.ConfigMap{} + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: services.NamespaceRegistryConfigMapName, + Namespace: services.DefaultKubernetesNamespace, + }, registryCm) + Expect(err).NotTo(HaveOccurred()) + var registryData services.NamespaceRegistryData + err = json.Unmarshal([]byte(registryCm.Data[services.NamespaceRegistryDataKey]), ®istryData) + Expect(err).NotTo(HaveOccurred()) + ns := primaryStore.Namespace + Expect(registryData.Namespaces[ns]).To(ContainElement(primaryFeast.GetFeastServiceName(services.ClientFeastType))) + Expect(registryData.Namespaces[ns]).To(ContainElement(crossFeast.GetFeastServiceName(services.ClientFeastType))) + + By("Cleaning up the cross-project FeatureStore") + Expect(k8sClient.Delete(ctx, crossProjectResource)).To(Succeed()) + }) + It("should correctly set container command args for grpc/rest modes", func() { controllerReconciler := &FeatureStoreReconciler{ Client: k8sClient, @@ -1361,6 +1491,109 @@ var _ = Describe("FeatureStore Controller", func() { Expect(err.Error()).To(ContainSubstring("At least one of restAPI or grpc must be true")) }) + It("should generate correct feature_store.yaml when registry MCP is enabled", func() { + const mcpName = "mcp-registry" + mcpNsName := types.NamespacedName{ + Name: mcpName, + Namespace: "default", + } + + resource := &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: mcpName, + Namespace: "default", + }, + Spec: feastdevv1.FeatureStoreSpec{ + FeastProject: feastProject, + Services: &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + RestAPI: ptr(true), + Mcp: &feastdevv1.McpConfig{ + Enabled: true, + }, + }, + }, + }, + }, + }, + } + resource.SetGroupVersionKind(feastdevv1.GroupVersion.WithKind("FeatureStore")) + Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + + controllerReconciler := &FeatureStoreReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + } + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: mcpNsName}) + Expect(err).NotTo(HaveOccurred()) + + err = k8sClient.Get(ctx, mcpNsName, resource) + Expect(err).NotTo(HaveOccurred()) + + feast := services.FeastServices{ + Handler: handler.FeastHandler{ + Client: controllerReconciler.Client, + Context: ctx, + Scheme: controllerReconciler.Scheme, + FeatureStore: resource, + }, + } + + deploy := &appsv1.Deployment{} + objMeta := feast.GetObjectMeta() + err = k8sClient.Get(ctx, types.NamespacedName{ + Name: objMeta.Name, + Namespace: objMeta.Namespace, + }, deploy) + Expect(err).NotTo(HaveOccurred()) + + registryContainer := services.GetRegistryContainer(*deploy) + Expect(registryContainer).NotTo(BeNil()) + + env := getFeatureStoreYamlEnvVar(registryContainer.Env) + Expect(env).NotTo(BeNil()) + + envByte, err := base64.StdEncoding.DecodeString(env.Value) + Expect(err).NotTo(HaveOccurred()) + repoConfig := &services.RepoConfig{} + err = yaml.Unmarshal(envByte, repoConfig) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.Registry.Mcp).NotTo(BeNil()) + Expect(repoConfig.Registry.Mcp.Enabled).To(BeTrue()) + }) + + It("should reject registry MCP without restAPI enabled", func() { + mcpNoRestResource := &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mcp-no-rest", + Namespace: "default", + }, + Spec: feastdevv1.FeatureStoreSpec{ + FeastProject: feastProject, + Services: &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + RestAPI: ptr(false), + GRPC: ptr(true), + Mcp: &feastdevv1.McpConfig{ + Enabled: true, + }, + }, + }, + }, + }, + }, + } + mcpNoRestResource.SetGroupVersionKind(feastdevv1.GroupVersion.WithKind("FeatureStore")) + + err := k8sClient.Create(ctx, mcpNoRestResource) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("MCP requires restAPI to be true")) + }) + It("should error on reconcile", func() { By("Trying to set the controller OwnerRef of a Deployment that already has a controller") controllerReconciler := &FeatureStoreReconciler{ diff --git a/infra/feast-operator/internal/controller/featurestore_controller_tls_test.go b/infra/feast-operator/internal/controller/featurestore_controller_tls_test.go index 0af097120ce..bc60aed4374 100644 --- a/infra/feast-operator/internal/controller/featurestore_controller_tls_test.go +++ b/infra/feast-operator/internal/controller/featurestore_controller_tls_test.go @@ -193,6 +193,16 @@ var _ = Describe("FeatureStore Controller - Feast service TLS", func() { Expect(deploy.Spec.Replicas).To(Equal(int32Ptr(1))) Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue()) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(4)) + + // verify init containers have TLS volume mounts after reconciliation + Expect(deploy.Spec.Template.Spec.InitContainers).NotTo(BeEmpty()) + for _, initContainer := range deploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).To(ContainElement(SatisfyAll( + HaveField("MountPath", services.GetTlsPath(services.RegistryFeastType)), + HaveField("ReadOnly", true), + )), "init container %s should have registry TLS volume mount", initContainer.Name) + } + svc := &corev1.Service{} err = k8sClient.Get(ctx, types.NamespacedName{ Name: feast.GetFeastServiceName(services.RegistryFeastType), @@ -401,6 +411,14 @@ var _ = Describe("FeatureStore Controller - Feast service TLS", func() { Expect(err).NotTo(HaveOccurred()) Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(2)) + // verify init containers have remote registry TLS volume mounts + for _, initContainer := range deploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).To(ContainElement(SatisfyAll( + HaveField("MountPath", services.GetTlsPath(services.RegistryFeastType)), + HaveField("ReadOnly", true), + )), "init container %s should have remote registry TLS volume mount", initContainer.Name) + } + // check offline config offlineContainer = services.GetOfflineContainer(*deploy) env = getFeatureStoreYamlEnvVar(offlineContainer.Env) @@ -530,6 +548,12 @@ var _ = Describe("Test mountCustomCABundle functionality", func() { HaveField("MountPath", tlsPathCustomCABundle), ))) } + for _, initContainer := range deploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).To(ContainElement(SatisfyAll( + HaveField("Name", configMapName), + HaveField("MountPath", tlsPathCustomCABundle), + )), "init container %s should have CA bundle volume mount", initContainer.Name) + } }) It("should not mount CA bundle volume or container mounts when ConfigMap is absent", func() { @@ -570,5 +594,10 @@ var _ = Describe("Test mountCustomCABundle functionality", func() { for _, container := range deploy.Spec.Template.Spec.Containers { Expect(container.VolumeMounts).NotTo(ContainElement(HaveField("Name", configMapName))) } + for _, initContainer := range deploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).NotTo(ContainElement( + HaveField("Name", configMapName), + ), "init container %s should not have CA bundle mount when ConfigMap is absent", initContainer.Name) + } }) }) diff --git a/infra/feast-operator/internal/controller/metrics/metrics.go b/infra/feast-operator/internal/controller/metrics/metrics.go new file mode 100644 index 00000000000..c29342aab2a --- /dev/null +++ b/infra/feast-operator/internal/controller/metrics/metrics.go @@ -0,0 +1,137 @@ +/* +Copyright 2026 Feast Community. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package metrics provides a Prometheus info gauge that records the store +// types configured for each FeatureStore CR (online store, offline store, +// registry). These operator-level metrics are distinct from the Feast +// feature-server application metrics (feast_feature_server_*) and are useful +// for usage telemetry and assessing the impact of removing store type support. +package metrics + +import ( + feastdevv1 "github.com/feast-dev/feast/infra/feast-operator/api/v1" + "github.com/prometheus/client_golang/prometheus" + ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +const ( + typeNone = "none" + labelName = "name" + labelNamespace = "namespace" +) + +// FeatureStoreMetrics holds the Prometheus GaugeVec for feast-operator +// installation telemetry. +type FeatureStoreMetrics struct { + FeatureStoreInfo *prometheus.GaugeVec +} + +// NewFeatureStoreMetrics creates a new FeatureStoreMetrics with the GaugeVec +// initialised but not yet registered. Call Register() before starting the manager. +func NewFeatureStoreMetrics() *FeatureStoreMetrics { + return &FeatureStoreMetrics{ + FeatureStoreInfo: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "feast_operator_feature_store_info", + Help: "Information about a deployed FeatureStore. " + + "Value is always 1. Labels carry the configured store types: " + + "'online_store_type', 'offline_store_type', and 'registry_type' " + + "are set to the persistence type (e.g. redis, snowflake.offline, local) " + + "or 'none' when that component is not configured.", + }, + []string{labelNamespace, labelName, "online_store_type", "offline_store_type", "registry_type"}, + ), + } +} + +// Register registers the metric with the controller-runtime metrics registry +// so it is exposed on the manager's /metrics endpoint. +func (m *FeatureStoreMetrics) Register() { + ctrlmetrics.Registry.MustRegister(m.FeatureStoreInfo) +} + +// RecordFeatureStore updates the gauge for the given FeatureStore using the +// applied configuration stored in status.Applied (which has operator defaults +// applied). The previous label set for this FeatureStore is deleted first so +// that store type changes are reflected cleanly on the next scrape. +func (m *FeatureStoreMetrics) RecordFeatureStore(fs *feastdevv1.FeatureStore) { + svcs := fs.Status.Applied.Services + m.FeatureStoreInfo.DeletePartialMatch(prometheus.Labels{ + labelNamespace: fs.Namespace, + labelName: fs.Name, + }) + m.FeatureStoreInfo.WithLabelValues( + fs.Namespace, + fs.Name, + onlineStoreType(svcs), + offlineStoreType(svcs), + registryType(svcs), + ).Set(1) +} + +// DeleteFeatureStore removes the metric label set for the given FeatureStore. +// Safe to call when the CR has already been deleted from the API server. +func (m *FeatureStoreMetrics) DeleteFeatureStore(namespace, name string) { + m.FeatureStoreInfo.DeletePartialMatch(prometheus.Labels{ + "namespace": namespace, + "name": name, + }) +} + +// onlineStoreType returns the online store persistence type or "none". +func onlineStoreType(svcs *feastdevv1.FeatureStoreServices) string { + if svcs == nil || svcs.OnlineStore == nil { + return typeNone + } + if p := svcs.OnlineStore.Persistence; p != nil && p.DBPersistence != nil { + return p.DBPersistence.Type + } + return "file" +} + +// offlineStoreType returns the offline store persistence type or "none". +func offlineStoreType(svcs *feastdevv1.FeatureStoreServices) string { + if svcs == nil || svcs.OfflineStore == nil { + return typeNone + } + if p := svcs.OfflineStore.Persistence; p != nil { + if p.DBPersistence != nil { + return p.DBPersistence.Type + } + if p.FilePersistence != nil && p.FilePersistence.Type != "" { + return p.FilePersistence.Type + } + } + return "file" +} + +// registryType returns "local", "remote", "remote_feastref", or "none". +func registryType(svcs *feastdevv1.FeatureStoreServices) string { + if svcs == nil || svcs.Registry == nil { + return typeNone + } + switch { + case svcs.Registry.Local != nil: + return "local" + case svcs.Registry.Remote != nil: + if svcs.Registry.Remote.FeastRef != nil { + return "remote_feastref" + } + return "remote" + default: + return typeNone + } +} diff --git a/infra/feast-operator/internal/controller/metrics/metrics_test.go b/infra/feast-operator/internal/controller/metrics/metrics_test.go new file mode 100644 index 00000000000..480a861560d --- /dev/null +++ b/infra/feast-operator/internal/controller/metrics/metrics_test.go @@ -0,0 +1,275 @@ +/* +Copyright 2026 Feast Community. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics_test + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + feastdevv1 "github.com/feast-dev/feast/infra/feast-operator/api/v1" + . "github.com/feast-dev/feast/infra/feast-operator/internal/controller/metrics" +) + +const testNamespace = "test-ns" + +// gaugeValue reads the float64 value for the given label values. +// Returns -1 if the metric is not found. +func gaugeValue(gv *prometheus.GaugeVec, labels ...string) float64 { + g, err := gv.GetMetricWithLabelValues(labels...) + if err != nil { + return -1 + } + m := &dto.Metric{} + if err := g.Write(m); err != nil { + return -1 + } + return m.GetGauge().GetValue() +} + +func featureStore(name string, svcs *feastdevv1.FeatureStoreServices) *feastdevv1.FeatureStore { + fs := &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: name}, + } + fs.Status.Applied.Services = svcs + return fs +} + +func TestRecordFeatureStore_NoServices(t *testing.T) { + m := NewFeatureStoreMetrics() + m.RecordFeatureStore(featureStore("fs", nil)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "none", "none"); v != 1 { + t.Errorf("expected 1 for all-absent store, got %v", v) + } +} + +func TestRecordFeatureStore_OnlineStore_File(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{}, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "file", "none", "none"); v != 1 { + t.Errorf("expected 1 for file online store, got %v", v) + } +} + +func TestRecordFeatureStore_OnlineStore_Redis(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "redis"}, + }, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "redis", "none", "none"); v != 1 { + t.Errorf("expected 1 for redis online store, got %v", v) + } +} + +func TestRecordFeatureStore_OfflineStore_DB(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OfflineStore: &feastdevv1.OfflineStore{ + Persistence: &feastdevv1.OfflineStorePersistence{ + DBPersistence: &feastdevv1.OfflineStoreDBStorePersistence{Type: "snowflake.offline"}, + }, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "snowflake.offline", "none"); v != 1 { + t.Errorf("expected 1 for snowflake offline store, got %v", v) + } +} + +func TestRecordFeatureStore_OfflineStore_FilePersistenceType(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OfflineStore: &feastdevv1.OfflineStore{ + Persistence: &feastdevv1.OfflineStorePersistence{ + FilePersistence: &feastdevv1.OfflineStoreFilePersistence{Type: "duckdb"}, + }, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "duckdb", "none"); v != 1 { + t.Errorf("expected 1 for duckdb offline store, got %v", v) + } +} + +func TestRecordFeatureStore_Registry_Local(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{}, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "none", "local"); v != 1 { + t.Errorf("expected 1 for local registry, got %v", v) + } +} + +func TestRecordFeatureStore_Registry_RemoteHostname(t *testing.T) { + hostname := "registry.example.com:443" + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Remote: &feastdevv1.RemoteRegistryConfig{Hostname: &hostname}, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "none", "remote"); v != 1 { + t.Errorf("expected 1 for remote registry, got %v", v) + } +} + +func TestRecordFeatureStore_Registry_RemoteFeastRef(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Remote: &feastdevv1.RemoteRegistryConfig{ + FeastRef: &feastdevv1.FeatureStoreRef{Name: "other-fs", Namespace: "other-ns"}, + }, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "none", "none", "remote_feastref"); v != 1 { + t.Errorf("expected 1 for remote_feastref registry, got %v", v) + } +} + +func TestRecordFeatureStore_AllComponents(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "redis"}, + }, + }, + OfflineStore: &feastdevv1.OfflineStore{ + Persistence: &feastdevv1.OfflineStorePersistence{ + DBPersistence: &feastdevv1.OfflineStoreDBStorePersistence{Type: "snowflake.offline"}, + }, + }, + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{}, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "redis", "snowflake.offline", "local"); v != 1 { + t.Errorf("expected 1 for full store config, got %v", v) + } +} + +func TestRecordFeatureStore_TypeChange(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs1 := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "redis"}, + }, + }, + } + svcs2 := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "postgres"}, + }, + }, + } + + m.RecordFeatureStore(featureStore("fs", svcs1)) + m.RecordFeatureStore(featureStore("fs", svcs2)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "redis", "none", "none"); v != 0 { + t.Errorf("old label set (redis) should be removed after type change, got %v", v) + } + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "postgres", "none", "none"); v != 1 { + t.Errorf("new label set (postgres) should be 1 after type change, got %v", v) + } +} + +func TestDeleteFeatureStore_RemovesMetric(t *testing.T) { + m := NewFeatureStoreMetrics() + svcs := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "redis"}, + }, + }, + } + m.RecordFeatureStore(featureStore("fs", svcs)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "redis", "none", "none"); v != 1 { + t.Fatalf("setup: expected 1 before delete, got %v", v) + } + + m.DeleteFeatureStore(testNamespace, "fs") + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs", "redis", "none", "none"); v != 0 { + t.Errorf("expected 0 after DeleteFeatureStore, got %v", v) + } +} + +func TestMultipleFeatureStores_IndependentLabelSets(t *testing.T) { + m := NewFeatureStoreMetrics() + + svcs1 := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "redis"}, + }, + }, + } + svcs2 := &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Persistence: &feastdevv1.OnlineStorePersistence{ + DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{Type: "postgres"}, + }, + }, + } + + m.RecordFeatureStore(featureStore("fs-1", svcs1)) + m.RecordFeatureStore(featureStore("fs-2", svcs2)) + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs-1", "redis", "none", "none"); v != 1 { + t.Errorf("fs-1: expected redis=1, got %v", v) + } + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs-2", "postgres", "none", "none"); v != 1 { + t.Errorf("fs-2: expected postgres=1, got %v", v) + } + + m.DeleteFeatureStore(testNamespace, "fs-1") + + if v := gaugeValue(m.FeatureStoreInfo, testNamespace, "fs-2", "postgres", "none", "none"); v != 1 { + t.Errorf("fs-2 should be unaffected after fs-1 deletion, got %v", v) + } +} diff --git a/infra/feast-operator/internal/controller/services/client.go b/infra/feast-operator/internal/controller/services/client.go index fbd972368fb..4fcd9b894e7 100644 --- a/infra/feast-operator/internal/controller/services/client.go +++ b/infra/feast-operator/internal/controller/services/client.go @@ -47,7 +47,7 @@ func (feast *FeastServices) createClientConfigMap() error { func (feast *FeastServices) setClientConfigMap(cm *corev1.ConfigMap) error { cm.Labels = feast.getFeastTypeLabels(ClientFeastType) - clientYaml, err := feast.getClientFeatureStoreYaml(feast.extractConfigFromSecret) + clientYaml, err := feast.getClientFeatureStoreYaml() if err != nil { return err } @@ -74,7 +74,7 @@ func (feast *FeastServices) setCaConfigMap(cm *corev1.ConfigMap) error { if len(cm.Annotations) == 0 { cm.Annotations = map[string]string{} } - cm.Annotations["service.beta.openshift.io/inject-cabundle"] = "true" + cm.Annotations[openshiftInjectCaBundleAnnotation] = stringTrue return controllerutil.SetControllerReference(feast.Handler.FeatureStore, cm, feast.Handler.Scheme) } diff --git a/infra/feast-operator/internal/controller/services/namespace_registry.go b/infra/feast-operator/internal/controller/services/namespace_registry.go index 64cdaebd6f0..dcea98a5764 100644 --- a/infra/feast-operator/internal/controller/services/namespace_registry.go +++ b/infra/feast-operator/internal/controller/services/namespace_registry.go @@ -163,42 +163,38 @@ func (feast *FeastServices) createNamespaceRegistryRoleBinding(targetNamespace s // setNamespaceRegistryRoleBinding sets the RoleBinding for namespace registry access func (feast *FeastServices) setNamespaceRegistryRoleBinding(rb *rbacv1.RoleBinding) error { - // Create a Role that allows reading the ConfigMap + roleName := NamespaceRegistryConfigMapName + "-reader" + + desiredRules := []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Resources: []string{"configmaps"}, + ResourceNames: []string{NamespaceRegistryConfigMapName}, + Verbs: []string{"get", "list"}, + }, + } + role := &rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ - Name: NamespaceRegistryConfigMapName + "-reader", + Name: roleName, Namespace: rb.Namespace, }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"configmaps"}, - ResourceNames: []string{NamespaceRegistryConfigMapName}, - Verbs: []string{"get", "list"}, - }, - }, } + role.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("Role")) - // Create or update the Role - if _, err := controllerutil.CreateOrUpdate(feast.Handler.Context, feast.Handler.Client, role, controllerutil.MutateFn(func() error { - role.Rules = []rbacv1.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"configmaps"}, - ResourceNames: []string{NamespaceRegistryConfigMapName}, - Verbs: []string{"get", "list"}, - }, - } + if _, err := controllerutil.CreateOrUpdate(feast.Handler.Context, feast.Handler.Client, role, func() error { + role.Labels = feast.getLabels() + role.Rules = desiredRules return nil - })); err != nil { - return err + }); err != nil { + return fmt.Errorf("failed to reconcile namespace registry Role: %w", err) } - // Set the RoleBinding + rb.Labels = feast.getLabels() rb.RoleRef = rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "Role", - Name: role.Name, + Name: roleName, } rb.Subjects = []rbacv1.Subject{ diff --git a/infra/feast-operator/internal/controller/services/repo_config.go b/infra/feast-operator/internal/controller/services/repo_config.go index 9b20955f324..454dd5b234a 100644 --- a/infra/feast-operator/internal/controller/services/repo_config.go +++ b/infra/feast-operator/internal/controller/services/repo_config.go @@ -19,6 +19,7 @@ package services import ( "encoding/base64" "fmt" + "os" "path" "strings" @@ -26,6 +27,8 @@ import ( "gopkg.in/yaml.v3" ) +const oidcIssuerUrlEnvVar = "OIDC_ISSUER_URL" + // GetServiceFeatureStoreYamlBase64 returns a base64 encoded feature_store.yaml config for the feast service func (feast *FeastServices) GetServiceFeatureStoreYamlBase64() (string, error) { fsYaml, err := feast.getServiceFeatureStoreYaml() @@ -44,14 +47,16 @@ func (feast *FeastServices) getServiceFeatureStoreYaml() ([]byte, error) { } func (feast *FeastServices) getServiceRepoConfig() (RepoConfig, error) { - return getServiceRepoConfig(feast.Handler.FeatureStore, feast.extractConfigFromSecret, feast.extractConfigFromConfigMap) + odhCaBundleExists := feast.GetCustomCertificatesBundle().IsDefined + return getServiceRepoConfig(feast.Handler.FeatureStore, feast.extractConfigFromSecret, feast.extractConfigFromConfigMap, odhCaBundleExists) } func getServiceRepoConfig( featureStore *feastdevv1.FeatureStore, secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error), - configMapExtractionFunc func(configMapRef string, configMapKey string) (map[string]interface{}, error)) (RepoConfig, error) { - repoConfig, err := getBaseServiceRepoConfig(featureStore, secretExtractionFunc) + configMapExtractionFunc func(configMapRef string, configMapKey string) (map[string]interface{}, error), + odhCaBundleExists bool) (RepoConfig, error) { + repoConfig, err := getBaseServiceRepoConfig(featureStore, secretExtractionFunc, odhCaBundleExists) if err != nil { return repoConfig, err } @@ -86,44 +91,115 @@ func getServiceRepoConfig( } } + if appliedSpec.Services != nil && appliedSpec.Services.OnlineStore != nil && + appliedSpec.Services.OnlineStore.Serving != nil { + setRepoConfigFeatureServer(appliedSpec.Services.OnlineStore.Serving, &repoConfig) + } + + if appliedSpec.Materialization != nil { + setRepoConfigMaterialization(appliedSpec.Materialization, &repoConfig) + } + + if appliedSpec.OpenLineage != nil { + if err := setRepoConfigOpenLineage(appliedSpec.OpenLineage, secretExtractionFunc, &repoConfig); err != nil { + return repoConfig, err + } + } + + if appliedSpec.DataQualityMonitoring != nil { + setRepoConfigDataQualityMonitoring(appliedSpec.DataQualityMonitoring, &repoConfig) + } + return repoConfig, nil } func getBaseServiceRepoConfig( featureStore *feastdevv1.FeatureStore, - secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error)) (RepoConfig, error) { + secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error), + odhCaBundleExists bool) (RepoConfig, error) { repoConfig := defaultRepoConfig(featureStore) - clientRepoConfig, err := getClientRepoConfig(featureStore, secretExtractionFunc, nil) - if err != nil { - return repoConfig, err - } + clientRepoConfig := getClientRepoConfig(featureStore, nil) if isRemoteRegistry(featureStore) { repoConfig.Registry = clientRepoConfig.Registry } - repoConfig.AuthzConfig = clientRepoConfig.AuthzConfig - appliedSpec := featureStore.Status.Applied if appliedSpec.AuthzConfig != nil && appliedSpec.AuthzConfig.OidcAuthz != nil { - propertiesMap, authSecretErr := secretExtractionFunc("", appliedSpec.AuthzConfig.OidcAuthz.SecretRef.Name, "") - if authSecretErr != nil { - return repoConfig, authSecretErr - } - + repoConfig.AuthzConfig = AuthzConfig{Type: OidcAuthType} + oidcAuthz := appliedSpec.AuthzConfig.OidcAuthz oidcParameters := map[string]interface{}{} - for _, oidcProperty := range OidcProperties { - if val, exists := propertiesMap[string(oidcProperty)]; exists { - oidcParameters[string(oidcProperty)] = val - } else { - return repoConfig, missingOidcSecretProperty(oidcProperty) + + var secretProperties map[string]interface{} + if oidcAuthz.SecretRef != nil { + var err error + secretProperties, err = secretExtractionFunc("", oidcAuthz.SecretRef.Name, oidcAuthz.SecretKeyName) + if err != nil { + return repoConfig, err + } + for _, prop := range OidcOptionalSecretProperties { + if val, exists := secretProperties[string(prop)]; exists { + oidcParameters[string(prop)] = val + } } } + + discoveryUrl, err := resolveAuthDiscoveryUrl(oidcAuthz, secretProperties) + if err != nil { + return repoConfig, err + } + oidcParameters[string(OidcAuthDiscoveryUrl)] = discoveryUrl + + if oidcAuthz.VerifySSL != nil { + oidcParameters[string(OidcVerifySsl)] = *oidcAuthz.VerifySSL + } + if caCertPath := resolveOidcCACertPath(oidcAuthz, odhCaBundleExists); caCertPath != "" { + oidcParameters[string(OidcCaCertPath)] = caCertPath + } repoConfig.AuthzConfig.OidcParameters = oidcParameters + } else { + repoConfig.AuthzConfig = clientRepoConfig.AuthzConfig } return repoConfig, nil } +// resolveAuthDiscoveryUrl determines the OIDC discovery URL from the first available source. +// Priority: CR issuerUrl > Secret auth_discovery_url > OIDC_ISSUER_URL env var. +func resolveAuthDiscoveryUrl(oidcAuthz *feastdevv1.OidcAuthz, secretProperties map[string]interface{}) (string, error) { + if oidcAuthz.IssuerUrl != "" { + return issuerToDiscoveryUrl(oidcAuthz.IssuerUrl), nil + } + + if val, ok := secretProperties[string(OidcAuthDiscoveryUrl)]; ok { + if s, ok := val.(string); ok && s != "" { + return s, nil + } + } + + if envIssuer := os.Getenv(oidcIssuerUrlEnvVar); envIssuer != "" { + return issuerToDiscoveryUrl(envIssuer), nil + } + + return "", fmt.Errorf("no OIDC discovery URL configured: set issuerUrl on the OidcAuthz CR, "+ + "include auth_discovery_url in the referenced Secret, or ensure the %s environment variable is set on the operator pod", oidcIssuerUrlEnvVar) +} + +func issuerToDiscoveryUrl(issuerUrl string) string { + return strings.TrimRight(issuerUrl, "/") + "/.well-known/openid-configuration" +} + +// resolveOidcCACertPath determines the CA cert file path for OIDC provider TLS verification. +// Priority: explicit CRD caCertConfigMap > ODH auto-detected bundle > empty (system CA fallback). +func resolveOidcCACertPath(oidcAuthz *feastdevv1.OidcAuthz, odhCaBundleExists bool) string { + if oidcAuthz.CACertConfigMap != nil { + return tlsPathOidcCA + } + if odhCaBundleExists { + return tlsPathOdhCABundle + } + return "" +} + func setRepoConfigRegistry(services *feastdevv1.FeatureStoreServices, secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error), repoConfig *RepoConfig) error { registryPersistence := services.Registry.Local.Persistence @@ -187,6 +263,15 @@ func setRepoConfigRegistry(services *feastdevv1.FeatureStoreServices, secretExtr repoConfig.Registry.DBParameters = parametersMap } } + + if services.Registry.Local.Server != nil && + services.Registry.Local.Server.Mcp != nil && + services.Registry.Local.Server.Mcp.Enabled { + repoConfig.Registry.Mcp = &RegistryMcpYamlConfig{ + Enabled: true, + } + } + return nil } @@ -284,24 +369,147 @@ func setRepoConfigBatchEngine( return nil } -func (feast *FeastServices) getClientFeatureStoreYaml(secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error)) ([]byte, error) { - clientRepo, err := getClientRepoConfig(feast.Handler.FeatureStore, secretExtractionFunc, feast) - if err != nil { - return []byte{}, err +// setRepoConfigFeatureServer maps the CRD ServingConfig into the feature_server YAML block. +// Type is set to "mcp" only when fs.Mcp is non-nil and fs.Mcp.Enabled is true; otherwise "local". +func setRepoConfigFeatureServer(fs *feastdevv1.ServingConfig, repoConfig *RepoConfig) { + serverType := "local" + if fs.Mcp != nil && fs.Mcp.Enabled { + serverType = "mcp" + } + + yamlCfg := &FeatureServerYamlConfig{ + Type: serverType, } + + if fs.Metrics != nil { + m := &MetricsYamlConfig{ + Enabled: fs.Metrics.Enabled, + } + if len(fs.Metrics.Categories) > 0 { + m.Categories = make(map[string]interface{}, len(fs.Metrics.Categories)) + for k, v := range fs.Metrics.Categories { + m.Categories[k] = v + } + } + yamlCfg.Metrics = m + } + + if fs.OfflinePushBatching != nil { + enabled := fs.OfflinePushBatching.Enabled + yamlCfg.OfflinePushBatchingEnabled = &enabled + yamlCfg.OfflinePushBatchingBatchSize = fs.OfflinePushBatching.BatchSize + yamlCfg.OfflinePushBatchingBatchIntervalSeconds = fs.OfflinePushBatching.BatchIntervalSeconds + } + + if fs.Mcp != nil && fs.Mcp.Enabled { + enabled := fs.Mcp.Enabled + yamlCfg.McpEnabled = &enabled + yamlCfg.McpServerName = fs.Mcp.ServerName + yamlCfg.McpServerVersion = fs.Mcp.ServerVersion + yamlCfg.McpTransport = fs.Mcp.Transport + } + + repoConfig.FeatureServer = yamlCfg +} + +// setRepoConfigMaterialization maps the CRD MaterializationConfig into the materialization YAML block. +func setRepoConfigMaterialization(mat *feastdevv1.MaterializationConfig, repoConfig *RepoConfig) { + yamlCfg := &MaterializationYamlConfig{ + OnlineWriteBatchSize: mat.OnlineWriteBatchSize, + } + if len(mat.ExtraConfig) > 0 { + ec := make(map[string]interface{}, len(mat.ExtraConfig)) + for k, v := range mat.ExtraConfig { + ec[k] = coerceStringToYamlType(v) + } + yamlCfg.ExtraConfig = ec + } + repoConfig.Materialization = yamlCfg +} + +// setRepoConfigOpenLineage maps the CRD OpenLineageConfig into the openlineage YAML block. +// When ApiKeySecretRef is set, the api_key value is resolved from the referenced Secret. +// ExtraConfig string values are coerced to native YAML types (bool/int) so that Feast's +// StrictBool/StrictInt Pydantic validators accept them correctly. +func setRepoConfigOpenLineage( + ol *feastdevv1.OpenLineageConfig, + secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error), + repoConfig *RepoConfig) error { + + yamlCfg := &OpenLineageYamlConfig{ + Enabled: ol.Enabled, + TransportType: ol.TransportType, + TransportUrl: ol.TransportUrl, + TransportEndpoint: ol.TransportEndpoint, + } + if len(ol.ExtraConfig) > 0 { + ec := make(map[string]interface{}, len(ol.ExtraConfig)) + for k, v := range ol.ExtraConfig { + ec[k] = coerceStringToYamlType(v) + } + yamlCfg.ExtraConfig = ec + } + + if ol.ApiKeySecretRef != nil { + params, err := secretExtractionFunc("", ol.ApiKeySecretRef.Name, "") + if err != nil { + return fmt.Errorf("failed to read OpenLineage API key from secret %s: %w", ol.ApiKeySecretRef.Name, err) + } + apiKey, exists := params["api_key"] + if !exists { + return fmt.Errorf("secret %q does not contain the required key \"api_key\"", ol.ApiKeySecretRef.Name) + } + apiKeyStr, ok := apiKey.(string) + if !ok { + return fmt.Errorf("key \"api_key\" in secret %q must be a string, got %T", ol.ApiKeySecretRef.Name, apiKey) + } + yamlCfg.ApiKey = &apiKeyStr + } + + repoConfig.OpenLineage = yamlCfg + return nil +} + +// coerceStringToYamlType converts "true"/"false" strings to native Go booleans +// so the YAML marshaler emits an unquoted boolean rather than a quoted string. +// This is required because CRD map[string]string fields can only hold strings, +// but Feast Pydantic StrictBool fields reject string inputs. +// +// Integer coercion is intentionally omitted: some ExtraConfig target fields are +// typed as StrictStr (e.g. OpenLineageConfig.namespace, .producer), and coercing +// a numeric string like "123" to int64 would cause a Pydantic validation failure +// at runtime. Fields that genuinely require integers should be exposed as typed +// CRD fields rather than going through ExtraConfig. +func coerceStringToYamlType(v string) interface{} { + switch v { + case stringTrue: + return true + case stringFalse: + return false + } + return v +} + +func setRepoConfigDataQualityMonitoring(dqmConfig *feastdevv1.DataQualityMonitoringConfig, repoConfig *RepoConfig) { + if dqmConfig.AutoBaseline == nil { + return + } + repoConfig.DataQualityMonitoring = &DataQualityMonitoringYamlConfig{ + AutoBaseline: *dqmConfig.AutoBaseline, + } +} + +func (feast *FeastServices) getClientFeatureStoreYaml() ([]byte, error) { + clientRepo := getClientRepoConfig(feast.Handler.FeatureStore, feast) return yaml.Marshal(clientRepo) } func getClientRepoConfig( featureStore *feastdevv1.FeatureStore, - secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error), - feast *FeastServices) (RepoConfig, error) { + feast *FeastServices) RepoConfig { status := featureStore.Status appliedServices := status.Applied.Services - clientRepoConfig, err := getRepoConfig(featureStore, secretExtractionFunc) - if err != nil { - return clientRepoConfig, err - } + clientRepoConfig := getRepoConfig(featureStore) if len(status.ServiceHostnames.OfflineStore) > 0 { clientRepoConfig.OfflineStore = OfflineStoreConfig{ Type: OfflineRemoteConfigType, @@ -339,12 +547,10 @@ func getClientRepoConfig( } } - return clientRepoConfig, nil + return clientRepoConfig } -func getRepoConfig( - featureStore *feastdevv1.FeatureStore, - secretExtractionFunc func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error)) (RepoConfig, error) { +func getRepoConfig(featureStore *feastdevv1.FeatureStore) RepoConfig { status := featureStore.Status repoConfig := initRepoConfig(status.Applied.FeastProject) if status.Applied.AuthzConfig != nil { @@ -356,24 +562,16 @@ func getRepoConfig( repoConfig.AuthzConfig = AuthzConfig{ Type: OidcAuthType, } - - propertiesMap, err := secretExtractionFunc("", status.Applied.AuthzConfig.OidcAuthz.SecretRef.Name, "") - if err != nil { - return repoConfig, err - } - oidcClientProperties := map[string]interface{}{} - for _, oidcProperty := range OidcProperties { - if val, exists := propertiesMap[string(oidcProperty)]; exists { - oidcClientProperties[string(oidcProperty)] = val - } else { - return repoConfig, missingOidcSecretProperty(oidcProperty) - } + if status.Applied.AuthzConfig.OidcAuthz.TokenEnvVar != nil { + oidcClientProperties[string(OidcTokenEnvVar)] = *status.Applied.AuthzConfig.OidcAuthz.TokenEnvVar + } + if len(oidcClientProperties) > 0 { + repoConfig.AuthzConfig.OidcParameters = oidcClientProperties } - repoConfig.AuthzConfig.OidcParameters = oidcClientProperties } } - return repoConfig, nil + return repoConfig } func getActualPath(filePath string, pvcConfig *feastdevv1.PvcConfig) string { diff --git a/infra/feast-operator/internal/controller/services/repo_config_test.go b/infra/feast-operator/internal/controller/services/repo_config_test.go index 70869568dea..5ae22a795f6 100644 --- a/infra/feast-operator/internal/controller/services/repo_config_test.go +++ b/infra/feast-operator/internal/controller/services/repo_config_test.go @@ -30,6 +30,8 @@ import ( var projectName = "test-project" +const marquezUrl = "http://marquez:5000" + var _ = Describe("Repo Config", func() { Context("When creating the RepoConfig of a FeatureStore", func() { It("should successfully create the repo configs", func() { @@ -46,7 +48,7 @@ var _ = Describe("Repo Config", func() { Path: EphemeralPath + "/" + DefaultOnlineStorePath, } - repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(NoAuthAuthType)) Expect(repoConfig.OfflineStore).To(Equal(emptyOfflineStoreConfig)) @@ -74,7 +76,7 @@ var _ = Describe("Repo Config", func() { Path: testPath, } - repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(NoAuthAuthType)) Expect(repoConfig.OfflineStore).To(Equal(emptyOfflineStoreConfig)) @@ -96,7 +98,7 @@ var _ = Describe("Repo Config", func() { Expect(appliedServices.OnlineStore).NotTo(BeNil()) Expect(appliedServices.Registry.Local).NotTo(BeNil()) - repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.OfflineStore).To(Equal(defaultOfflineStoreConfig)) Expect(repoConfig.AuthzConfig.Type).To(Equal(NoAuthAuthType)) @@ -115,7 +117,7 @@ var _ = Describe("Repo Config", func() { }, } ApplyDefaultsToStatus(featureStore) - repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(NoAuthAuthType)) Expect(repoConfig.OfflineStore).To(Equal(emptyOfflineStoreConfig)) @@ -135,7 +137,7 @@ var _ = Describe("Repo Config", func() { OnlineStore: &feastdevv1.OnlineStore{ Persistence: &feastdevv1.OnlineStorePersistence{ FilePersistence: &feastdevv1.OnlineStoreFilePersistence{ - Path: "/data/online.db", + Path: dataOnlineDbPath, }, }, }, @@ -143,7 +145,7 @@ var _ = Describe("Repo Config", func() { Local: &feastdevv1.LocalRegistryConfig{ Persistence: &feastdevv1.RegistryPersistence{ FilePersistence: &feastdevv1.RegistryFilePersistence{ - Path: "/data/registry.db", + Path: dataRegistryDbPath, }, }, }, @@ -156,14 +158,14 @@ var _ = Describe("Repo Config", func() { } expectedRegistryConfig = RegistryConfig{ RegistryType: "file", - Path: "/data/registry.db", + Path: dataRegistryDbPath, } expectedOnlineConfig = OnlineStoreConfig{ Type: "sqlite", - Path: "/data/online.db", + Path: dataOnlineDbPath, } - repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(NoAuthAuthType)) Expect(repoConfig.OfflineStore).To(Equal(expectedOfflineConfig)) @@ -188,18 +190,18 @@ var _ = Describe("Repo Config", func() { Type: "dask", } - repoConfig, err = getServiceRepoConfig(featureStore, mockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, mockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(KubernetesAuthType)) Expect(repoConfig.OfflineStore).To(Equal(expectedOfflineConfig)) Expect(repoConfig.OnlineStore).To(Equal(defaultOnlineStoreConfig(featureStore))) Expect(repoConfig.Registry).To(Equal(defaultRegistryConfig(featureStore))) - By("Having oidc authorization") + By("Having oidc authorization with Secret") featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ OidcAuthz: &feastdevv1.OidcAuthz{ - SecretRef: corev1.LocalObjectReference{ - Name: "oidc-secret", + SecretRef: &corev1.LocalObjectReference{ + Name: oidcSecretName, }, }, } @@ -207,11 +209,11 @@ var _ = Describe("Repo Config", func() { secretExtractionFunc := mockOidcConfigFromSecret(map[string]interface{}{ string(OidcAuthDiscoveryUrl): "discovery-url", - string(OidcClientId): "client-id", + string(OidcClientId): clientIDValue, string(OidcClientSecret): "client-secret", string(OidcUsername): "username", string(OidcPassword): "password"}) - repoConfig, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(OidcAuthType)) Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveLen(5)) @@ -224,15 +226,35 @@ var _ = Describe("Repo Config", func() { Expect(repoConfig.OnlineStore).To(Equal(defaultOnlineStoreConfig(featureStore))) Expect(repoConfig.Registry).To(Equal(defaultRegistryConfig(featureStore))) - repoConfig, err = getClientRepoConfig(featureStore, secretExtractionFunc, nil) + repoConfig = getClientRepoConfig(featureStore, nil) + Expect(repoConfig.AuthzConfig.Type).To(Equal(OidcAuthType)) + + By("Having oidc authorization with issuerUrl only (no Secret)") + featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ + OidcAuthz: &feastdevv1.OidcAuthz{ + IssuerUrl: "https://keycloak.example.com/realms/test", + }, + } + ApplyDefaultsToStatus(featureStore) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) Expect(repoConfig.AuthzConfig.Type).To(Equal(OidcAuthType)) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveLen(5)) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveKey(string(OidcClientId))) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveKey(string(OidcAuthDiscoveryUrl))) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveKey(string(OidcClientSecret))) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveKey(string(OidcUsername))) - Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveKey(string(OidcPassword))) + Expect(repoConfig.AuthzConfig.OidcParameters).To(HaveLen(1)) + Expect(repoConfig.AuthzConfig.OidcParameters[string(OidcAuthDiscoveryUrl)]).To(Equal("https://keycloak.example.com/realms/test/.well-known/openid-configuration")) + + By("Having oidc with issuerUrl on CR and auth_discovery_url in Secret — CR wins") + featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ + OidcAuthz: &feastdevv1.OidcAuthz{ + IssuerUrl: "https://keycloak.example.com/realms/cr-wins", + SecretRef: &corev1.LocalObjectReference{ + Name: oidcSecretName, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + repoConfig, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.AuthzConfig.OidcParameters[string(OidcAuthDiscoveryUrl)]).To(Equal("https://keycloak.example.com/realms/cr-wins/.well-known/openid-configuration")) By("Having the all the db services") featureStore = minimalFeatureStore() @@ -275,7 +297,7 @@ var _ = Describe("Repo Config", func() { featureStore.Spec.Services.OfflineStore.Persistence.FilePersistence = nil featureStore.Spec.Services.OnlineStore.Persistence.FilePersistence = nil featureStore.Spec.Services.Registry.Local.Persistence.FilePersistence = nil - repoConfig, err = getServiceRepoConfig(featureStore, mockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap) + repoConfig, err = getServiceRepoConfig(featureStore, mockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) Expect(err).NotTo(HaveOccurred()) newMap := CopyMap(parameterMap) port := parameterMap["port"].(int) @@ -296,38 +318,399 @@ var _ = Describe("Repo Config", func() { Expect(repoConfig.OfflineStore).To(Equal(expectedOfflineConfig)) Expect(repoConfig.OnlineStore).To(Equal(expectedOnlineConfig)) Expect(repoConfig.Registry).To(Equal(expectedRegistryConfig)) + + By("Having DQM config with auto_baseline disabled") + featureStore = minimalFeatureStore() + dqmAutoBaseline := false + featureStore.Spec.DataQualityMonitoring = &feastdevv1.DataQualityMonitoringConfig{ + AutoBaseline: &dqmAutoBaseline, + } + ApplyDefaultsToStatus(featureStore) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.DataQualityMonitoring).NotTo(BeNil()) + Expect(repoConfig.DataQualityMonitoring.AutoBaseline).To(BeFalse()) + + fsYaml, marshalErr := yaml.Marshal(repoConfig) + Expect(marshalErr).NotTo(HaveOccurred()) + Expect(string(fsYaml)).To(ContainSubstring("data_quality_monitoring:")) + Expect(string(fsYaml)).To(ContainSubstring("auto_baseline: false")) + + By("Having no DataQualityMonitoring config — should be nil") + featureStore = minimalFeatureStore() + ApplyDefaultsToStatus(featureStore) + repoConfig, err = getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.DataQualityMonitoring).To(BeNil()) + }) + + It("should set feature_server block with type local and all options", func() { + featureStore := minimalFeatureStore() + batchSize := int32(500) + batchInterval := int32(15) + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Serving: &feastdevv1.ServingConfig{ + Metrics: &feastdevv1.ServingMetricsConfig{ + Enabled: true, + Categories: map[string]bool{ + "resource": true, + "freshness": false, + "registry_sync": false, + }, + }, + OfflinePushBatching: &feastdevv1.OfflinePushBatchingConfig{ + Enabled: true, + BatchSize: &batchSize, + BatchIntervalSeconds: &batchInterval, + }, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.FeatureServer).NotTo(BeNil()) + Expect(repoConfig.FeatureServer.Type).To(Equal("local")) + + Expect(repoConfig.FeatureServer.Metrics).NotTo(BeNil()) + Expect(repoConfig.FeatureServer.Metrics.Enabled).To(BeTrue()) + Expect(repoConfig.FeatureServer.Metrics.Categories).To(HaveKeyWithValue("resource", true)) + Expect(repoConfig.FeatureServer.Metrics.Categories).To(HaveKeyWithValue("freshness", false)) + Expect(repoConfig.FeatureServer.Metrics.Categories).To(HaveKeyWithValue("registry_sync", false)) + + Expect(repoConfig.FeatureServer.OfflinePushBatchingEnabled).NotTo(BeNil()) + Expect(*repoConfig.FeatureServer.OfflinePushBatchingEnabled).To(BeTrue()) + Expect(repoConfig.FeatureServer.OfflinePushBatchingBatchSize).To(Equal(&batchSize)) + Expect(repoConfig.FeatureServer.OfflinePushBatchingBatchIntervalSeconds).To(Equal(&batchInterval)) + + Expect(repoConfig.FeatureServer.McpEnabled).To(BeNil()) + }) + + It("should set feature_server block with type mcp", func() { + featureStore := minimalFeatureStore() + serverName := "my-mcp-server" + serverVersion := "2.0.0" + transport := HttpScheme + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Serving: &feastdevv1.ServingConfig{ + Mcp: &feastdevv1.McpConfig{ + Enabled: true, + ServerName: &serverName, + ServerVersion: &serverVersion, + Transport: &transport, + }, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.FeatureServer).NotTo(BeNil()) + Expect(repoConfig.FeatureServer.Type).To(Equal("mcp")) + Expect(repoConfig.FeatureServer.McpEnabled).NotTo(BeNil()) + Expect(*repoConfig.FeatureServer.McpEnabled).To(BeTrue()) + Expect(repoConfig.FeatureServer.McpServerName).To(Equal(&serverName)) + Expect(repoConfig.FeatureServer.McpServerVersion).To(Equal(&serverVersion)) + Expect(repoConfig.FeatureServer.McpTransport).To(Equal(&transport)) + }) + + It("should use type local when Mcp is present but Enabled is false", func() { + featureStore := minimalFeatureStore() + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Serving: &feastdevv1.ServingConfig{ + Mcp: &feastdevv1.McpConfig{ + Enabled: false, + }, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.FeatureServer).NotTo(BeNil()) + Expect(repoConfig.FeatureServer.Type).To(Equal("local")) + Expect(repoConfig.FeatureServer.McpEnabled).To(BeNil()) + }) + + It("should set registry mcp when enabled", func() { + featureStore := minimalFeatureStore() + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + Mcp: &feastdevv1.McpConfig{ + Enabled: true, + }, + }, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.Registry.Mcp).NotTo(BeNil()) + Expect(repoConfig.Registry.Mcp.Enabled).To(BeTrue()) + }) + + It("should not set registry mcp when disabled", func() { + featureStore := minimalFeatureStore() + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + Mcp: &feastdevv1.McpConfig{ + Enabled: false, + }, + }, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.Registry.Mcp).To(BeNil()) + }) + + It("should not set registry mcp when server has no mcp config", func() { + featureStore := minimalFeatureStore() + + featureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{}, + }, + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.Registry.Mcp).To(BeNil()) + }) + + It("should set materialization block", func() { + featureStore := minimalFeatureStore() + batchSize := int32(10000) + + featureStore.Spec.Materialization = &feastdevv1.MaterializationConfig{ + OnlineWriteBatchSize: &batchSize, + ExtraConfig: map[string]string{ + "pull_latest_features": stringFalse, + "max_workers": "4", + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.Materialization).NotTo(BeNil()) + Expect(repoConfig.Materialization.OnlineWriteBatchSize).To(Equal(&batchSize)) + // "true"/"false" strings are coerced to native booleans; other strings pass through unchanged. + Expect(repoConfig.Materialization.ExtraConfig).To(HaveKeyWithValue("pull_latest_features", false)) + Expect(repoConfig.Materialization.ExtraConfig).To(HaveKeyWithValue("max_workers", "4")) + }) + + It("should set openlineage block without api_key secret", func() { + featureStore := minimalFeatureStore() + transportType := HttpScheme + transportUrl := marquezUrl + endpoint := "api/v1/lineage" + + featureStore.Spec.OpenLineage = &feastdevv1.OpenLineageConfig{ + Enabled: true, + TransportType: &transportType, + TransportUrl: &transportUrl, + TransportEndpoint: &endpoint, + ExtraConfig: map[string]string{ + "namespace": "my-feast", + "producer": "feast-operator", + "emit_on_apply": stringTrue, + "emit_on_materialize": "false", + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.OpenLineage).NotTo(BeNil()) + Expect(repoConfig.OpenLineage.Enabled).To(BeTrue()) + Expect(repoConfig.OpenLineage.TransportType).To(Equal(&transportType)) + Expect(repoConfig.OpenLineage.TransportUrl).To(Equal(&transportUrl)) + Expect(repoConfig.OpenLineage.TransportEndpoint).To(Equal(&endpoint)) + Expect(repoConfig.OpenLineage.ApiKey).To(BeNil()) + // ExtraConfig: "true"/"false" strings coerced to booleans; other strings unchanged. + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("namespace", "my-feast")) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("producer", "feast-operator")) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("emit_on_apply", true)) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("emit_on_materialize", false)) + }) + + It("should set openlineage block with kafka extraConfig", func() { + featureStore := minimalFeatureStore() + transportType := "kafka" + + featureStore.Spec.OpenLineage = &feastdevv1.OpenLineageConfig{ + Enabled: true, + TransportType: &transportType, + ExtraConfig: map[string]string{ + "bootstrap_servers": "kafka.svc:9092", + "topic": "openlineage", + "sasl_mechanism": "PLAIN", + }, + } + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.OpenLineage).NotTo(BeNil()) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("bootstrap_servers", "kafka.svc:9092")) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("topic", "openlineage")) + Expect(repoConfig.OpenLineage.ExtraConfig).To(HaveKeyWithValue("sasl_mechanism", "PLAIN")) + }) + + It("should resolve api_key from secret for openlineage", func() { + featureStore := minimalFeatureStore() + transportType := HttpScheme + transportUrl := marquezUrl + + featureStore.Spec.OpenLineage = &feastdevv1.OpenLineageConfig{ + Enabled: true, + TransportType: &transportType, + TransportUrl: &transportUrl, + ApiKeySecretRef: &corev1.LocalObjectReference{ + Name: lineageSecretName, + }, + } + ApplyDefaultsToStatus(featureStore) + + apiKeyMockExtract := func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error) { + return map[string]interface{}{ + "api_key": "my-secret-key", + }, nil + } + + repoConfig, err := getServiceRepoConfig(featureStore, apiKeyMockExtract, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.OpenLineage).NotTo(BeNil()) + Expect(repoConfig.OpenLineage.ApiKey).NotTo(BeNil()) + Expect(*repoConfig.OpenLineage.ApiKey).To(Equal("my-secret-key")) + }) + + It("should return error when apiKeySecretRef Secret is missing the api_key key", func() { + featureStore := minimalFeatureStore() + transportType := HttpScheme + transportUrl := marquezUrl + + featureStore.Spec.OpenLineage = &feastdevv1.OpenLineageConfig{ + Enabled: true, + TransportType: &transportType, + TransportUrl: &transportUrl, + ApiKeySecretRef: &corev1.LocalObjectReference{ + Name: lineageSecretName, + }, + } + ApplyDefaultsToStatus(featureStore) + + missingKeyMock := func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error) { + return map[string]interface{}{ + "wrong_key": "some-value", + }, nil + } + + _, err := getServiceRepoConfig(featureStore, missingKeyMock, emptyMockExtractConfigFromConfigMap, false) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("api_key")) + Expect(err.Error()).To(ContainSubstring(lineageSecretName)) + }) + + It("should return error when apiKeySecretRef api_key value is not a string", func() { + featureStore := minimalFeatureStore() + transportType := HttpScheme + transportUrl := marquezUrl + + featureStore.Spec.OpenLineage = &feastdevv1.OpenLineageConfig{ + Enabled: true, + TransportType: &transportType, + TransportUrl: &transportUrl, + ApiKeySecretRef: &corev1.LocalObjectReference{ + Name: lineageSecretName, + }, + } + ApplyDefaultsToStatus(featureStore) + + nonStringMock := func(storeType string, secretRef string, secretKeyName string) (map[string]interface{}, error) { + return map[string]interface{}{ + "api_key": 12345, // integer, not a string + }, nil + } + + _, err := getServiceRepoConfig(featureStore, nonStringMock, emptyMockExtractConfigFromConfigMap, false) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("api_key")) + Expect(err.Error()).To(ContainSubstring(lineageSecretName)) + }) + + It("should not set feature_server block when serving is nil", func() { + featureStore := minimalFeatureStore() + ApplyDefaultsToStatus(featureStore) + + repoConfig, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + Expect(repoConfig.FeatureServer).To(BeNil()) + Expect(repoConfig.Materialization).To(BeNil()) + Expect(repoConfig.OpenLineage).To(BeNil()) }) }) It("should fail to create the repo configs", func() { featureStore := minimalFeatureStore() - By("Having invalid server oidc authorization") + By("Having oidc with no issuerUrl, no Secret, no env var — should fail") + featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ + OidcAuthz: &feastdevv1.OidcAuthz{}, + } + ApplyDefaultsToStatus(featureStore) + + _, err := getServiceRepoConfig(featureStore, emptyMockExtractConfigFromSecret, emptyMockExtractConfigFromConfigMap, false) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no OIDC discovery URL configured")) + + By("Having oidc with Secret missing auth_discovery_url and no issuerUrl — should fail") featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ OidcAuthz: &feastdevv1.OidcAuthz{ - SecretRef: corev1.LocalObjectReference{ - Name: "oidc-secret", + SecretRef: &corev1.LocalObjectReference{ + Name: oidcSecretName, }, }, } ApplyDefaultsToStatus(featureStore) secretExtractionFunc := mockOidcConfigFromSecret(map[string]interface{}{ - string(OidcClientId): "client-id", + string(OidcClientId): clientIDValue, string(OidcClientSecret): "client-secret", string(OidcUsername): "username", string(OidcPassword): "password"}) - _, err := getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap) + _, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap, false) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("missing OIDC secret")) - _, err = getClientRepoConfig(featureStore, secretExtractionFunc, nil) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("missing OIDC secret")) + Expect(err.Error()).To(ContainSubstring("no OIDC discovery URL configured")) By("Having invalid client oidc authorization") featureStore.Spec.AuthzConfig = &feastdevv1.AuthzConfig{ OidcAuthz: &feastdevv1.OidcAuthz{ - SecretRef: corev1.LocalObjectReference{ - Name: "oidc-secret", + SecretRef: &corev1.LocalObjectReference{ + Name: oidcSecretName, }, }, } @@ -335,15 +718,12 @@ var _ = Describe("Repo Config", func() { secretExtractionFunc = mockOidcConfigFromSecret(map[string]interface{}{ string(OidcAuthDiscoveryUrl): "discovery-url", - string(OidcClientId): "client-id", + string(OidcClientId): clientIDValue, string(OidcUsername): "username", string(OidcPassword): "password"}) - _, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("missing OIDC secret")) - _, err = getClientRepoConfig(featureStore, secretExtractionFunc, nil) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("missing OIDC secret")) + _, err = getServiceRepoConfig(featureStore, secretExtractionFunc, emptyMockExtractConfigFromConfigMap, false) + Expect(err).NotTo(HaveOccurred()) + getClientRepoConfig(featureStore, nil) }) }) @@ -476,7 +856,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "offline-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -486,7 +866,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "online-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -506,7 +886,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "registry-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -519,8 +899,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { } // Test with nil feast parameter (no custom CA bundle) - repoConfig, err := getClientRepoConfig(featureStore, emptyMockExtractConfigFromSecret, nil) - Expect(err).NotTo(HaveOccurred()) + repoConfig := getClientRepoConfig(featureStore, nil) // Verify individual service certificate paths are used Expect(repoConfig.OfflineStore.Cert).To(Equal("/tls/offline/tls.crt")) @@ -546,7 +925,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "offline-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -556,7 +935,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "online-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -576,7 +955,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { TLS: &feastdevv1.TlsConfigs{ SecretRef: &corev1.LocalObjectReference{Name: "registry-tls"}, SecretKeyNames: feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, }, }, }, @@ -589,8 +968,7 @@ var _ = Describe("TLS Certificate Path Configuration", func() { } // Test with nil feast parameter (no custom CA bundle available) - repoConfig, err := getClientRepoConfig(featureStore, emptyMockExtractConfigFromSecret, nil) - Expect(err).NotTo(HaveOccurred()) + repoConfig := getClientRepoConfig(featureStore, nil) Expect(repoConfig.OfflineStore.Cert).To(Equal("/tls/offline/tls.crt")) }) }) diff --git a/infra/feast-operator/internal/controller/services/scaling.go b/infra/feast-operator/internal/controller/services/scaling.go index ef1dd1f91d8..b02dc1eee07 100644 --- a/infra/feast-operator/internal/controller/services/scaling.go +++ b/infra/feast-operator/internal/controller/services/scaling.go @@ -231,7 +231,7 @@ func (feast *FeastServices) buildPDBApplyConfig() *pdbac.PodDisruptionBudgetAppl WithBlockOwnerDeletion(true), ). WithSpec(pdbac.PodDisruptionBudgetSpec(). - WithSelector(metaac.LabelSelector().WithMatchLabels(feast.getLabels())), + WithSelector(metaac.LabelSelector().WithMatchLabels(feast.getSelectorLabels())), ) if pdbConfig.MinAvailable != nil { @@ -249,8 +249,7 @@ func (feast *FeastServices) updateScalingStatus(deploy *appsv1.Deployment) { cr := feast.Handler.FeatureStore cr.Status.Replicas = deploy.Status.ReadyReplicas - labels := feast.getLabels() - cr.Status.Selector = metav1.FormatLabelSelector(metav1.SetAsLabelSelector(labels)) + cr.Status.Selector = metav1.FormatLabelSelector(metav1.SetAsLabelSelector(feast.getSelectorLabels())) if !isScalingEnabled(cr) { cr.Status.ScalingStatus = nil diff --git a/infra/feast-operator/internal/controller/services/scaling_test.go b/infra/feast-operator/internal/controller/services/scaling_test.go index 58e808ac2dc..1f65a4835ce 100644 --- a/infra/feast-operator/internal/controller/services/scaling_test.go +++ b/infra/feast-operator/internal/controller/services/scaling_test.go @@ -46,7 +46,7 @@ var _ = Describe("Horizontal Scaling", func() { ctx = context.Background() typeNamespacedName = types.NamespacedName{ Name: "scaling-test-fs", - Namespace: "default", + Namespace: DefaultNs, } featureStore = &feastdevv1.FeatureStore{ @@ -67,9 +67,9 @@ var _ = Describe("Horizontal Scaling", func() { }, Persistence: &feastdevv1.OnlineStorePersistence{ DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{ - Type: "redis", + Type: redisType, SecretRef: corev1.LocalObjectReference{ - Name: "redis-secret", + Name: redisSecretName, }, }, }, @@ -90,7 +90,7 @@ var _ = Describe("Horizontal Scaling", func() { DBPersistence: &feastdevv1.RegistryDBStorePersistence{ Type: "sql", SecretRef: corev1.LocalObjectReference{ - Name: "registry-secret", + Name: registrySecretName, }, }, }, @@ -146,8 +146,8 @@ var _ = Describe("Horizontal Scaling", func() { dbOnlineStore := &feastdevv1.OnlineStore{ Persistence: &feastdevv1.OnlineStorePersistence{ DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{ - Type: "redis", - SecretRef: corev1.LocalObjectReference{Name: "redis-secret"}, + Type: redisType, + SecretRef: corev1.LocalObjectReference{Name: redisSecretName}, }, }, } @@ -157,7 +157,7 @@ var _ = Describe("Horizontal Scaling", func() { Persistence: &feastdevv1.RegistryPersistence{ DBPersistence: &feastdevv1.RegistryDBStorePersistence{ Type: "sql", - SecretRef: corev1.LocalObjectReference{Name: "registry-secret"}, + SecretRef: corev1.LocalObjectReference{Name: registrySecretName}, }, }, }, @@ -165,9 +165,9 @@ var _ = Describe("Horizontal Scaling", func() { It("should accept scaling with full DB persistence", func() { fs := &feastdevv1.FeatureStore{ - ObjectMeta: metav1.ObjectMeta{Name: "cel-valid-db", Namespace: "default"}, + ObjectMeta: metav1.ObjectMeta{Name: "cel-valid-db", Namespace: DefaultNs}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -181,9 +181,9 @@ var _ = Describe("Horizontal Scaling", func() { It("should reject scaling when online store is missing (implicit file default)", func() { fs := &feastdevv1.FeatureStore{ - ObjectMeta: metav1.ObjectMeta{Name: "cel-no-online", Namespace: "default"}, + ObjectMeta: metav1.ObjectMeta{Name: "cel-no-online", Namespace: DefaultNs}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ Registry: dbRegistry, @@ -199,13 +199,13 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-file-online", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: &feastdevv1.OnlineStore{ Persistence: &feastdevv1.OnlineStorePersistence{ FilePersistence: &feastdevv1.OnlineStoreFilePersistence{ - Path: "/data/online.db", + Path: dataOnlineDbPath, }, }, }, @@ -222,7 +222,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-file-offline", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -246,7 +246,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-no-registry", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -262,7 +262,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-file-registry", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -270,7 +270,7 @@ var _ = Describe("Horizontal Scaling", func() { Local: &feastdevv1.LocalRegistryConfig{ Persistence: &feastdevv1.RegistryPersistence{ FilePersistence: &feastdevv1.RegistryFilePersistence{ - Path: "/data/registry.db", + Path: dataRegistryDbPath, }, }, }, @@ -287,7 +287,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-s3-registry", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -311,7 +311,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-gs-registry", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -335,7 +335,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-remote-reg", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -355,7 +355,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-rep1-file", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(1)), }, } @@ -367,7 +367,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-no-scaling", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, }, } Expect(k8sClient.Create(ctx, fs)).To(Succeed()) @@ -378,7 +378,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-hpa-no-db", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Services: &feastdevv1.FeatureStoreServices{ Scaling: &feastdevv1.ScalingConfig{ Autoscaling: &feastdevv1.AutoscalingConfig{MaxReplicas: 5}, @@ -396,7 +396,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-online-nop", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: &feastdevv1.OnlineStore{}, @@ -413,7 +413,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-mutual-excl", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ Scaling: &feastdevv1.ScalingConfig{ @@ -683,8 +683,8 @@ var _ = Describe("Horizontal Scaling", func() { dbOnlineStore := &feastdevv1.OnlineStore{ Persistence: &feastdevv1.OnlineStorePersistence{ DBPersistence: &feastdevv1.OnlineStoreDBStorePersistence{ - Type: "redis", - SecretRef: corev1.LocalObjectReference{Name: "redis-secret"}, + Type: redisType, + SecretRef: corev1.LocalObjectReference{Name: redisSecretName}, }, }, } @@ -693,7 +693,7 @@ var _ = Describe("Horizontal Scaling", func() { Persistence: &feastdevv1.RegistryPersistence{ DBPersistence: &feastdevv1.RegistryDBStorePersistence{ Type: "sql", - SecretRef: corev1.LocalObjectReference{Name: "registry-secret"}, + SecretRef: corev1.LocalObjectReference{Name: registrySecretName}, }, }, }, @@ -703,7 +703,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-pdb-both", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -724,7 +724,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-pdb-none", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -742,7 +742,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-pdb-maxu", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -761,7 +761,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{Name: "cel-pdb-mina", Namespace: "default"}, Spec: feastdevv1.FeatureStoreSpec{ - FeastProject: "celtest", + FeastProject: celTestProject, Replicas: ptr.To(int32(3)), Services: &feastdevv1.FeatureStoreServices{ OnlineStore: dbOnlineStore, @@ -814,7 +814,7 @@ var _ = Describe("Horizontal Scaling", func() { featureStore.Status.Applied.Replicas = ptr.To(int32(3)) featureStore.Status.Applied.Services.TopologySpreadConstraints = []corev1.TopologySpreadConstraint{{ MaxSkew: 2, - TopologyKey: "kubernetes.io/hostname", + TopologyKey: kubernetesHostnameTopologyKey, WhenUnsatisfiable: corev1.DoNotSchedule, LabelSelector: metav1.SetAsLabelSelector(map[string]string{"custom": "label"}), }} @@ -902,7 +902,7 @@ var _ = Describe("Horizontal Scaling", func() { MatchExpressions: []corev1.NodeSelectorRequirement{{ Key: "gpu", Operator: corev1.NodeSelectorOpIn, - Values: []string{"true"}, + Values: []string{stringTrue}, }}, }}, }, @@ -922,7 +922,7 @@ var _ = Describe("Horizontal Scaling", func() { return &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: "default", + Namespace: DefaultNs, }, Spec: feastdevv1.FeatureStoreSpec{ FeastProject: "scaletest", @@ -940,7 +940,7 @@ var _ = Describe("Horizontal Scaling", func() { Persistence: &feastdevv1.RegistryPersistence{ DBPersistence: &feastdevv1.RegistryDBStorePersistence{ Type: "sql", - SecretRef: corev1.LocalObjectReference{Name: "registry-secret"}, + SecretRef: corev1.LocalObjectReference{Name: registrySecretName}, }, }, }, @@ -972,7 +972,7 @@ var _ = Describe("Horizontal Scaling", func() { fs := &feastdevv1.FeatureStore{ ObjectMeta: metav1.ObjectMeta{ Name: "scale-sub-reject", - Namespace: "default", + Namespace: DefaultNs, }, Spec: feastdevv1.FeatureStoreSpec{ FeastProject: "scaletest", diff --git a/infra/feast-operator/internal/controller/services/service_monitor.go b/infra/feast-operator/internal/controller/services/service_monitor.go new file mode 100644 index 00000000000..8de4d131289 --- /dev/null +++ b/infra/feast-operator/internal/controller/services/service_monitor.go @@ -0,0 +1,117 @@ +/* +Copyright 2026 Feast Community. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package services + +import ( + "encoding/json" + + feastdevv1 "github.com/feast-dev/feast/infra/feast-operator/api/v1" + monitoringv1apply "github.com/prometheus-operator/prometheus-operator/pkg/client/applyconfiguration/monitoring/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + metav1apply "k8s.io/client-go/applyconfigurations/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +var serviceMonitorGVK = schema.GroupVersionKind{ + Group: "monitoring.coreos.com", + Version: "v1", + Kind: "ServiceMonitor", +} + +// createOrDeleteServiceMonitor reconciles the ServiceMonitor for the +// FeatureStore's online store metrics endpoint using Server-Side Apply. +// When the Prometheus Operator CRD is not present in the cluster, this is +// a no-op. When metrics are enabled on the online store, a ServiceMonitor +// is applied; otherwise any existing ServiceMonitor is deleted. +func (feast *FeastServices) createOrDeleteServiceMonitor() error { + if !hasServiceMonitorCRD { + return nil + } + + if feast.isOnlineStore() && feast.isMetricsEnabled(OnlineFeastType) { + return feast.applyServiceMonitor() + } + + return feast.deleteServiceMonitor() +} + +func (feast *FeastServices) applyServiceMonitor() error { + smApply := feast.buildServiceMonitorApplyConfig() + data, err := json.Marshal(smApply) + if err != nil { + return err + } + + sm := feast.initServiceMonitor() + logger := log.FromContext(feast.Handler.Context) + if err := feast.Handler.Client.Patch(feast.Handler.Context, sm, + client.RawPatch(types.ApplyPatchType, data), + client.FieldOwner(fieldManager), client.ForceOwnership); err != nil { + return err + } + logger.Info("Successfully applied", "ServiceMonitor", sm.GetName()) + + return nil +} + +func (feast *FeastServices) deleteServiceMonitor() error { + sm := feast.initServiceMonitor() + return feast.Handler.DeleteOwnedFeastObj(sm) +} + +func (feast *FeastServices) initServiceMonitor() *unstructured.Unstructured { + sm := &unstructured.Unstructured{} + sm.SetGroupVersionKind(serviceMonitorGVK) + sm.SetName(feast.GetFeastServiceName(OnlineFeastType)) + sm.SetNamespace(feast.Handler.FeatureStore.Namespace) + return sm +} + +// buildServiceMonitorApplyConfig constructs the fully desired ServiceMonitor +// state for Server-Side Apply. +func (feast *FeastServices) buildServiceMonitorApplyConfig() *monitoringv1apply.ServiceMonitorApplyConfiguration { + cr := feast.Handler.FeatureStore + objMeta := feast.GetObjectMetaType(OnlineFeastType) + + return monitoringv1apply.ServiceMonitor(objMeta.Name, objMeta.Namespace). + WithLabels(feast.getFeastTypeLabels(OnlineFeastType)). + WithOwnerReferences( + metav1apply.OwnerReference(). + WithAPIVersion(feastdevv1.GroupVersion.String()). + WithKind("FeatureStore"). + WithName(cr.Name). + WithUID(cr.UID). + WithController(true). + WithBlockOwnerDeletion(true), + ). + WithSpec(monitoringv1apply.ServiceMonitorSpec(). + WithEndpoints( + monitoringv1apply.Endpoint(). + WithPort("metrics"). + WithPath("/metrics"), + ). + WithSelector(metav1apply.LabelSelector(). + WithMatchLabels(map[string]string{ + NameLabelKey: cr.Name, + ServiceTypeLabelKey: string(OnlineFeastType), + }), + ), + ) +} diff --git a/infra/feast-operator/internal/controller/services/service_monitor_test.go b/infra/feast-operator/internal/controller/services/service_monitor_test.go new file mode 100644 index 00000000000..8d982e6953e --- /dev/null +++ b/infra/feast-operator/internal/controller/services/service_monitor_test.go @@ -0,0 +1,168 @@ +/* +Copyright 2026 Feast Community. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package services + +import ( + "context" + + feastdevv1 "github.com/feast-dev/feast/infra/feast-operator/api/v1" + "github.com/feast-dev/feast/infra/feast-operator/internal/controller/handler" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" +) + +var _ = Describe("ServiceMonitor", func() { + var ( + featureStore *feastdevv1.FeatureStore + feast *FeastServices + typeNamespacedName types.NamespacedName + ctx context.Context + ) + + BeforeEach(func() { + ctx = context.Background() + typeNamespacedName = types.NamespacedName{ + Name: "sm-test-fs", + Namespace: DefaultNs, + } + + featureStore = &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: typeNamespacedName.Name, + Namespace: typeNamespacedName.Namespace, + }, + Spec: feastdevv1.FeatureStoreSpec{ + FeastProject: "smtestproject", + Services: &feastdevv1.FeatureStoreServices{ + OnlineStore: &feastdevv1.OnlineStore{ + Server: &feastdevv1.ServerConfigs{ + ContainerConfigs: feastdevv1.ContainerConfigs{ + DefaultCtrConfigs: feastdevv1.DefaultCtrConfigs{ + Image: ptr.To("test-image"), + }, + }, + }, + }, + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + ServerConfigs: feastdevv1.ServerConfigs{ + ContainerConfigs: feastdevv1.ContainerConfigs{ + DefaultCtrConfigs: feastdevv1.DefaultCtrConfigs{ + Image: ptr.To("test-image"), + }, + }, + }, + GRPC: ptr.To(true), + }, + }, + }, + }, + }, + } + + Expect(k8sClient.Create(ctx, featureStore)).To(Succeed()) + + feast = &FeastServices{ + Handler: handler.FeastHandler{ + Client: k8sClient, + Context: ctx, + Scheme: k8sClient.Scheme(), + FeatureStore: featureStore, + }, + } + + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + }) + + AfterEach(func() { + testSetHasServiceMonitorCRD(false) + Expect(k8sClient.Delete(ctx, featureStore)).To(Succeed()) + }) + + Describe("initServiceMonitor", func() { + It("should create an unstructured ServiceMonitor with correct GVK and name", func() { + sm := feast.initServiceMonitor() + Expect(sm).NotTo(BeNil()) + Expect(sm.GetKind()).To(Equal("ServiceMonitor")) + Expect(sm.GetAPIVersion()).To(Equal("monitoring.coreos.com/v1")) + Expect(sm.GetName()).To(Equal(feast.GetFeastServiceName(OnlineFeastType))) + Expect(sm.GetNamespace()).To(Equal(featureStore.Namespace)) + }) + }) + + Describe("buildServiceMonitorApplyConfig", func() { + It("should build the correct SSA payload with labels, endpoints, selector, and owner reference", func() { + sm := feast.buildServiceMonitorApplyConfig() + + Expect(*sm.APIVersion).To(Equal("monitoring.coreos.com/v1")) + Expect(*sm.Kind).To(Equal("ServiceMonitor")) + Expect(*sm.Name).To(Equal(feast.GetFeastServiceName(OnlineFeastType))) + Expect(*sm.Namespace).To(Equal(featureStore.Namespace)) + + Expect(sm.Labels).To(HaveKeyWithValue(NameLabelKey, featureStore.Name)) + Expect(sm.Labels).To(HaveKeyWithValue(ServiceTypeLabelKey, string(OnlineFeastType))) + + Expect(sm.OwnerReferences).To(HaveLen(1)) + ownerRef := sm.OwnerReferences[0] + Expect(*ownerRef.APIVersion).To(Equal(feastdevv1.GroupVersion.String())) + Expect(*ownerRef.Kind).To(Equal("FeatureStore")) + Expect(*ownerRef.Name).To(Equal(featureStore.Name)) + Expect(*ownerRef.Controller).To(BeTrue()) + Expect(*ownerRef.BlockOwnerDeletion).To(BeTrue()) + + Expect(sm.Spec).NotTo(BeNil()) + Expect(sm.Spec.Endpoints).To(HaveLen(1)) + Expect(*sm.Spec.Endpoints[0].Port).To(Equal("metrics")) + Expect(*sm.Spec.Endpoints[0].Path).To(Equal("/metrics")) + + Expect(sm.Spec.Selector).NotTo(BeNil()) + Expect(sm.Spec.Selector.MatchLabels).To(HaveKeyWithValue(NameLabelKey, featureStore.Name)) + Expect(sm.Spec.Selector.MatchLabels).To(HaveKeyWithValue(ServiceTypeLabelKey, string(OnlineFeastType))) + }) + }) + + Describe("createOrDeleteServiceMonitor", func() { + It("should be a no-op when ServiceMonitor CRD is not available", func() { + testSetHasServiceMonitorCRD(false) + Expect(feast.createOrDeleteServiceMonitor()).To(Succeed()) + }) + + It("should not error when metrics is not enabled and CRD is unavailable", func() { + testSetHasServiceMonitorCRD(false) + featureStore.Status.Applied.Services.OnlineStore.Server.Metrics = ptr.To(false) + Expect(feast.createOrDeleteServiceMonitor()).To(Succeed()) + }) + }) + + Describe("HasServiceMonitorCRD", func() { + It("should return false by default", func() { + testSetHasServiceMonitorCRD(false) + Expect(HasServiceMonitorCRD()).To(BeFalse()) + }) + + It("should return true when set", func() { + testSetHasServiceMonitorCRD(true) + Expect(HasServiceMonitorCRD()).To(BeTrue()) + }) + }) +}) diff --git a/infra/feast-operator/internal/controller/services/services.go b/infra/feast-operator/internal/controller/services/services.go index fe8f3ecbc15..c6271c28d3a 100644 --- a/infra/feast-operator/internal/controller/services/services.go +++ b/infra/feast-operator/internal/controller/services/services.go @@ -32,6 +32,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" @@ -96,6 +97,9 @@ func (feast *FeastServices) Deploy() error { if err := feast.deployCronJob(); err != nil { return err } + if err := feast.createOrDeleteServiceMonitor(); err != nil { + return err + } return nil } @@ -381,10 +385,13 @@ func (feast *FeastServices) createPVC(pvcCreate *feastdevv1.PvcCreate, feastType } // PVCs are immutable, so we only create... we don't update an existing one. + // Treat AlreadyExists as success: a pre-existing PVC without the managed-by label + // won't appear in the filtered cache (Client.Get returns NotFound), but Create + // will hit AlreadyExists on the API server — both cases mean the PVC is present. err = feast.Handler.Client.Get(feast.Handler.Context, client.ObjectKeyFromObject(pvc), pvc) if err != nil && apierrors.IsNotFound(err) { err = feast.Handler.Client.Create(feast.Handler.Context, pvc) - if err != nil { + if err != nil && !apierrors.IsAlreadyExists(err) { return err } logger.Info("Successfully created", "PersistentVolumeClaim", pvc.Name) @@ -405,13 +412,15 @@ func (feast *FeastServices) setDeployment(deploy *appsv1.Deployment) error { } deploy.Labels = feast.getLabels() + selectorLabels := feast.getSelectorLabels() deploy.Spec = appsv1.DeploymentSpec{ Replicas: replicas, - Selector: metav1.SetAsLabelSelector(deploy.GetLabels()), + Selector: metav1.SetAsLabelSelector(selectorLabels), Strategy: feast.getDeploymentStrategy(), Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: deploy.GetLabels(), + Labels: deploy.GetLabels(), + Annotations: cr.Status.Applied.Services.PodAnnotations, }, Spec: corev1.PodSpec{ ServiceAccountName: feast.initFeastSA().Name, @@ -436,6 +445,7 @@ func (feast *FeastServices) setPod(podSpec *corev1.PodSpec) error { feast.applyNodeSelector(podSpec) feast.applyTopologySpread(podSpec) feast.applyAffinity(podSpec) + feast.applyResourceClaims(podSpec) return nil } @@ -495,7 +505,7 @@ func (feast *FeastServices) setContainer(containers *[]corev1.Container, feastTy }) if feastType == OnlineFeastType && feast.isMetricsEnabled(feastType) { container.Ports = append(container.Ports, corev1.ContainerPort{ - Name: "metrics", + Name: metricsPortName, ContainerPort: MetricsPort, Protocol: corev1.ProtocolTCP, }) @@ -587,7 +597,7 @@ func (feast *FeastServices) setRoute(route *routev1.Route, feastType FeastServic } func (feast *FeastServices) getContainerCommand(feastType FeastServiceType) []string { - baseCommand := "feast" + baseCommand := feastCommand options := []string{} logLevel := feast.getLogLevelForType(feastType) if logLevel != nil { @@ -596,7 +606,10 @@ func (feast *FeastServices) getContainerCommand(feastType FeastServiceType) []st deploySettings := FeastServiceConstants[feastType] deploySettings.Args = append([]string{}, deploySettings.Args...) - if feastType == OnlineFeastType && feast.isMetricsEnabled(feastType) { + // Only inject --metrics CLI flag for the server.metrics bool path. + // When serving.metrics.enabled is used, Python reads it from feature_store.yaml + // and starts the metrics server itself — no CLI flag needed. + if feastType == OnlineFeastType && feast.isMetricsEnabledViaCLI(feastType) { deploySettings.Args = append([]string{deploySettings.Args[0], "--metrics"}, deploySettings.Args[1:]...) } targetPort := deploySettings.TargetHttpPort @@ -675,7 +688,7 @@ func (feast *FeastServices) setInitContainer(podSpec *corev1.PodSpec, fsYamlB64 workingDir := getOfflineMountPath(feast.Handler.FeatureStore) projectPath := workingDir + "/" + applied.FeastProject container := corev1.Container{ - Name: "feast-init", + Name: feastInitContainerName, Image: getFeatureServerImage(), Env: []corev1.EnvVar{ { @@ -725,7 +738,47 @@ func (feast *FeastServices) setInitContainer(podSpec *corev1.PodSpec, fsYamlB64 "echo $" + TmpFeatureStoreYamlEnvVar + " | base64 -d \u003e " + featureRepoDir + "/feature_store.yaml;\necho \"Feast repo creation complete\";\n", } podSpec.InitContainers = append(podSpec.InitContainers, container) + + if applied.Services.RunFeastApplyOnInit != nil && *applied.Services.RunFeastApplyOnInit { + applyContainer := corev1.Container{ + Name: feastApplyContainerName, + Image: getFeatureServerImage(), + Command: []string{feastCommand, "apply"}, + WorkingDir: featureRepoDir, + } + // feast apply needs DB/store connectivity, so inherit env, envFrom + // and volume mounts from all server container configs. + seen := map[string]bool{} + for _, feastType := range []FeastServiceType{RegistryFeastType, OnlineFeastType, OfflineFeastType} { + if serverConfigs := feast.getServerConfigs(feastType); serverConfigs != nil { + if serverConfigs.OptionalCtrConfigs.Env != nil { + applyContainer.Env = envOverride(applyContainer.Env, *serverConfigs.OptionalCtrConfigs.Env) + } + if serverConfigs.OptionalCtrConfigs.EnvFrom != nil { + applyContainer.EnvFrom = append(applyContainer.EnvFrom, *serverConfigs.OptionalCtrConfigs.EnvFrom...) + } + for _, vm := range feast.getVolumeMounts(feastType) { + if !seen[vm.MountPath] { + applyContainer.VolumeMounts = append(applyContainer.VolumeMounts, vm) + seen[vm.MountPath] = true + } + } + } + } + podSpec.InitContainers = append(podSpec.InitContainers, applyContainer) + } + } +} + +// getServiceAppProtocol returns the appProtocol for a Service port. +// The registry gRPC service uses the gRPC protocol, which requires HTTP/2. +// Setting appProtocol allows service meshes (e.g. Istio) and load balancers +// to correctly classify the traffic and avoid downgrading to HTTP/1.1. +func (feast *FeastServices) getServiceAppProtocol(feastType FeastServiceType, isRestService bool) *string { + if feastType == RegistryFeastType && !isRestService && feast.isRegistryGrpcEnabled() { + return ptr.To("grpc") } + return nil } func (feast *FeastServices) setService(svc *corev1.Service, feastType FeastServiceType, isRestService bool) error { @@ -746,26 +799,26 @@ func (feast *FeastServices) setService(svc *corev1.Service, feastType FeastServi // The certificate will include both hostnames as SANs if !isRestService { grpcSvcName := feast.initFeastSvc(RegistryFeastType).Name - svc.Annotations["service.beta.openshift.io/serving-cert-secret-name"] = grpcSvcName + tlsNameSuffix + svc.Annotations[openshiftServingCertSecretAnnotation] = grpcSvcName + tlsNameSuffix // pragma: allowlist secret // Add Subject Alternative Names (SANs) for both services grpcHostname := grpcSvcName + "." + svc.Namespace + ".svc.cluster.local" restHostname := feast.GetFeastRestServiceName(RegistryFeastType) + "." + svc.Namespace + ".svc.cluster.local" - svc.Annotations["service.beta.openshift.io/serving-cert-sans"] = grpcHostname + "," + restHostname + svc.Annotations[openshiftServingCertSansAnnotation] = grpcHostname + "," + restHostname } // REST service should not have the annotation - it will use the same certificate // from the gRPC service secret (mounted in the pod) } else if grpcEnabled && !restEnabled { // Only gRPC enabled: Use gRPC service name grpcSvcName := feast.initFeastSvc(RegistryFeastType).Name - svc.Annotations["service.beta.openshift.io/serving-cert-secret-name"] = grpcSvcName + tlsNameSuffix + svc.Annotations[openshiftServingCertSecretAnnotation] = grpcSvcName + tlsNameSuffix // pragma: allowlist secret } else if !grpcEnabled && restEnabled { // Only REST enabled: Use REST service name - svc.Annotations["service.beta.openshift.io/serving-cert-secret-name"] = svc.Name + tlsNameSuffix + svc.Annotations[openshiftServingCertSecretAnnotation] = svc.Name + tlsNameSuffix // pragma: allowlist secret } } else { // Standard behavior for non-registry services - svc.Annotations["service.beta.openshift.io/serving-cert-secret-name"] = svc.Name + tlsNameSuffix + svc.Annotations[openshiftServingCertSecretAnnotation] = svc.Name + tlsNameSuffix // pragma: allowlist secret } } @@ -785,21 +838,22 @@ func (feast *FeastServices) setService(svc *corev1.Service, feastType FeastServi } svc.Spec = corev1.ServiceSpec{ - Selector: feast.getLabels(), + Selector: feast.getSelectorLabels(), Type: corev1.ServiceTypeClusterIP, Ports: []corev1.ServicePort{ { - Name: scheme, - Port: port, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(int(targetPort)), + Name: scheme, + Port: port, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(int(targetPort)), + AppProtocol: feast.getServiceAppProtocol(feastType, isRestService), }, }, } if feastType == OnlineFeastType && feast.isMetricsEnabled(feastType) { svc.Spec.Ports = append(svc.Spec.Ports, corev1.ServicePort{ - Name: "metrics", + Name: metricsPortName, Port: MetricsPort, Protocol: corev1.ProtocolTCP, TargetPort: intstr.FromInt(int(MetricsPort)), @@ -835,6 +889,7 @@ func (feast *FeastServices) setServiceAccount(sa *corev1.ServiceAccount) error { func (feast *FeastServices) createNewPVC(pvcCreate *feastdevv1.PvcCreate, feastType FeastServiceType) (*corev1.PersistentVolumeClaim, error) { pvc := feast.initPVC(feastType) + pvc.Labels = feast.getFeastTypeLabels(feastType) pvc.Spec = corev1.PersistentVolumeClaimSpec{ AccessModes: pvcCreate.AccessModes, @@ -881,14 +936,42 @@ func (feast *FeastServices) getWorkerConfigs(feastType FeastServiceType) *feastd return nil } -func (feast *FeastServices) isMetricsEnabled(feastType FeastServiceType) bool { +// isMetricsEnabledViaCLI returns true only when metrics are enabled via the +// server.metrics bool flag, which requires the --metrics CLI argument to be +// injected into the feast serve command. +func (feast *FeastServices) isMetricsEnabledViaCLI(feastType FeastServiceType) bool { if feastType != OnlineFeastType { return false } - if serviceConfigs := feast.getServerConfigs(feastType); serviceConfigs != nil && serviceConfigs.Metrics != nil { return *serviceConfigs.Metrics } + return false +} + +func (feast *FeastServices) isMetricsEnabled(feastType FeastServiceType) bool { + if feastType != OnlineFeastType { + return false + } + + // CLI flag path: server.metrics: true → adds --metrics arg + exposes port 8000. + // Only return true immediately; an explicit false must not suppress the YAML path. + if serviceConfigs := feast.getServerConfigs(feastType); serviceConfigs != nil && + serviceConfigs.Metrics != nil && *serviceConfigs.Metrics { + return true + } + + // YAML config path: serving.metrics.enabled: true → written into feature_store.yaml; + // Python reads it and starts the metrics server on port 8000 automatically. + // We still need to expose the port and Service so Prometheus can scrape it. + appliedSpec := feast.Handler.FeatureStore.Status.Applied + if appliedSpec.Services != nil && + appliedSpec.Services.OnlineStore != nil && + appliedSpec.Services.OnlineStore.Serving != nil && + appliedSpec.Services.OnlineStore.Serving.Metrics != nil && + appliedSpec.Services.OnlineStore.Serving.Metrics.Enabled { + return true + } return false } @@ -943,7 +1026,7 @@ func (feast *FeastServices) applyTopologySpread(podSpec *corev1.PodSpec) { MaxSkew: 1, TopologyKey: "topology.kubernetes.io/zone", WhenUnsatisfiable: corev1.ScheduleAnyway, - LabelSelector: metav1.SetAsLabelSelector(feast.getLabels()), + LabelSelector: metav1.SetAsLabelSelector(feast.getSelectorLabels()), }} } @@ -966,13 +1049,20 @@ func (feast *FeastServices) applyAffinity(podSpec *corev1.PodSpec) { Weight: 100, PodAffinityTerm: corev1.PodAffinityTerm{ TopologyKey: "kubernetes.io/hostname", - LabelSelector: metav1.SetAsLabelSelector(feast.getLabels()), + LabelSelector: metav1.SetAsLabelSelector(feast.getSelectorLabels()), }, }}, }, } } +func (feast *FeastServices) applyResourceClaims(podSpec *corev1.PodSpec) { + services := feast.Handler.FeatureStore.Status.Applied.Services + if services != nil && len(services.ResourceClaims) > 0 { + podSpec.ResourceClaims = services.ResourceClaims + } +} + // mergeNodeSelectors merges existing and operator node selectors // Existing selectors are preserved, operator selectors can override existing keys func (feast *FeastServices) mergeNodeSelectors(existing, operator map[string]string) map[string]string { @@ -1027,12 +1117,24 @@ func (feast *FeastServices) getFeastTypeLabels(feastType FeastServiceType) map[s return labels } -func (feast *FeastServices) getLabels() map[string]string { +// getSelectorLabels returns the minimal label set used for immutable selectors +// (Deployment spec.selector, Service spec.selector, TopologySpreadConstraints, PodAffinity). +// This must NOT change after initial resource creation. +func (feast *FeastServices) getSelectorLabels() map[string]string { return map[string]string{ NameLabelKey: feast.Handler.FeatureStore.Name, } } +// getLabels returns the full label set for mutable metadata (ObjectMeta.Labels). +// Includes the managed-by label used by the informer cache filter. +func (feast *FeastServices) getLabels() map[string]string { + return map[string]string{ + NameLabelKey: feast.Handler.FeatureStore.Name, + ManagedByLabelKey: ManagedByLabelValue, + } +} + func (feast *FeastServices) setServiceHostnames() error { feast.Handler.FeatureStore.Status.ServiceHostnames = feastdevv1.ServiceHostnames{} domain := svcDomain + ":" @@ -1072,13 +1174,12 @@ func (feast *FeastServices) setFeastServiceCondition(err error, feastType FeastS if err != nil { logger := log.FromContext(feast.Handler.Context) cond := conditionMap[metav1.ConditionFalse] - cond.Message = "Error: " + err.Error() + cond.Message = ErrorMessagePrefix + err.Error() apimeta.SetStatusCondition(&feast.Handler.FeatureStore.Status.Conditions, cond) logger.Error(err, "Error deploying the FeatureStore "+string(ClientFeastType)+" service") return err - } else { - apimeta.SetStatusCondition(&feast.Handler.FeatureStore.Status.Conditions, conditionMap[metav1.ConditionTrue]) } + apimeta.SetStatusCondition(&feast.Handler.FeatureStore.Status.Conditions, conditionMap[metav1.ConditionTrue]) return nil } @@ -1122,9 +1223,6 @@ func (feast *FeastServices) getRemoteRegistryFeastHandler() (*FeastServices, err } return nil, err } - if feast.Handler.FeatureStore.Status.Applied.FeastProject != remoteFeastObj.Status.Applied.FeastProject { - return nil, errors.New("FeatureStore '" + remoteFeastObj.Name + "' is using a different feast project than '" + feast.Handler.FeatureStore.Status.Applied.FeastProject + "'. Project names must match.") - } return &FeastServices{ Handler: handler.FeastHandler{ Client: feast.Handler.Client, @@ -1282,13 +1380,11 @@ func (feast *FeastServices) mountPvcConfig(podSpec *corev1.PodSpec, pvcConfig *f }, }, }) - if feastType == OfflineFeastType { - for i := range podSpec.InitContainers { - podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, corev1.VolumeMount{ - Name: volName, - MountPath: pvcConfig.MountPath, - }) - } + for i := range podSpec.InitContainers { + podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, corev1.VolumeMount{ + Name: volName, + MountPath: pvcConfig.MountPath, + }) } for i := range podSpec.Containers { podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, corev1.VolumeMount{ @@ -1405,6 +1501,67 @@ func IsDeploymentAvailable(conditions []appsv1.DeploymentCondition) bool { return false } +// GetPodContainerFailureMessage inspects pods belonging to the given deployment +// and returns a human-readable message describing the first init or regular +// container that is in a failing state. Returns empty string if no failure found. +func (feast *FeastServices) GetPodContainerFailureMessage(deploy appsv1.Deployment) string { + podList := corev1.PodList{} + selectorLabels := feast.getSelectorLabels() + if err := feast.Handler.Client.List(feast.Handler.Context, &podList, + client.InNamespace(deploy.Namespace), + client.MatchingLabels(selectorLabels), + ); err != nil { + return "" + } + for i := range podList.Items { + pod := &podList.Items[i] + if msg := initContainerFailureMessage(pod); msg != "" { + return msg + } + if msg := containerFailureMessage(pod); msg != "" { + return msg + } + } + return "" +} + +func initContainerFailureMessage(pod *corev1.Pod) string { + for _, cs := range pod.Status.InitContainerStatuses { + if cs.State.Waiting != nil && cs.State.Waiting.Reason != "" && cs.State.Waiting.Reason != "PodInitializing" { + return "Init container '" + cs.Name + "' waiting: " + cs.State.Waiting.Reason + + messageIfPresent(cs.State.Waiting.Message) + } + if cs.State.Terminated != nil && cs.State.Terminated.ExitCode != 0 { + return "Init container '" + cs.Name + "' failed with exit code " + + strconv.Itoa(int(cs.State.Terminated.ExitCode)) + + messageIfPresent(cs.State.Terminated.Message) + } + } + return "" +} + +func containerFailureMessage(pod *corev1.Pod) string { + for _, cs := range pod.Status.ContainerStatuses { + if cs.State.Waiting != nil && cs.State.Waiting.Reason != "" && cs.State.Waiting.Reason != "ContainerCreating" { + return "Container '" + cs.Name + "' waiting: " + cs.State.Waiting.Reason + + messageIfPresent(cs.State.Waiting.Message) + } + if cs.State.Terminated != nil && cs.State.Terminated.ExitCode != 0 { + return "Container '" + cs.Name + "' failed with exit code " + + strconv.Itoa(int(cs.State.Terminated.ExitCode)) + + messageIfPresent(cs.State.Terminated.Message) + } + } + return "" +} + +func messageIfPresent(msg string) string { + if msg != "" { + return " - " + msg + } + return "" +} + // GetFeastRestServiceName returns the feast REST service object name based on service type func (feast *FeastServices) GetFeastRestServiceName(feastType FeastServiceType) string { return feast.GetFeastServiceName(feastType) + "-rest" diff --git a/infra/feast-operator/internal/controller/services/services_test.go b/infra/feast-operator/internal/controller/services/services_test.go index d53caa3e25f..da3590674f1 100644 --- a/infra/feast-operator/internal/controller/services/services_test.go +++ b/infra/feast-operator/internal/controller/services/services_test.go @@ -63,7 +63,7 @@ var _ = Describe("Registry Service", func() { ctx = context.Background() typeNamespacedName = types.NamespacedName{ Name: "testfeaturestore", - Namespace: "default", + Namespace: DefaultNs, } featureStore = &feastdevv1.FeatureStore{ @@ -202,12 +202,135 @@ var _ = Describe("Registry Service", func() { }) }) + Describe("PodAnnotations Configuration", func() { + It("should apply podAnnotations to deployment pod template", func() { + featureStore.Spec.Services.PodAnnotations = map[string]string{ + otelInjectPythonAnnotation: stringTrue, + "sidecar.istio.io/inject": stringTrue, + } + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + + Expect(deployment.Spec.Template.Annotations).To(Equal(map[string]string{ + otelInjectPythonAnnotation: stringTrue, + "sidecar.istio.io/inject": stringTrue, + })) + }) + + It("should have no pod template annotations when podAnnotations is not set", func() { + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + + Expect(deployment.Spec.Template.Annotations).To(BeNil()) + }) + + It("should remove pod template annotations when podAnnotations is removed", func() { + featureStore.Spec.Services.PodAnnotations = map[string]string{ + otelInjectPythonAnnotation: stringTrue, + } + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + Expect(deployment.Spec.Template.Annotations).To(HaveKey("instrumentation.opentelemetry.io/inject-python")) + + featureStore.Spec.Services.PodAnnotations = nil + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + Expect(feast.setDeployment(deployment)).To(Succeed()) + Expect(deployment.Spec.Template.Annotations).To(BeNil()) + }) + }) + + Describe("ResourceClaims Configuration", func() { + It("should apply resourceClaims to deployment pod template", func() { + featureStore.Spec.Services.ResourceClaims = []corev1.PodResourceClaim{ + { + Name: "gpu-claim", + ResourceClaimName: ptr.To("my-gpu-claim"), + }, + } + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + + Expect(deployment.Spec.Template.Spec.ResourceClaims).To(Equal([]corev1.PodResourceClaim{ + { + Name: "gpu-claim", + ResourceClaimName: ptr.To("my-gpu-claim"), + }, + })) + }) + + It("should have no resourceClaims when field is not set", func() { + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + + Expect(deployment.Spec.Template.Spec.ResourceClaims).To(BeNil()) + }) + + It("should remove resourceClaims when field is removed", func() { + featureStore.Spec.Services.ResourceClaims = []corev1.PodResourceClaim{ + { + Name: "gpu-claim", + ResourceClaimName: ptr.To("my-gpu-claim"), + }, + } + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + deployment := feast.initFeastDeploy() + Expect(deployment).NotTo(BeNil()) + Expect(feast.setDeployment(deployment)).To(Succeed()) + Expect(deployment.Spec.Template.Spec.ResourceClaims).To(HaveLen(1)) + + featureStore.Spec.Services.ResourceClaims = nil + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + feast.refreshFeatureStore(ctx, typeNamespacedName) + + Expect(feast.setDeployment(deployment)).To(Succeed()) + Expect(deployment.Spec.Template.Spec.ResourceClaims).To(BeNil()) + }) + }) + Describe("NodeSelector Configuration", func() { It("should apply NodeSelector to pod spec when configured", func() { // Set NodeSelector for registry service nodeSelector := map[string]string{ - "kubernetes.io/os": "linux", - "node-type": "compute", + kubernetesOsLabel: linuxOS, + nodeTypeLabel: computeNodeType, } featureStore.Spec.Services.Registry.Local.Server.ContainerConfigs.OptionalCtrConfigs.NodeSelector = &nodeSelector Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) @@ -222,8 +345,8 @@ var _ = Describe("Registry Service", func() { // Verify NodeSelector is applied to pod spec expectedNodeSelector := map[string]string{ - "kubernetes.io/os": "linux", - "node-type": "compute", + kubernetesOsLabel: linuxOS, + nodeTypeLabel: computeNodeType, } Expect(deployment.Spec.Template.Spec.NodeSelector).To(Equal(expectedNodeSelector)) }) @@ -231,15 +354,15 @@ var _ = Describe("Registry Service", func() { It("should merge NodeSelectors from multiple services", func() { // Set NodeSelector for registry service registryNodeSelector := map[string]string{ - "kubernetes.io/os": "linux", - "node-type": "compute", + kubernetesOsLabel: linuxOS, + nodeTypeLabel: computeNodeType, } featureStore.Spec.Services.Registry.Local.Server.ContainerConfigs.OptionalCtrConfigs.NodeSelector = ®istryNodeSelector // Set NodeSelector for online store service onlineNodeSelector := map[string]string{ - "node-type": "online", - "zone": "us-west-1a", + nodeTypeLabel: "online", + zoneLabel: "us-west-1a", } featureStore.Spec.Services.OnlineStore = &feastdevv1.OnlineStore{ Server: &feastdevv1.ServerConfigs{ @@ -266,9 +389,9 @@ var _ = Describe("Registry Service", func() { // Verify NodeSelector merges all service selectors (online overrides registry for node-type) expectedNodeSelector := map[string]string{ - "kubernetes.io/os": "linux", - "node-type": "online", - "zone": "us-west-1a", + kubernetesOsLabel: linuxOS, + "node-type": "online", + zoneLabel: "us-west-1a", } Expect(deployment.Spec.Template.Spec.NodeSelector).To(Equal(expectedNodeSelector)) }) @@ -323,7 +446,7 @@ var _ = Describe("Registry Service", func() { It("should apply UI service NodeSelector when UI has highest precedence", func() { // Set NodeSelector for online service onlineNodeSelector := map[string]string{ - "node-type": "online", + nodeTypeLabel: "online", } featureStore.Spec.Services.OnlineStore = &feastdevv1.OnlineStore{ Server: &feastdevv1.ServerConfigs{ @@ -390,15 +513,15 @@ var _ = Describe("Registry Service", func() { onlineContainer := GetOnlineContainer(*deployment) Expect(onlineContainer).NotTo(BeNil()) - Expect(onlineContainer.Command).To(Equal([]string{"feast", "serve", "--metrics", "-h", "0.0.0.0", "-p", "6566"})) + Expect(onlineContainer.Command).To(Equal([]string{feastCommand, "serve", "--metrics", "-h", hostAllIPv4, "-p", "6566"})) Expect(onlineContainer.Ports).To(ContainElement(corev1.ContainerPort{ - Name: "metrics", + Name: metricsPortName, ContainerPort: MetricsPort, Protocol: corev1.ProtocolTCP, })) metricsPortCount := 0 for _, port := range onlineContainer.Ports { - if port.Name == "metrics" { + if port.Name == metricsPortName { metricsPortCount++ } } @@ -573,3 +696,231 @@ var _ = Describe("Registry Service", func() { }) }) }) + +var _ = Describe("Service AppProtocol Configuration", func() { + var ( + featureStore *feastdevv1.FeatureStore + feast *FeastServices + ctx context.Context + ) + + BeforeEach(func() { + ctx = context.Background() + featureStore = &feastdevv1.FeatureStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testfeaturestore-approtocol", + Namespace: DefaultNs, + }, + Spec: feastdevv1.FeatureStoreSpec{ + FeastProject: "testproject", + Services: &feastdevv1.FeatureStoreServices{ + Registry: &feastdevv1.Registry{ + Local: &feastdevv1.LocalRegistryConfig{ + Server: &feastdevv1.RegistryServerConfigs{ + ServerConfigs: feastdevv1.ServerConfigs{ + ContainerConfigs: feastdevv1.ContainerConfigs{ + DefaultCtrConfigs: feastdevv1.DefaultCtrConfigs{ + Image: ptr.To("test-image"), + }, + }, + }, + GRPC: ptr.To(true), + RestAPI: ptr.To(false), + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, featureStore)).To(Succeed()) + applySpecToStatus(featureStore) + feast = &FeastServices{ + Handler: handler.FeastHandler{ + Client: k8sClient, + Context: ctx, + Scheme: k8sClient.Scheme(), + FeatureStore: featureStore, + }, + } + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + }) + + AfterEach(func() { + Expect(k8sClient.Delete(ctx, featureStore)).To(Succeed()) + }) + + It("should return grpc appProtocol for the registry gRPC service", func() { + Expect(feast.isRegistryGrpcEnabled()).To(BeTrue()) + Expect(feast.getServiceAppProtocol(RegistryFeastType, false)).To(Equal(ptr.To("grpc"))) + }) + + It("should return nil appProtocol for the registry REST service", func() { + featureStore.Spec.Services.Registry.Local.Server.RestAPI = ptr.To(true) + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + + Expect(feast.getServiceAppProtocol(RegistryFeastType, true)).To(BeNil()) + }) + + It("should return nil appProtocol for the online store service", func() { + Expect(feast.getServiceAppProtocol(OnlineFeastType, false)).To(BeNil()) + }) + + It("should return nil appProtocol for the offline store service", func() { + Expect(feast.getServiceAppProtocol(OfflineFeastType, false)).To(BeNil()) + }) + + It("should return nil appProtocol when registry gRPC is disabled", func() { + featureStore.Spec.Services.Registry.Local.Server.GRPC = ptr.To(false) + featureStore.Spec.Services.Registry.Local.Server.RestAPI = ptr.To(true) + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + + Expect(feast.isRegistryGrpcEnabled()).To(BeFalse()) + Expect(feast.getServiceAppProtocol(RegistryFeastType, false)).To(BeNil()) + }) + + It("should set grpc appProtocol on the registry gRPC Service port", func() { + Expect(feast.deployFeastServiceByType(RegistryFeastType)).To(Succeed()) + svc := feast.initFeastSvc(RegistryFeastType) + Expect(svc).NotTo(BeNil()) + Expect(feast.setService(svc, RegistryFeastType, false)).To(Succeed()) + + Expect(svc.Spec.Ports).To(HaveLen(1)) + Expect(svc.Spec.Ports[0].AppProtocol).To(Equal(ptr.To("grpc"))) + }) + + It("should not set appProtocol on the registry REST Service port", func() { + featureStore.Spec.Services.Registry.Local.Server.RestAPI = ptr.To(true) + Expect(k8sClient.Update(ctx, featureStore)).To(Succeed()) + Expect(feast.ApplyDefaults()).To(Succeed()) + applySpecToStatus(featureStore) + + Expect(feast.deployFeastServiceByType(RegistryFeastType)).To(Succeed()) + restSvc := feast.initFeastRestSvc(RegistryFeastType) + Expect(restSvc).NotTo(BeNil()) + Expect(feast.setService(restSvc, RegistryFeastType, true)).To(Succeed()) + + Expect(restSvc.Spec.Ports).To(HaveLen(1)) + Expect(restSvc.Spec.Ports[0].AppProtocol).To(BeNil()) + }) +}) + +var _ = Describe("Pod Container Failure Messages", func() { + It("should detect init container in CrashLoopBackOff", func() { + pod := &corev1.Pod{ + Status: corev1.PodStatus{ + InitContainerStatuses: []corev1.ContainerStatus{ + { + Name: feastInitContainerName, + State: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ExitCode: 0}, + }, + }, + { + Name: feastApplyContainerName, + State: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "CrashLoopBackOff", + Message: "back-off 5m0s restarting failed container", + }, + }, + }, + }, + }, + } + msg := initContainerFailureMessage(pod) + Expect(msg).To(ContainSubstring("feast-apply")) + Expect(msg).To(ContainSubstring("CrashLoopBackOff")) + Expect(msg).To(ContainSubstring("back-off 5m0s")) + }) + + It("should detect init container terminated with non-zero exit code", func() { + pod := &corev1.Pod{ + Status: corev1.PodStatus{ + InitContainerStatuses: []corev1.ContainerStatus{ + { + Name: feastApplyContainerName, + State: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + ExitCode: 1, + Message: "feast apply failed", + }, + }, + }, + }, + }, + } + msg := initContainerFailureMessage(pod) + Expect(msg).To(ContainSubstring("feast-apply")) + Expect(msg).To(ContainSubstring("exit code 1")) + Expect(msg).To(ContainSubstring("feast apply failed")) + }) + + It("should return empty for init containers still initializing", func() { + pod := &corev1.Pod{ + Status: corev1.PodStatus{ + InitContainerStatuses: []corev1.ContainerStatus{ + { + Name: feastInitContainerName, + State: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "PodInitializing", + }, + }, + }, + }, + }, + } + Expect(initContainerFailureMessage(pod)).To(BeEmpty()) + }) + + It("should detect regular container failure", func() { + pod := &corev1.Pod{ + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: registryName, + State: corev1.ContainerState{ + Waiting: &corev1.ContainerStateWaiting{ + Reason: "ImagePullBackOff", + Message: "image not found", + }, + }, + }, + }, + }, + } + msg := containerFailureMessage(pod) + Expect(msg).To(ContainSubstring("registry")) + Expect(msg).To(ContainSubstring("ImagePullBackOff")) + }) + + It("should return empty for healthy pods", func() { + pod := &corev1.Pod{ + Status: corev1.PodStatus{ + InitContainerStatuses: []corev1.ContainerStatus{ + { + Name: feastInitContainerName, + State: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ExitCode: 0}, + }, + }, + }, + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: registryName, + State: corev1.ContainerState{ + Running: &corev1.ContainerStateRunning{}, + }, + }, + }, + }, + } + Expect(initContainerFailureMessage(pod)).To(BeEmpty()) + Expect(containerFailureMessage(pod)).To(BeEmpty()) + }) +}) diff --git a/infra/feast-operator/internal/controller/services/services_types.go b/infra/feast-operator/internal/controller/services/services_types.go index 10ac3538a99..366f0c8d765 100644 --- a/infra/feast-operator/internal/controller/services/services_types.go +++ b/infra/feast-operator/internal/controller/services/services_types.go @@ -48,8 +48,17 @@ const ( tlsPathCustomCABundle = "/etc/pki/tls/custom-certs/ca-bundle.crt" tlsNameSuffix = "-tls" - caBundleAnnotation = "config.openshift.io/inject-trusted-cabundle" - caBundleName = "odh-trusted-ca-bundle" + caBundleAnnotation = "config.openshift.io/inject-trusted-cabundle" + caBundleName = "odh-trusted-ca-bundle" + odhCaBundleKey = "odh-ca-bundle.crt" + tlsPathOdhCABundle = "/etc/pki/tls/custom-certs/odh-ca-bundle.crt" + tlsPathOidcCA = "/etc/pki/tls/oidc-ca/ca.crt" + oidcCaVolumeName = "oidc-ca-cert" + defaultCACertKey = "ca-bundle.crt" + openshiftServingCertSecretAnnotation = "service.beta.openshift.io/serving-cert-secret-name" // pragma: allowlist secret + openshiftServingCertSansAnnotation = "service.beta.openshift.io/serving-cert-sans" + openshiftInjectCaBundleAnnotation = "service.beta.openshift.io/inject-cabundle" + ErrorMessagePrefix = "Error: " DefaultOfflineStorageRequest = "20Gi" DefaultOnlineStorageRequest = "5Gi" @@ -91,8 +100,57 @@ const ( OidcClientSecret OidcPropertyType = "client_secret" OidcUsername OidcPropertyType = "username" OidcPassword OidcPropertyType = "password" + OidcTokenEnvVar OidcPropertyType = "token_env_var" + OidcVerifySsl OidcPropertyType = "verify_ssl" + OidcCaCertPath OidcPropertyType = "ca_cert_path" OidcMissingSecretError string = "missing OIDC secret: %s" + + // Common string constants + stringTrue = "true" + stringFalse = "false" + hostAllIPv4 = "0.0.0.0" + tlsCertKey = "tls.crt" + DefaultNs = "default" + feastCommand = "feast" + metricsPortName = "metrics" + registryName = "registry" + feastInitContainerName = "feast-init" + feastApplyContainerName = "feast-apply" + + // Test-specific constants + dataOnlineDbPath = "/data/online.db" + dataRegistryDbPath = "/data/registry.db" + oidcSecretName = "oidc-secret" // pragma: allowlist secret + clientIDValue = "client-id" + lineageSecretName = "lineage-secret" // pragma: allowlist secret + redisType = "redis" + redisSecretName = "redis-secret" // pragma: allowlist secret + registrySecretName = "registry-secret" // pragma: allowlist secret + celTestProject = "celtest" + kubernetesHostnameTopologyKey = "kubernetes.io/hostname" + dailyMidnightCron = "0 0 * * *" + otelInjectPythonAnnotation = "instrumentation.opentelemetry.io/inject-python" + kubernetesOsLabel = "kubernetes.io/os" + computeNodeType = "compute" + nodeTypeLabel = "node-type" + zoneLabel = "zone" + linuxOS = "linux" + TestValue = "test" + OfflineStoreSecretName = "offline-store-secret" // pragma: allowlist secret + OnlineStoreSecretName = "online-store-secret" // pragma: allowlist secret + RegistryStoreSecretName = "registry-store-secret" // pragma: allowlist secret + FieldRefName = "fieldRefName" + ConfigOne = "config-1" + MetadataNameField = "metadata.name" + GrpcFlag = "--grpc" + ExampleConfigMapName = "example-configmap" + ExampleSecretName = "example-secret" // pragma: allowlist secret +) + +const ( + ManagedByLabelKey = "app.kubernetes.io/managed-by" + ManagedByLabelValue = "feast-operator" ) var ( @@ -104,12 +162,12 @@ var ( FeastServiceConstants = map[FeastServiceType]deploymentSettings{ OfflineFeastType: { - Args: []string{"serve_offline", "-h", "0.0.0.0"}, + Args: []string{"serve_offline", "-h", hostAllIPv4}, TargetHttpPort: 8815, TargetHttpsPort: 8816, }, OnlineFeastType: { - Args: []string{"serve", "-h", "0.0.0.0"}, + Args: []string{"serve", "-h", hostAllIPv4}, TargetHttpPort: 6566, TargetHttpsPort: 6567, }, @@ -208,9 +266,7 @@ var ( }, } - OidcServerProperties = []OidcPropertyType{OidcClientId, OidcAuthDiscoveryUrl} - OidcClientProperties = []OidcPropertyType{OidcClientSecret, OidcUsername, OidcPassword} - OidcProperties = []OidcPropertyType{OidcClientId, OidcAuthDiscoveryUrl, OidcClientSecret, OidcUsername, OidcPassword} + OidcOptionalSecretProperties = []OidcPropertyType{OidcAuthDiscoveryUrl, OidcClientId, OidcClientSecret, OidcUsername, OidcPassword} ) // Feast server types: Reserved only for server types like Online, Offline, and Registry servers. Should not be used for client types like the UI, etc. @@ -249,14 +305,69 @@ type FeastServices struct { // RepoConfig is the Repo config. Typically loaded from feature_store.yaml. // https://rtd.feast.dev/en/stable/#feast.repo_config.RepoConfig type RepoConfig struct { - Project string `yaml:"project,omitempty"` - Provider FeastProviderType `yaml:"provider,omitempty"` - OfflineStore OfflineStoreConfig `yaml:"offline_store,omitempty"` - OnlineStore OnlineStoreConfig `yaml:"online_store,omitempty"` - Registry RegistryConfig `yaml:"registry,omitempty"` - AuthzConfig AuthzConfig `yaml:"auth,omitempty"` - EntityKeySerializationVersion int `yaml:"entity_key_serialization_version,omitempty"` - BatchEngine *ComputeEngineConfig `yaml:"batch_engine,omitempty"` + Project string `yaml:"project,omitempty"` + Provider FeastProviderType `yaml:"provider,omitempty"` + OfflineStore OfflineStoreConfig `yaml:"offline_store,omitempty"` + OnlineStore OnlineStoreConfig `yaml:"online_store,omitempty"` + Registry RegistryConfig `yaml:"registry,omitempty"` + AuthzConfig AuthzConfig `yaml:"auth,omitempty"` + EntityKeySerializationVersion int `yaml:"entity_key_serialization_version,omitempty"` + BatchEngine *ComputeEngineConfig `yaml:"batch_engine,omitempty"` + FeatureServer *FeatureServerYamlConfig `yaml:"feature_server,omitempty"` + Materialization *MaterializationYamlConfig `yaml:"materialization,omitempty"` + OpenLineage *OpenLineageYamlConfig `yaml:"openlineage,omitempty"` + DataQualityMonitoring *DataQualityMonitoringYamlConfig `yaml:"data_quality_monitoring,omitempty"` +} + +// FeatureServerYamlConfig maps to the feature_server section of feature_store.yaml. +// Field names match Feast's Python SDK YAML keys exactly. +type FeatureServerYamlConfig struct { + Type string `yaml:"type"` + Metrics *MetricsYamlConfig `yaml:"metrics,omitempty"` + OfflinePushBatchingEnabled *bool `yaml:"offline_push_batching_enabled,omitempty"` + OfflinePushBatchingBatchSize *int32 `yaml:"offline_push_batching_batch_size,omitempty"` + OfflinePushBatchingBatchIntervalSeconds *int32 `yaml:"offline_push_batching_batch_interval_seconds,omitempty"` + McpEnabled *bool `yaml:"mcp_enabled,omitempty"` + McpServerName *string `yaml:"mcp_server_name,omitempty"` + McpServerVersion *string `yaml:"mcp_server_version,omitempty"` + McpTransport *string `yaml:"mcp_transport,omitempty"` +} + +// MetricsYamlConfig maps to the feature_server.metrics section of feature_store.yaml. +// Category booleans are merged inline so they sit at the same YAML level as +// "enabled". Keys must be valid Feast MetricsConfig field names for the SDK +// version in use (e.g. resource, request, online_features, push, +// materialization, freshness). Note: Feast's MetricsConfig uses +// extra="forbid", so unknown keys will be rejected by SDK validation. +type MetricsYamlConfig struct { + Enabled bool `yaml:"enabled"` + Categories map[string]interface{} `yaml:",inline,omitempty"` +} + +// DataQualityMonitoringYamlConfig mirrors the Python DqmConfig in feature_store.yaml. +type DataQualityMonitoringYamlConfig struct { + AutoBaseline bool `yaml:"auto_baseline"` +} + +// MaterializationYamlConfig maps to the materialization section of feature_store.yaml. +// ExtraConfig is merged inline so future Feast MaterializationConfig fields appear +// at the same YAML level as the typed fields above. +type MaterializationYamlConfig struct { + OnlineWriteBatchSize *int32 `yaml:"online_write_batch_size,omitempty"` + ExtraConfig map[string]interface{} `yaml:",inline,omitempty"` +} + +// OpenLineageYamlConfig maps to the openlineage section of feature_store.yaml. +// ExtraConfig is merged inline so all extra key-value pairs (namespace, producer, +// emit_on_apply, emit_on_materialize, transport-specific options, etc.) appear at +// the same YAML level as the typed connection fields. +type OpenLineageYamlConfig struct { + Enabled bool `yaml:"enabled"` + TransportType *string `yaml:"transport_type,omitempty"` + TransportUrl *string `yaml:"transport_url,omitempty"` + TransportEndpoint *string `yaml:"transport_endpoint,omitempty"` + ApiKey *string `yaml:"api_key,omitempty"` + ExtraConfig map[string]interface{} `yaml:",inline,omitempty"` } // OfflineStoreConfig is the configuration that relates to reading from and writing to the Feast offline store. @@ -285,9 +396,15 @@ type RegistryConfig struct { S3AdditionalKwargs *map[string]string `yaml:"s3_additional_kwargs,omitempty"` CacheTTLSeconds *int32 `yaml:"cache_ttl_seconds,omitempty"` CacheMode *string `yaml:"cache_mode,omitempty"` + Mcp *RegistryMcpYamlConfig `yaml:"mcp,omitempty"` DBParameters map[string]interface{} `yaml:",inline,omitempty"` } +// RegistryMcpYamlConfig maps to the registry.mcp section of feature_store.yaml. +type RegistryMcpYamlConfig struct { + Enabled bool `yaml:"enabled"` +} + // AuthzConfig is the RBAC authorization configuration. type AuthzConfig struct { Type AuthzType `yaml:"type,omitempty"` diff --git a/infra/feast-operator/internal/controller/services/suite_test.go b/infra/feast-operator/internal/controller/services/suite_test.go index a3d5bb3dae8..de1b75817ef 100644 --- a/infra/feast-operator/internal/controller/services/suite_test.go +++ b/infra/feast-operator/internal/controller/services/suite_test.go @@ -88,3 +88,7 @@ var _ = AfterSuite(func() { func testSetIsOpenShift() { isOpenShift = true } + +func testSetHasServiceMonitorCRD(val bool) { + hasServiceMonitorCRD = val +} diff --git a/infra/feast-operator/internal/controller/services/tls.go b/infra/feast-operator/internal/controller/services/tls.go index 4a50697c5a1..a3a5493ba5b 100644 --- a/infra/feast-operator/internal/controller/services/tls.go +++ b/infra/feast-operator/internal/controller/services/tls.go @@ -210,6 +210,10 @@ func (feast *FeastServices) mountTlsConfigs(podSpec *corev1.PodSpec) { feast.mountTlsConfig(OnlineFeastType, podSpec) feast.mountTlsConfig(UIFeastType, podSpec) feast.mountCustomCABundle(podSpec) + appliedSpec := feast.Handler.FeatureStore.Status.Applied + if appliedSpec.AuthzConfig != nil && appliedSpec.AuthzConfig.OidcAuthz != nil { + feast.mountOidcCACert(podSpec, appliedSpec.AuthzConfig.OidcAuthz) + } } func (feast *FeastServices) mountTlsConfig(feastType FeastServiceType, podSpec *corev1.PodSpec) { @@ -224,12 +228,16 @@ func (feast *FeastServices) mountTlsConfig(feastType FeastServiceType, podSpec * }, }, }) + tlsMount := corev1.VolumeMount{ + Name: volName, + MountPath: GetTlsPath(feastType), + ReadOnly: true, + } if i, container := getContainerByType(feastType, *podSpec); container != nil { - podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, corev1.VolumeMount{ - Name: volName, - MountPath: GetTlsPath(feastType), - ReadOnly: true, - }) + podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, tlsMount) + } + for i := range podSpec.InitContainers { + podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, tlsMount) } } } @@ -245,12 +253,16 @@ func mountTlsRemoteRegistryConfig(podSpec *corev1.PodSpec, tls *feastdevv1.TlsRe }, }, }) + tlsMount := corev1.VolumeMount{ + Name: volName, + MountPath: GetTlsPath(RegistryFeastType), + ReadOnly: true, + } for i := range podSpec.Containers { - podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, corev1.VolumeMount{ - Name: volName, - MountPath: GetTlsPath(RegistryFeastType), - ReadOnly: true, - }) + podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, tlsMount) + } + for i := range podSpec.InitContainers { + podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, tlsMount) } } } @@ -267,24 +279,69 @@ func (feast *FeastServices) mountCustomCABundle(podSpec *corev1.PodSpec) { }, }) + caMount := corev1.VolumeMount{ + Name: customCaBundle.VolumeName, + MountPath: tlsPathCustomCABundle, + ReadOnly: true, + SubPath: "ca-bundle.crt", + } + odhCaMount := corev1.VolumeMount{ + Name: customCaBundle.VolumeName, + MountPath: tlsPathOdhCABundle, + ReadOnly: true, + SubPath: odhCaBundleKey, + } for i := range podSpec.Containers { - podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, corev1.VolumeMount{ - Name: customCaBundle.VolumeName, - MountPath: tlsPathCustomCABundle, - ReadOnly: true, - SubPath: "ca-bundle.crt", - }) + podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, caMount, odhCaMount) + } + for i := range podSpec.InitContainers { + podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, caMount, odhCaMount) } log.FromContext(feast.Handler.Context).Info("Mounted custom CA bundle ConfigMap to Feast pods.") } } +func (feast *FeastServices) mountOidcCACert(podSpec *corev1.PodSpec, oidcAuthz *feastdevv1.OidcAuthz) { + if oidcAuthz.CACertConfigMap == nil { + return + } + cmName := oidcAuthz.CACertConfigMap.Name + cmKey := oidcAuthz.CACertConfigMap.Key + if cmKey == "" { + cmKey = defaultCACertKey + } + + podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{ + Name: oidcCaVolumeName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: cmName}, + }, + }, + }) + + mount := corev1.VolumeMount{ + Name: oidcCaVolumeName, + MountPath: tlsPathOidcCA, + ReadOnly: true, + SubPath: cmKey, + } + for i := range podSpec.Containers { + podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, mount) + } + for i := range podSpec.InitContainers { + podSpec.InitContainers[i].VolumeMounts = append(podSpec.InitContainers[i].VolumeMounts, mount) + } + + log.FromContext(feast.Handler.Context).Info("Mounted OIDC CA certificate ConfigMap to Feast pods.", "configMap", cmName, "key", cmKey) +} + // GetCustomCertificatesBundle retrieves the custom CA bundle ConfigMap if it exists when deployed with RHOAI or ODH func (feast *FeastServices) GetCustomCertificatesBundle() CustomCertificatesBundle { var customCertificatesBundle CustomCertificatesBundle configMapList := &corev1.ConfigMapList{} - labelSelector := client.MatchingLabels{caBundleAnnotation: "true"} + labelSelector := client.MatchingLabels{caBundleAnnotation: stringTrue} err := feast.Handler.Client.List( feast.Handler.Context, @@ -322,7 +379,7 @@ func getPortStr(tls *feastdevv1.TlsConfigs) string { func tlsDefaults(tls *feastdevv1.TlsConfigs) { if tls.IsTLS() { if len(tls.SecretKeyNames.TlsCrt) == 0 { - tls.SecretKeyNames.TlsCrt = "tls.crt" + tls.SecretKeyNames.TlsCrt = tlsCertKey } if len(tls.SecretKeyNames.TlsKey) == 0 { tls.SecretKeyNames.TlsKey = "tls.key" diff --git a/infra/feast-operator/internal/controller/services/tls_test.go b/infra/feast-operator/internal/controller/services/tls_test.go index e5299d79119..7f1c94789bc 100644 --- a/infra/feast-operator/internal/controller/services/tls_test.go +++ b/infra/feast-operator/internal/controller/services/tls_test.go @@ -37,7 +37,7 @@ var _ = Describe("TLS Config", func() { utilruntime.Must(feastdevv1.AddToScheme(scheme)) secretKeyNames := feastdevv1.SecretKeyNames{ - TlsCrt: "tls.crt", + TlsCrt: tlsCertKey, TlsKey: "tls.key", } @@ -128,8 +128,7 @@ var _ = Describe("TLS Config", func() { err = feast.ApplyDefaults() Expect(err).ToNot(HaveOccurred()) - repoConfig, err := getClientRepoConfig(feast.Handler.FeatureStore, emptyMockExtractConfigFromSecret, &feast) - Expect(err).NotTo(HaveOccurred()) + repoConfig := getClientRepoConfig(feast.Handler.FeatureStore, &feast) Expect(repoConfig.OfflineStore.Port).To(Equal(HttpsPort)) Expect(repoConfig.OfflineStore.Scheme).To(Equal(HttpsScheme)) Expect(repoConfig.OfflineStore.Cert).To(ContainSubstring(string(OfflineFeastType))) @@ -173,7 +172,7 @@ var _ = Describe("TLS Config", func() { feastDeploy := feast.initFeastDeploy() err = feast.setDeployment(feastDeploy) Expect(err).ToNot(HaveOccurred()) - Expect(feastDeploy.Spec.Template.Spec.InitContainers).To(HaveLen(1)) + Expect(feastDeploy.Spec.Template.Spec.InitContainers).To(HaveLen(2)) Expect(feastDeploy.Spec.Template.Spec.Containers).To(HaveLen(4)) Expect(feastDeploy.Spec.Template.Spec.Containers[0].Command).To(ContainElements(ContainSubstring("--key"))) Expect(feastDeploy.Spec.Template.Spec.Containers[1].Command).To(ContainElements(ContainSubstring("--key"))) @@ -181,6 +180,19 @@ var _ = Describe("TLS Config", func() { Expect(feastDeploy.Spec.Template.Spec.Containers[3].Command).To(ContainElements(ContainSubstring("--key"))) Expect(feastDeploy.Spec.Template.Spec.Volumes).To(HaveLen(5)) + // verify init containers receive TLS volume mounts when all services have TLS + for _, initContainer := range feastDeploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).To(ContainElement( + HaveField("MountPath", GetTlsPath(RegistryFeastType)), + ), "init container %s should have registry TLS mount", initContainer.Name) + Expect(initContainer.VolumeMounts).To(ContainElement( + HaveField("MountPath", GetTlsPath(OnlineFeastType)), + ), "init container %s should have online TLS mount", initContainer.Name) + Expect(initContainer.VolumeMounts).To(ContainElement( + HaveField("MountPath", GetTlsPath(OfflineFeastType)), + ), "init container %s should have offline TLS mount", initContainer.Name) + } + // registry service w/ tls and in an openshift cluster feast.Handler.FeatureStore = minimalFeatureStore() feast.Handler.FeatureStore.Spec.Services = &feastdevv1.FeatureStoreServices{ @@ -262,8 +274,7 @@ var _ = Describe("TLS Config", func() { err = feast.ApplyDefaults() Expect(err).ToNot(HaveOccurred()) - repoConfig, err = getClientRepoConfig(feast.Handler.FeatureStore, emptyMockExtractConfigFromSecret, &feast) - Expect(err).NotTo(HaveOccurred()) + repoConfig = getClientRepoConfig(feast.Handler.FeatureStore, &feast) Expect(repoConfig.OfflineStore.Port).To(Equal(HttpsPort)) Expect(repoConfig.OfflineStore.Scheme).To(Equal(HttpsScheme)) Expect(repoConfig.OfflineStore.Cert).To(ContainSubstring(string(OfflineFeastType))) @@ -336,6 +347,19 @@ var _ = Describe("TLS Config", func() { Expect(GetUIContainer(*feastDeploy).Command).NotTo(ContainElements(ContainSubstring("--key"))) Expect(GetUIContainer(*feastDeploy).VolumeMounts).To(HaveLen(1)) + // verify init containers receive only the offline TLS mount when only offline has TLS + for _, initContainer := range feastDeploy.Spec.Template.Spec.InitContainers { + Expect(initContainer.VolumeMounts).To(ContainElement( + HaveField("MountPath", GetTlsPath(OfflineFeastType)), + ), "init container %s should have offline TLS mount", initContainer.Name) + Expect(initContainer.VolumeMounts).NotTo(ContainElement( + HaveField("MountPath", GetTlsPath(RegistryFeastType)), + ), "init container %s should not have registry TLS mount when registry TLS is disabled", initContainer.Name) + Expect(initContainer.VolumeMounts).NotTo(ContainElement( + HaveField("MountPath", GetTlsPath(OnlineFeastType)), + ), "init container %s should not have online TLS mount when online TLS is disabled", initContainer.Name) + } + // Test REST registry server TLS configuration feast.Handler.FeatureStore = minimalFeatureStore() restEnabled := true diff --git a/infra/feast-operator/internal/controller/services/util.go b/infra/feast-operator/internal/controller/services/util.go index 9ce1ecd749a..387ccdb631b 100644 --- a/infra/feast-operator/internal/controller/services/util.go +++ b/infra/feast-operator/internal/controller/services/util.go @@ -21,6 +21,7 @@ import ( ) var isOpenShift = false +var hasServiceMonitorCRD = false func IsRegistryServer(featureStore *feastdevv1.FeatureStore) bool { return IsLocalRegistry(featureStore) && featureStore.Status.Applied.Services.Registry.Local.Server != nil @@ -99,6 +100,9 @@ func ApplyDefaultsToStatus(cr *feastdevv1.FeatureStore) { applied.Services = &feastdevv1.FeatureStoreServices{} } services := applied.Services + if services.RunFeastApplyOnInit == nil { + services.RunFeastApplyOnInit = boolPtr(true) + } if services.Registry != nil { // if remote registry not set, proceed w/ local registry defaults @@ -313,7 +317,7 @@ func hasAttrib(s interface{}, fieldName string, value interface{}) (bool, error) val := reflect.ValueOf(s) // Check that the object is a pointer so we can modify it - if val.Kind() != reflect.Ptr || val.IsNil() { + if val.Kind() != reflect.Pointer || val.IsNil() { return false, fmt.Errorf("expected a pointer to struct, got %v", val.Kind()) } @@ -371,6 +375,12 @@ func IsOpenShift() bool { return isOpenShift } +// HasServiceMonitorCRD returns whether the monitoring.coreos.com API group +// (Prometheus Operator) is available in the cluster. +func HasServiceMonitorCRD() bool { + return hasServiceMonitorCRD +} + // SetIsOpenShift sets the global flag isOpenShift by the controller manager. // We don't need to keep fetching the API every reconciliation cycle that we need to know about the platform. func SetIsOpenShift(cfg *rest.Config) { @@ -390,15 +400,13 @@ func SetIsOpenShift(cfg *rest.Config) { for _, v := range apiList.Groups { if v.Name == "route.openshift.io" { isOpenShift = true - break + } + if v.Name == "monitoring.coreos.com" { + hasServiceMonitorCRD = true } } } -func missingOidcSecretProperty(property OidcPropertyType) error { - return fmt.Errorf(OidcMissingSecretError, property) -} - // getEnvVar returns the position of the EnvVar found by name func getEnvVar(envName string, env []corev1.EnvVar) int { for pos, v := range env { diff --git a/infra/feast-operator/test/api/featurestore_types_test.go b/infra/feast-operator/test/api/featurestore_types_test.go index d426c8e0d7e..00312e0fabb 100644 --- a/infra/feast-operator/test/api/featurestore_types_test.go +++ b/infra/feast-operator/test/api/featurestore_types_test.go @@ -445,7 +445,7 @@ func cronJobWithAnnotations(featureStore *feastdevv1.FeatureStore) *feastdevv1.F "test-annotation": "test-value", "another-annotation": "another-value", }, - Schedule: "0 0 * * *", + Schedule: dailyMidnightCron, } return fsCopy } @@ -462,7 +462,7 @@ func cronJobWithEmptyAnnotations(featureStore *feastdevv1.FeatureStore) *feastde func cronJobWithoutAnnotations(featureStore *feastdevv1.FeatureStore) *feastdevv1.FeatureStore { fsCopy := featureStore.DeepCopy() fsCopy.Spec.CronJob = &feastdevv1.FeastCronJob{ - Schedule: "0 0 * * *", + Schedule: dailyMidnightCron, } return fsCopy } @@ -477,12 +477,16 @@ func quotedSlice(stringSlice []string) string { return strings.Join(quotedSlice, ", ") } -const resourceName = "test-resource" -const namespaceName = "default" +const ( + resourceName = "test-resource" + namespaceName = "default" + defaultNs = "default" + dailyMidnightCron = "0 0 * * *" +) var typeNamespacedName = types.NamespacedName{ Name: resourceName, - Namespace: "default", + Namespace: defaultNs, } func initContext() (context.Context, *feastdevv1.FeatureStore) { diff --git a/infra/feast-operator/test/testdata/feast_integration_test_crs/feast.yaml b/infra/feast-operator/test/testdata/feast_integration_test_crs/feast.yaml index 9dec3831b8c..56ab0ffbd4b 100644 --- a/infra/feast-operator/test/testdata/feast_integration_test_crs/feast.yaml +++ b/infra/feast-operator/test/testdata/feast_integration_test_crs/feast.yaml @@ -7,7 +7,7 @@ stringData: redis: | connection_string: redis.test-ns-feast.svc.cluster.local:6379 sql: | - path: postgresql+psycopg://${POSTGRESQL_USER}:${POSTGRESQL_PASSWORD}@postgres.test-ns-feast.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + path: postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres.test-ns-feast.svc.cluster.local:5432/${POSTGRES_DB} cache_ttl_seconds: 60 sqlalchemy_config_kwargs: echo: false diff --git a/infra/feast-operator/test/testdata/feast_integration_test_crs/postgres.yaml b/infra/feast-operator/test/testdata/feast_integration_test_crs/postgres.yaml index 8fbb11cf1cd..ba4599cea25 100644 --- a/infra/feast-operator/test/testdata/feast_integration_test_crs/postgres.yaml +++ b/infra/feast-operator/test/testdata/feast_integration_test_crs/postgres.yaml @@ -4,9 +4,9 @@ metadata: name: postgres-secret namespace: test-ns-feast stringData: - POSTGRESQL_DATABASE: feast - POSTGRESQL_USER: feast - POSTGRESQL_PASSWORD: feast + POSTGRES_DB: feast + POSTGRES_USER: feast + POSTGRES_PASSWORD: feast --- apiVersion: apps/v1 kind: Deployment @@ -25,7 +25,7 @@ spec: spec: containers: - name: postgres - image: 'quay.io/sclorg/postgresql-16-c9s@sha256:5879226a0fd2ea295df6836cc30ab624d2a1c51b81b3406284885604e10ddefe' + image: 'quay.io/feastdev-ci/feast-test-images:postgres-17-alpine' ports: - containerPort: 5432 envFrom: diff --git a/infra/feast-operator/test/testdata/feast_integration_test_crs/redis.yaml b/infra/feast-operator/test/testdata/feast_integration_test_crs/redis.yaml index cd88fb88fe5..c81fdb46b67 100644 --- a/infra/feast-operator/test/testdata/feast_integration_test_crs/redis.yaml +++ b/infra/feast-operator/test/testdata/feast_integration_test_crs/redis.yaml @@ -15,7 +15,8 @@ spec: spec: containers: - name: redis - image: 'quay.io/sclorg/redis-7-c9s@sha256:ce07d358cea749e67bcc77f73b2c5244d771ac0781ed20d7ebb2ba271c169173' + image: 'quay.io/feastdev-ci/feast-test-images:redis-7-alpine' + command: ["redis-server", "--save", ""] ports: - containerPort: 6379 env: diff --git a/infra/feast-operator/test/utils/test_util.go b/infra/feast-operator/test/utils/test_util.go index 15cd558ea16..dfb5a9f31fd 100644 --- a/infra/feast-operator/test/utils/test_util.go +++ b/infra/feast-operator/test/utils/test_util.go @@ -27,6 +27,8 @@ const ( FeatureStoreName = "simple-feast-setup" FeastResourceName = FeastPrefix + FeatureStoreName FeatureStoreResourceName = "featurestores.feast.dev" + feastCommand = "feast" + listCommand = "list" ) // dynamically checks if all conditions of custom resource featurestore are in "Ready" state. @@ -548,27 +550,27 @@ func VerifyFeastMethods(namespace string, feastDeploymentName string, testDir st } checks := []feastCheck{ { - command: []string{"feast", "projects", "list"}, + command: []string{feastCommand, "projects", listCommand}, expected: []string{"credit_scoring_local"}, logPrefix: "Projects List", }, { - command: []string{"feast", "feature-views", "list"}, + command: []string{feastCommand, "feature-views", listCommand}, expected: []string{"credit_history", "zipcode_features", "total_debt_calc"}, logPrefix: "Feature Views List", }, { - command: []string{"feast", "entities", "list"}, + command: []string{feastCommand, "entities", listCommand}, expected: []string{"zipcode", "dob_ssn"}, logPrefix: "Entities List", }, { - command: []string{"feast", "data-sources", "list"}, + command: []string{feastCommand, "data-sources", listCommand}, expected: []string{"Zipcode source", "Credit history", "application_data"}, logPrefix: "Data Sources List", }, { - command: []string{"feast", "features", "list"}, + command: []string{feastCommand, "features", listCommand}, expected: []string{ "credit_card_due", "mortgage_due", "student_loan_due", "vehicle_loan_due", "hard_pulls", "missed_payments_2y", "missed_payments_1y", "missed_payments_6m", diff --git a/infra/scripts/feature_server_docker_smoke.py b/infra/scripts/feature_server_docker_smoke.py index 5eac394bccd..c8b3b440b7f 100644 --- a/infra/scripts/feature_server_docker_smoke.py +++ b/infra/scripts/feature_server_docker_smoke.py @@ -9,6 +9,9 @@ class _FakeRegistry: def proto(self): return object() + def list_projects(self, allow_cache=True, tags=None): + return [] + class _FakeStore: def __init__(self): diff --git a/infra/scripts/pixi/pixi.toml b/infra/scripts/pixi/pixi.toml index afb6407042d..b5ce74b1791 100644 --- a/infra/scripts/pixi/pixi.toml +++ b/infra/scripts/pixi/pixi.toml @@ -1,4 +1,4 @@ -[project] +[workspace] name = "pixi-feast" channels = ["conda-forge"] platforms = ["linux-64", "osx-arm64", "osx-64"] diff --git a/infra/website/docs/blog/feast-agents-mcp.md b/infra/website/docs/blog/feast-agents-mcp.md new file mode 100644 index 00000000000..5678cd5a578 --- /dev/null +++ b/infra/website/docs/blog/feast-agents-mcp.md @@ -0,0 +1,363 @@ +--- +title: "Building AI Agents with Feast: Feature Stores as Context and Memory" +description: "How Feast's MCP integration turns your feature store into a governed context and memory layer for AI agents, bridging the gap between experimental agents and production-ready systems." +date: 2026-04-11 +authors: ["Nikhil Kathole"] +--- + +
+ AI Agents powered by Feast Feature Store +
+ +AI agents are moving from demos to production. They handle customer support, orchestrate complex workflows, and make real-time decisions that affect business outcomes. But there is a gap between a working prototype and a production system: agents need reliable, low-latency access to structured data, they need to remember what happened in prior interactions, and all of this access needs to be governed. + +This is where feature stores enter the picture. In this post, we show how **Feast** -- an open-source feature store -- can serve as both the **context provider** and the **persistent memory layer** for AI agents, using the **Model Context Protocol (MCP)**. + +## The Problem: Agents Need Context, Memory, and Governance + +A standalone LLM knows nothing about your customers, your products, or your internal processes. To make good decisions, agents need **tools** that give them access to real data: + +- **Who is this user?** Their plan tier, account age, purchase history, satisfaction score. +- **What do we know about this topic?** Relevant documentation, knowledge-base articles, FAQs. +- **What happened before?** What did this agent discuss with this customer last time? What was left unresolved? + +That last point is critical and often overlooked. Most agent demos are stateless -- every conversation starts from scratch. But real support interactions build on prior context: *"I called about this yesterday"*, *"you said you'd escalate"*, *"I prefer email over chat."* An agent without memory cannot handle these. + +Without a proper data layer, teams end up writing ad-hoc database queries, hardcoding API calls, stuffing memory into Redis with no governance, or giving agents raw database access. This creates fragile, ungoverned, and hard-to-audit agent systems. + +## Feature Stores Solve This -- Including Memory + +Feature stores were built to solve exactly this class of problem -- albeit originally for traditional ML. They provide: + +1. **Low-latency online serving** of pre-computed features. +2. **Versioned, governed access** to data with RBAC and audit trails. +3. **Consistency** between training/offline and serving/online environments. +4. **A single abstraction** over diverse data sources (databases, data warehouses, streaming systems, and vector stores -- including Milvus, Elasticsearch, Qdrant, PGVector, and FAISS). +5. **Entity-keyed read/write** -- the same mechanism that serves features can also store and retrieve agent memory, keyed by customer ID, session ID, or any entity. + +With Feast's MCP support, these capabilities are exposed as **tools that AI agents can discover and call dynamically** -- and critically, agents can **write back** to the feature store, turning it into a governed memory layer. + +## Feast + MCP: Turning a Feature Store into an Agent Tool + +The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open standard that lets AI applications discover and interact with external tools through a unified interface. Feast's feature server can now expose its endpoints as MCP tools with a simple configuration change: + +```yaml +feature_server: + type: mcp + enabled: true + mcp_enabled: true + mcp_transport: http + mcp_server_name: "feast-feature-store" + mcp_server_version: "1.0.0" +``` + +Once enabled, any MCP-compatible agent -- whether built with LangChain, LlamaIndex, CrewAI, AutoGen, or a custom framework -- can connect to `http://your-feast-server/mcp` and discover available tools like `get-online-features` for entity-based retrieval, `retrieve-online-documents` for vector similarity search, and `write-to-online-store` for persisting agent state. + +## A Concrete Example: Customer-Support Agent with Memory + +To make this tangible, let's walk through a customer-support agent that uses Feast for structured feature retrieval, document search, and persistent memory. + +> **Note on the implementation:** This example builds the agent loop from scratch using the OpenAI tool-calling API and the MCP Python SDK -- no framework required. All Feast interactions use the MCP protocol: the agent connects to Feast's MCP endpoint, discovers available tools via `session.list_tools()`, and invokes them via `session.call_tool()`. We chose this approach to keep dependencies minimal and make every Feast interaction visible. In production, you would typically use a framework like LangChain/LangGraph, LlamaIndex, CrewAI, or AutoGen. Because Feast exposes a standard MCP endpoint, any of these frameworks can auto-discover the tools with zero custom code (see [Connecting Your Agent Framework](#connecting-your-agent-framework) below). + +### The Setup + +We define three feature views in Feast: + +**Customer profiles** -- structured data served from the online store: + +```python +customer_profile = FeatureView( + name="customer_profile", + entities=[customer], + schema=[ + Field(name="name", dtype=String), + Field(name="email", dtype=String), + Field(name="plan_tier", dtype=String), + Field(name="account_age_days", dtype=Int64), + Field(name="total_spend", dtype=Float64), + Field(name="open_tickets", dtype=Int64), + Field(name="satisfaction_score", dtype=Float64), + ], + source=customer_profile_source, + ttl=timedelta(days=1), +) +``` + +**Knowledge base** -- support articles stored as vector embeddings (Feast supports multiple vector backends including Milvus, Elasticsearch, Qdrant, PGVector, and FAISS -- this example uses Milvus): + +```python +knowledge_base = FeatureView( + name="knowledge_base", + entities=[document], + schema=[ + Field( + name="vector", dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="title", dtype=String), + Field(name="content", dtype=String), + Field(name="category", dtype=String), + ], + source=knowledge_base_source, + ttl=timedelta(days=7), +) +``` + +**Agent memory** -- per-customer interaction state written back by the agent: + +```python +agent_memory = FeatureView( + name="agent_memory", + entities=[customer], + schema=[ + Field(name="last_topic", dtype=String), + Field(name="last_resolution", dtype=String), + Field(name="interaction_count", dtype=Int64), + Field(name="preferences", dtype=String), + Field(name="open_issue", dtype=String), + ], + ttl=timedelta(days=30), +) +``` + +This is the key insight: Feast is not just providing context to the agent -- it is also **storing the agent's memory**. The `agent_memory` feature view is entity-keyed by customer ID, TTL-managed (30-day expiration), schema-typed, and governed by the same RBAC as every other feature. The agent reads prior interactions via `recall_memory`, and memory is automatically checkpointed after each turn using the same online store infrastructure. + +### The Agent Loop + +The agent connects to Feast's MCP endpoint, discovers tools dynamically, and uses the MCP protocol for all Feast interactions. Each round, the LLM sees the conversation history plus the available read tools, and decides what to do. Memory is saved automatically after the turn -- framework-style, not as an LLM decision: + +```python +from mcp import ClientSession +from mcp.client.streamable_http import streamablehttp_client + +async with streamablehttp_client("http://localhost:6566/mcp") as (r, w, _): + async with ClientSession(r, w) as session: + await session.initialize() + tools = await session.list_tools() # discover Feast tools + + for round in range(MAX_ROUNDS): + response = call_llm(messages, tools=[...]) + + if response.finish_reason == "stop": + break + + for tool_call in response.tool_calls: + result = await session.call_tool(name, args) # MCP + messages.append(tool_result(result)) + + # Framework-style checkpoint: auto-save via MCP + await session.call_tool("write_to_online_store", {...}) +``` + +A typical multi-turn flow looks like: + +1. **Round 1**: Agent calls `recall_memory("C1001")` -- checks for prior interactions. Calls `lookup_customer("C1001")` -- gets profile data. Calls `search_knowledge_base("SSO setup")` -- finds the relevant article. +2. **Round 2**: Has enough context. Generates a personalised response and returns it. +3. **Checkpoint**: The framework auto-saves `topic="SSO setup"` and a resolution summary to Feast. + +When C1001 comes back later and says *"I'm following up on my SSO question"*, the agent calls `recall_memory` and immediately knows what was discussed -- no re-explanation needed. + +For a simpler question like *"What's my current plan?"*, the agent only calls `lookup_customer` -- skipping the knowledge base entirely. The LLM makes these routing decisions based on the question, not hardcoded logic. + +### Memory as Infrastructure + +Production agent frameworks treat persistence as infrastructure, not an LLM decision: + +- **LangGraph** uses checkpointers (`MemorySaver`, `PostgresSaver`) that auto-save state after every graph step, keyed by `thread_id`. +- **CrewAI** enables `memory=True` for automatic short-term, long-term, and entity memory. +- **AutoGen** uses post-conversation hooks to extract and store learnings. + +This demo follows the same pattern. The LLM has three read tools for reasoning; memory is checkpointed by the framework after each turn via Feast's `write-to-online-store` endpoint. This ensures consistent, reliable memory regardless of LLM behaviour -- no risk of the model forgetting to save or writing inconsistent state. Feast is a natural fit for this checkpoint layer because it provides entity-keyed storage, TTL-managed expiration, schema enforcement, RBAC governance, and offline queryability -- all out of the box. + +
+ Feast MCP Agent Workflow — agent loop with context retrieval, vector search, and memory persistence through Feast +
+ +The agent doesn't need to know *where* the data lives or *which* vector database is behind the scenes. It calls Feast through a standard protocol, and Feast handles the routing to the right store -- whether that's Milvus, Elasticsearch, Qdrant, PGVector, or FAISS. Swapping the vector backend is a configuration change, not a code change. The same protocol handles both reads and writes -- context retrieval and memory persistence use the same governed infrastructure. + +### The Response + +Instead of a generic answer, the agent produces something like: + +> *"Hi Alice! Since you're on our Enterprise plan, SSO is available for your team. Go to Settings > Security > SSO and enter your Identity Provider metadata URL. We support SAML 2.0 and OIDC. Once configured, all team members will authenticate through your IdP. As an Enterprise customer, you also have a dedicated Slack channel and account manager if you need hands-on help."* + +The personalisation (mentioning the Enterprise plan, dedicated Slack channel) comes directly from the Feast features. And if Alice calls back next week, the agent already knows what was discussed. + +## Why This Matters for Production + +### Unified Data Access: Structured Features + Vector Search + Memory + +Real-world agents need more than document retrieval. They need access to multiple data types through a single governed interface: + +| Data Type | Example | Feast Capability | +|---|---|---| +| Structured features | Account tier, spend history | `get_online_features` | +| Vector embeddings | Support article search | `retrieve_online_documents_v2` | +| Agent memory | Last interaction topic, open issues | `get_online_features` + `write_to_online_store` | +| Streaming features | Real-time click counts | Push sources with `write_to_online_store` | +| Pre-computed predictions | Churn probability | Served alongside other features | + +Feast unifies all of these behind a single API that agents can both read from and write to. + +### Context Memory: Why Feast Beats Ad-Hoc Solutions + +Many teams use Redis, in-memory dicts, or custom databases for agent memory. Feast provides a better foundation: + +| Concern | Ad-hoc Memory | Feast Memory | +|---|---|---| +| **Governance** | No RBAC, no audit trail | Same RBAC and permissions as all features | +| **TTL management** | Manual expiration logic | Declarative TTL on the feature view | +| **Entity-keying** | Custom key design | Native entity model (customer_id, session_id, etc.) | +| **Observability** | Custom logging | Integrated with OpenTelemetry and MLflow traces | +| **Offline analysis** | Separate export pipeline | Memory is just another feature -- queryable offline | +| **Schema evolution** | Unstructured blobs | Typed schema with versioning | + +Because agent memory is stored as a standard Feast feature view, it inherits all the infrastructure that already exists for serving ML features: monitoring, access control, TTL management, and offline queryability. There is no separate system to operate. + +### Governance: Who Can Access What + +In production, you do not want every agent to access every feature. Feast provides: + +- **RBAC**: Role-based access control with OIDC integration. +- **Feature-level permissions**: Control which feature views each service account can read or write. +- **Audit trails**: Track which agent accessed which features and when. + +This is especially important for memory: you want governance over what agents remember and who can read those memories. + +### Production Platform Architecture + +Deploying agents in production requires more than just the agent code. A well-architected platform wraps agents in enterprise infrastructure without requiring changes to the agent itself. Feast fits naturally into this layered approach: + +
+ Production platform architecture — Feast MCP Server behind MCP Gateway with observability, guardrails, and lifecycle management +
+ +- **MCP Gateway**: Feast sits behind an Envoy-based MCP Gateway as one of many tool servers. The gateway provides identity-based tool filtering -- an agent's JWT claims determine whether it can call Feast at all, and which features it can access. +- **Sandboxed Execution**: Feast runs as a standard Kubernetes service, benefiting from sandboxed container isolation that keeps agent workloads separated. +- **Observability**: Feast feature-retrieval and memory-write calls flow through the platform's OpenTelemetry pipeline, appearing in MLflow traces alongside LLM calls and tool invocations. +- **Agent Lifecycle Management (Kagenti)**: An operator like Kagenti can discover Feast as a tool server via AgentCard CRDs and inject tracing and governance without code changes. + +The principle is straightforward: the agent is yours, the platform provides the guardrails, and Feast provides the data and memory. + +## Connecting Your Agent Framework + +Since Feast exposes a standard MCP endpoint, integration is framework-agnostic: + +**LangChain / LangGraph:** +```python +from langchain_mcp_adapters.client import MultiServerMCPClient +from langgraph.prebuilt import create_react_agent + +async with MultiServerMCPClient( + {"feast": {"url": "http://feast-server:6566/mcp", "transport": "streamable_http"}} +) as client: + tools = client.get_tools() + agent = create_react_agent(llm, tools) + result = await agent.ainvoke({"messages": "How do I set up SSO?"}) +``` + +**LlamaIndex:** +```python +from llama_index.tools.mcp import aget_tools_from_mcp_url +from llama_index.core.agent.function_calling import FunctionCallingAgent +from llama_index.llms.openai import OpenAI + +tools = await aget_tools_from_mcp_url("http://feast-server:6566/mcp") +agent = FunctionCallingAgent.from_tools(tools, llm=OpenAI(model="gpt-4o-mini")) +response = await agent.achat("How do I set up SSO?") +``` + +**Claude Desktop / Cursor:** +```json +{ + "mcpServers": { + "feast": { + "url": "http://feast-server:6566/mcp", + "transport": "streamable_http" + } + } +} +``` + +**Direct REST API:** +```python +import requests + +features = requests.post("http://feast-server:6566/get-online-features", json={ + "features": ["customer_profile:plan_tier", "customer_profile:satisfaction_score"], + "entities": {"customer_id": ["C1001"]}, +}).json() +``` + +The Feast-specific integration is just connecting to the MCP endpoint and getting the tools. Once you have them, building the agent follows each framework's standard patterns -- the tool-calling loop, message threading, and state persistence are handled natively. Feast's MCP endpoint means zero custom wiring. + +### Customizing for Your Use Case + +This demo's system prompt, tool names, and feature views are all specific to the customer-support scenario. Here's what changes when you build your own agent: + +| What | This demo | Your agent | +|---|---|---| +| **Feature views** | `customer_profile`, `knowledge_base`, `agent_memory` | Define your own in `features.py` (e.g., `product_catalog`, `order_history`, `fraud_signals`) | +| **System prompt** | "Call recall_memory and lookup_customer first..." | Write instructions specific to your domain and workflow | +| **Tool wrappers** | `lookup_customer`, `search_knowledge_base`, `recall_memory` | Optional -- see below | + +**Do you need custom tool wrappers?** It depends on how you build your agent: + +- **With a framework (LangChain, LlamaIndex, etc.):** No. The framework discovers Feast's generic MCP tools (`get_online_features`, `retrieve_online_documents`, `write_to_online_store`) automatically. The LLM calls them directly with your feature view names and entities. No wrapper code needed. + +- **With a raw loop (like this demo):** Optional but recommended. This demo wraps `get_online_features` into `lookup_customer` and `recall_memory` to give the LLM friendlier, domain-specific tool names. You'd create similar wrappers for your use case (e.g., `check_inventory`, `get_order_status`). The wrappers are thin -- they just call the Feast MCP tool with the right feature names and entities. + +**What stays the same** regardless of use case: Feast's MCP server, the online/offline store infrastructure, RBAC, TTL management, and the auto-save memory pattern. You define feature views, `feast apply`, start the server, and connect -- the same three generic MCP tools serve any domain. + +## Try It Yourself + +We have published a complete working example in the Feast repository. A single script handles setup, server startup, and the demo: + +```bash +git clone https://github.com/feast-dev/feast.git +cd feast/examples/agent_feature_store + +./run_demo.sh # demo mode (no API key needed) +OPENAI_API_KEY=sk-... ./run_demo.sh # live LLM tool-calling +``` + +The script installs dependencies, generates sample data (customer profiles, knowledge-base articles, and the agent memory scaffold), starts the Feast MCP server, runs the agent, and tears everything down on exit. + +To run with a real LLM, set the API key and (optionally) the base URL and model: + +```bash +# OpenAI +export OPENAI_API_KEY="sk-..." # pragma: allowlist secret +./run_demo.sh + +# Ollama (free, local -- no API key needed) +ollama pull llama3.1:8b +export OPENAI_API_KEY="ollama" # pragma: allowlist secret +export OPENAI_BASE_URL="http://localhost:11434/v1" +export LLM_MODEL="llama3.1:8b" +./run_demo.sh + +# Any OpenAI-compatible provider (Azure, vLLM, LiteLLM, etc.) +export OPENAI_API_KEY="your-key" # pragma: allowlist secret +export OPENAI_BASE_URL="https://your-endpoint/v1" +export LLM_MODEL="your-model" +./run_demo.sh +``` + +The agent demonstrates memory continuity: when the same customer returns, the agent recalls what was discussed previously. + +See the full example on [GitHub](https://github.com/feast-dev/feast/tree/master/examples/agent_feature_store). + +## What's Next + +The intersection of feature stores and agentic AI is just getting started. Here is what we are working on: + +- **Richer MCP tools**: Exposing `retrieve_online_documents_v2` as a first-class MCP tool for native vector search. +- **Memory patterns**: Expanding the memory model to support session-scoped memory, hierarchical summarisation, and cross-agent shared memory. +- **Platform integration**: First-class support in MCP Gateway tool catalogs and agent lifecycle operators. +- **Streaming features for agents**: Real-time feature updates from Kafka/Flink that agents can subscribe to. + +## Join the Conversation + +We would love to hear how you are using (or plan to use) Feast in your agent workflows. Reach out on [Slack](https://slack.feast.dev/) or [GitHub](https://github.com/feast-dev/feast) -- and give the example a try! diff --git a/infra/website/docs/blog/feast-feature-server-monitoring.md b/infra/website/docs/blog/feast-feature-server-monitoring.md new file mode 100644 index 00000000000..c416e84e82b --- /dev/null +++ b/infra/website/docs/blog/feast-feature-server-monitoring.md @@ -0,0 +1,443 @@ +--- +title: "Monitoring Your Feast Feature Server with Prometheus and Grafana" +description: "Feast now ships built-in Prometheus metrics for the feature server — request latency, feature freshness, materialization health, ODFV transformation duration, and more. Enable with a single flag and get production-grade observability for your ML infrastructure." +date: 2026-03-26 +authors: ["Nikhil Kathole"] +--- + +
+ Feast Feature Server Monitoring — Feast exports metrics to Prometheus for monitoring and alerting, visualized in Grafana dashboards +
+ +# Monitoring Your Feast Feature Server with Prometheus and Grafana + +As feature stores become a critical part of production ML systems, the question shifts from *"Can I serve features?"* to *"Can I trust what I'm serving?"*. Are my features fresh? Is latency within SLA? Are materialization pipelines succeeding? How long are my on-demand transformations taking? + +Until now, answering these questions for Feast required ad-hoc monitoring — parsing logs, writing custom health checks, or bolting on external instrumentation. That changes today. + +**Feast now ships built-in Prometheus metrics for the feature server**, covering the full request lifecycle — from HTTP request handling through online store reads and on-demand feature transformations to materialization pipelines and feature freshness tracking. Enable it with a single flag, point Prometheus at the metrics endpoint, and get production-grade observability for your feature serving infrastructure. + +This post walks through the metrics available, what each one tells you, how to enable and configure them, and how to build a Grafana dashboard that gives you a complete operational picture of your feature server. + +## What's New + +Feast's feature server now exposes a comprehensive set of Prometheus metrics across seven categories, designed to give ML platform teams full visibility into their feature serving infrastructure: + +- **Request metrics** — Per-endpoint request counters and latency histograms with `feature_count` and `feature_view_count` labels, so you can correlate latency with request complexity. +- **Online store read duration** — A histogram capturing total time spent reading from the online store (Redis, DynamoDB, PostgreSQL, etc.), covering both synchronous and async paths across all backends. +- **ODFV transformation duration** — Per-ODFV histograms for both read-path (during `/get-online-features`) and write-path (during push/materialize) transformations, with `odfv_name` and `mode` labels to compare Pandas vs Python vs Substrait performance. +- **Online feature retrieval counters** — Request counts and entity-row-per-request histograms, revealing the shape of your traffic. +- **Push counters** — Tracked by push source and mode (online/offline/both), giving early warning when ingestion pipelines stop sending data. +- **Materialization tracking** — Success/failure counters and duration histograms per feature view, so you know immediately when a pipeline breaks. +- **Feature freshness gauges** — Per-feature-view staleness (seconds since last materialization), updated by a background thread every 30 seconds. The single most important metric for ML model quality. +- **CPU and memory gauges** — Per-worker resource usage for capacity planning and leak detection. +- **Kubernetes-native discovery** — The Feast Operator auto-generates a `ServiceMonitor` when metrics are enabled, so Prometheus Operator discovers the scrape target automatically. + +All metrics are fully opt-in with zero overhead when disabled. Per-category toggles let you enable exactly the metrics you need. + +## Enabling Metrics + +### CLI: One Flag + +The simplest way — one flag, everything enabled: + +```bash +feast serve --metrics +``` + +This starts the feature server on its default port (6566) and a Prometheus metrics endpoint on port 8000. + +### YAML: Fine-Grained Control + +For production deployments, configure metrics in `feature_store.yaml` with per-category toggles: + +```yaml +feature_server: + metrics: + enabled: true + resource: true # CPU and memory gauges + request: true # HTTP request counters and latency histograms + online_features: true # Entity count and retrieval tracking + push: true # Push/ingestion request counters + materialization: true # Pipeline success/failure and duration + freshness: true # Per-feature-view data staleness +``` + +### Kubernetes: Feast Operator + +If you're running Feast on Kubernetes with the [Feast Operator](/blog/scaling-feast-feature-server), set `metrics: true` on the online store server: + +```yaml +apiVersion: feast.dev/v1alpha1 +kind: FeatureStore +metadata: + name: production-feast +spec: + feastProject: my_project + services: + onlineStore: + server: + metrics: true +``` + +The operator automatically appends `--metrics` to the serve command and exposes port 8000 as a `metrics` port on the Service. It also auto-generates a `ServiceMonitor` resource for Prometheus Operator discovery. The operator detects the `monitoring.coreos.com` API group at startup; if the Prometheus Operator CRD is absent, ServiceMonitor creation is silently skipped, so vanilla Kubernetes clusters are unaffected. + +## The Metrics + +Feast exposes metrics across seven categories. Here's the full reference, organized by what each category helps you answer. + +### Request Metrics — "How is my API performing?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_feature_server_request_total` | Counter | `endpoint`, `status` | +| `feast_feature_server_request_latency_seconds` | Histogram | `endpoint`, `feature_count`, `feature_view_count` | + +These are the core RED metrics (Rate, Errors, Duration) for your feature server. The latency histogram includes `feature_count` and `feature_view_count` labels so you can correlate latency with request complexity — a request fetching 200 features from 15 feature views will naturally be slower than one fetching 5 features from 2 views. + +The histogram uses bucket boundaries tuned for feature serving workloads: `5ms, 10ms, 25ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s, 10s`. Most online feature requests should complete in the lower buckets. + +### Online Feature Retrieval — "What does my traffic look like?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_online_features_request_total` | Counter | — | +| `feast_online_features_entity_count` | Histogram | — | + +The entity count histogram (buckets: `1, 5, 10, 25, 50, 100, 250, 500, 1000`) tells you the shape of your traffic. Are callers sending single-entity lookups (real-time inference) or batch requests of hundreds (batch scoring)? A sudden spike in entity count per request means an upstream service changed its batching strategy — this directly impacts latency and memory. + +### Online Store Read Duration — "Where is my latency coming from?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_feature_server_online_store_read_duration_seconds` | Histogram | — | + +This metric captures the total time spent reading from the online store (Redis, DynamoDB, PostgreSQL, etc.) during a `/get-online-features` request. It covers both the synchronous for-loop path and the async `asyncio.gather` path across all backends. + +By comparing this with the overall request latency, you can determine whether latency is dominated by the store read or by other processing (serialization, transformation, network overhead). + +### ODFV Transformation Duration — "How expensive are my transforms?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_feature_server_transformation_duration_seconds` | Histogram | `odfv_name`, `mode` | +| `feast_feature_server_write_transformation_duration_seconds` | Histogram | `odfv_name`, `mode` | + +These metrics capture per-ODFV transformation time for both read-path (during `/get-online-features`) and write-path (during push/materialize with `write_to_online_store=True`) operations. The `mode` label distinguishes `pandas`, `python`, and `substrait` transformation modes, making it easy to compare their performance characteristics side by side. + +ODFV transformation metrics are **opt-in at the definition level** via `track_metrics=True`: + +```python +@on_demand_feature_view( + sources=[driver_stats_fv, input_request], + schema=[Field(name="conv_rate_plus_val1", dtype=Float64)], + mode="python", + track_metrics=True, # Enable Prometheus metrics for this ODFV +) +def transformed_conv_rate_python(inputs: Dict[str, Any]) -> Dict[str, Any]: + return {"conv_rate_plus_val1": inputs["conv_rate"] + inputs["val_to_add"]} +``` + +When `track_metrics=False` (the default), zero metrics code runs for that ODFV — no timing, no Prometheus recording. This lets you selectively instrument the transforms you care about without adding overhead to others. + +### Push Metrics — "Is my ingestion pipeline healthy?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_push_request_total` | Counter | `push_source`, `mode` | + +The `push_source` label identifies which source is pushing data. The `mode` label is one of `online`, `offline`, or `online_and_offline`. A push source that stops sending data is an early signal that an upstream pipeline is broken — long before feature staleness becomes visible. + +### Materialization Metrics — "Are my pipelines succeeding?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_materialization_total` | Counter | `feature_view`, `status` | +| `feast_materialization_duration_seconds` | Histogram | `feature_view` | + +The `status` label is `success` or `failure`. The duration histogram uses wide buckets (`1s, 5s, 10s, 30s, 60s, 2min, 5min, 10min, 30min, 1hr`) because materialization jobs can range from seconds to tens of minutes depending on the feature view size and offline store. + +### Feature Freshness — "How stale is my data?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_feature_freshness_seconds` | Gauge | `feature_view`, `project` | + +**This is the single most important metric for ML teams.** It measures data staleness — the gap between "now" and the last successful materialization end time — per feature view. A background thread computes this every 30 seconds. + +If your model was trained on hourly features and the freshness gauge crosses 2 hours, your model is receiving data it has never seen patterns for. Before this metric existed, this was a silent failure. Now you can set an alert and catch it in minutes. + +The dashboard below shows these ML-specific metrics in action — latency correlated with feature count, online feature request rate, average entities per request, feature freshness per feature view, and materialization success counts with duration: + +
+ Grafana dashboard showing latency by feature count, feature freshness, average entities per request, and materialization metrics +
+ +### Resource Metrics — "Is my server healthy?" + +| Metric | Type | Labels | +|---|---|---| +| `feast_feature_server_cpu_usage` | Gauge | (per worker PID) | +| `feast_feature_server_memory_usage` | Gauge | (per worker PID) | + +Per-worker CPU and memory gauges, updated every 5 seconds by a background thread. In Gunicorn deployments, each worker reports independently, so you can spot an individual worker consuming excessive resources. + +## Latency Breakdown: Understanding Where Time Is Spent + +One of the most powerful uses of these metrics is **latency decomposition**. By overlaying the overall request latency with the online store read duration and ODFV transformation duration, you can pinpoint exactly where time is spent: + +``` +Total request latency = Store read + ODFV transforms + Serialization/overhead +``` + +The Grafana dashboard below shows this decomposition in action — online store read latency (p50/p95/p99), per-ODFV read-path and write-path transform latency, and a side-by-side Pandas vs Python ODFV comparison: + +
+ Grafana dashboard showing online store read latency, ODFV transformation latency by name, and Pandas vs Python ODFV comparison +
+ +If store reads dominate, the bottleneck is your online store (consider Redis instead of PostgreSQL, or tune your connection pool). If ODFV transforms dominate, consider switching from Pandas mode to Python mode — or re-evaluate whether the transformation should be precomputed during materialization instead of computed on the fly. + +### Pandas vs Python ODFV Comparison + +The `mode` label on transformation metrics makes it straightforward to compare Pandas and Python ODFV performance. The bottom-left panel in the dashboard above shows p50/p95 latencies for Pandas-mode and Python-mode ODFVs overlaid, making the comparison immediate. You can also query these directly: + +```promql +# Pandas p95 read-path latency +histogram_quantile(0.95, + sum(rate(feast_feature_server_transformation_duration_seconds_bucket{mode="pandas"}[1m])) by (le)) + +# Python p95 read-path latency +histogram_quantile(0.95, + sum(rate(feast_feature_server_transformation_duration_seconds_bucket{mode="python"}[1m])) by (le)) +``` + +## Building Alerts + +Here are the recommended alert rules, ordered by impact: + +### Feature Freshness SLO Breach + +```yaml +- alert: FeastFeatureViewStale + expr: feast_feature_freshness_seconds > 3600 + for: 5m + labels: + severity: critical + annotations: + summary: > + Feature view {{ $labels.feature_view }} in project {{ $labels.project }} + has not been materialized in {{ $value | humanizeDuration }}. + impact: Models consuming this feature view are receiving stale data. +``` + +### Materialization Failures + +```yaml +- alert: FeastMaterializationFailing + expr: rate(feast_materialization_total{status="failure"}[15m]) > 0 + for: 5m + labels: + severity: critical + annotations: + summary: > + Materialization is failing for feature view {{ $labels.feature_view }}. +``` + +### High p99 Latency + +```yaml +- alert: FeastHighLatency + expr: | + histogram_quantile(0.99, + rate(feast_feature_server_request_latency_seconds_bucket{ + endpoint="/get-online-features" + }[5m]) + ) > 1.0 + for: 5m + labels: + severity: warning + annotations: + summary: > + Feast p99 latency for online features is {{ $value }}s. +``` + +### High Error Rate + +```yaml +- alert: FeastHighErrorRate + expr: | + sum(rate(feast_feature_server_request_total{status="error"}[5m])) + / sum(rate(feast_feature_server_request_total[5m])) + > 0.01 + for: 5m + labels: + severity: warning + annotations: + summary: > + Feast feature server error rate is {{ $value | humanizePercentage }}. +``` + +## Building a Grafana Dashboard + +With these metrics exposed, you can build a Grafana dashboard that gives you a complete operational picture of your feature server. We've published a [ready-to-import Grafana dashboard JSON](https://github.com/ntkathole/feast-automated-setups/blob/main/feast-prometheus-metrics/grafana_dashboard.json) that covers all the panels described below — import it into your Grafana instance and point it at your Prometheus datasource to get started immediately. + +### Connecting Prometheus to Feast + +Add the Feast metrics endpoint to your Prometheus scrape configuration: + +```yaml +scrape_configs: + - job_name: feast + static_configs: + - targets: [":8000"] + scrape_interval: 15s +``` + +Once Prometheus is scraping, verify the raw metrics output: + +```bash +curl -s http://localhost:8000 | grep feast_ +``` + +### Key PromQL Queries + +Here are the most useful queries for building your own panels or running ad-hoc investigations in the Prometheus UI: + +**Throughput and errors:** + +```promql +# Request rate by endpoint +rate(feast_feature_server_request_total[5m]) + +# Error rate +sum(rate(feast_feature_server_request_total{status="error"}[5m])) + / sum(rate(feast_feature_server_request_total[5m])) +``` + +**Latency percentiles:** + +```promql +# p99 latency for online features +histogram_quantile(0.99, + rate(feast_feature_server_request_latency_seconds_bucket{endpoint="/get-online-features"}[5m])) + +# Online store read p95 +histogram_quantile(0.95, + sum(rate(feast_feature_server_online_store_read_duration_seconds_bucket[1m])) by (le)) + +# ODFV transform p95 by name and mode +histogram_quantile(0.95, + sum(rate(feast_feature_server_transformation_duration_seconds_bucket[1m])) by (le, odfv_name)) + +# ODFV write-path transform p95 by name +histogram_quantile(0.95, + sum(rate(feast_feature_server_write_transformation_duration_seconds_bucket[1m])) by (le, odfv_name)) +``` + +**Latency decomposition:** + +```promql +# Average total request latency +rate(feast_feature_server_request_latency_seconds_sum{endpoint="/get-online-features"}[5m]) + / rate(feast_feature_server_request_latency_seconds_count{endpoint="/get-online-features"}[5m]) + +# Average store read time +rate(feast_feature_server_online_store_read_duration_seconds_sum[5m]) + / rate(feast_feature_server_online_store_read_duration_seconds_count[5m]) + +# Average ODFV transform time +rate(feast_feature_server_transformation_duration_seconds_sum[5m]) + / rate(feast_feature_server_transformation_duration_seconds_count[5m]) +``` + +**Pandas vs Python comparison:** + +```promql +# Pandas p95 +histogram_quantile(0.95, + sum(rate(feast_feature_server_transformation_duration_seconds_bucket{mode="pandas"}[1m])) by (le)) + +# Python p95 +histogram_quantile(0.95, + sum(rate(feast_feature_server_transformation_duration_seconds_bucket{mode="python"}[1m])) by (le)) +``` + +**ML-specific signals:** + +```promql +# Feature freshness — views stale beyond 1 hour +feast_feature_freshness_seconds > 3600 + +# Materialization failure rate +rate(feast_materialization_total{status="failure"}[1h]) + +# Average entities per request +rate(feast_online_features_entity_count_sum[5m]) + / rate(feast_online_features_entity_count_count[5m]) + +# Push rate by source +rate(feast_push_request_total[5m]) +``` + +## Try the Automated Demo + +Want to see all of this in action without manual setup? We've published an [automated demo](https://github.com/ntkathole/feast-automated-setups/tree/main/feast-prometheus-metrics) that deploys a Feast feature server with metrics, a Prometheus instance, and the pre-built Grafana dashboard — all with a single `./setup.sh` command. It includes a traffic generator that exercises every metric category (plain online features, Pandas and Python ODFVs, push, materialize, and write-path transforms), so the dashboard populates immediately. + +## Kubernetes: Automatic Prometheus Discovery + +For teams running Feast on Kubernetes, the Feast Operator now auto-generates a `ServiceMonitor` when `metrics: true` is set on the online store. The operator: + +1. Detects the `monitoring.coreos.com` API group at startup +2. If present, creates a `ServiceMonitor` owned by the `FeatureStore` CR, targeting the `metrics` port (8000) +3. If absent (vanilla Kubernetes without Prometheus Operator), skips silently — no errors, no CRD dependency + +This means on an OpenShift or Prometheus-Operator-enabled cluster, metrics discovery is fully automatic — no manual `ServiceMonitor` creation required. The `ServiceMonitor` is cleaned up automatically when the `FeatureStore` CR is deleted or `metrics` is set back to `false`. + +For teams using [KEDA for autoscaling](/blog/scaling-feast-feature-server), these Prometheus metrics also serve as scaling signals. For example, you can scale the feature server based on request rate: + +```yaml +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: feast-scaledobject +spec: + scaleTargetRef: + apiVersion: feast.dev/v1 + kind: FeatureStore + name: my-feast + triggers: + - type: prometheus + metadata: + serverAddress: http://prometheus.monitoring.svc:9090 + query: sum(rate(feast_feature_server_request_total[2m])) + threshold: "100" +``` + +## Metrics Summary + +| Category | Metric | What It Answers | +|---|---|---| +| Request | `feast_feature_server_request_total` | What is my throughput and error rate? | +| Request | `feast_feature_server_request_latency_seconds` | What are my p50/p99 latencies? | +| Online Features | `feast_online_features_entity_count` | What is my traffic shape? | +| Store Read | `feast_feature_server_online_store_read_duration_seconds` | Is my online store the bottleneck? | +| ODFV Transform | `feast_feature_server_transformation_duration_seconds` | How expensive are my read-path transforms? | +| ODFV Transform | `feast_feature_server_write_transformation_duration_seconds` | How expensive are my write-path transforms? | +| Push | `feast_push_request_total` | Is my ingestion pipeline sending data? | +| Materialization | `feast_materialization_total` | Are my pipelines succeeding? | +| Materialization | `feast_materialization_duration_seconds` | How long do my pipelines take? | +| Freshness | `feast_feature_freshness_seconds` | How stale is the data my models are using? | +| Resource | `feast_feature_server_cpu_usage` / `memory_usage` | Is my server healthy? | + +## How Can I Get Started? + +1. **Enable metrics**: `feast serve --metrics` or set `metrics.enabled: true` in your `feature_store.yaml` +2. **Verify the endpoint**: `curl http://localhost:8000` +3. **Import the dashboard**: Grab the [Grafana dashboard JSON](https://github.com/ntkathole/feast-automated-setups/blob/main/feast-prometheus-metrics/grafana_dashboard.json) and import it into your Grafana instance +4. **Set up alerts**: Start with freshness and materialization failures — those catch the problems that affect ML model quality first +5. **Try the automated demo**: Run the [feast-prometheus-metrics setup](https://github.com/ntkathole/feast-automated-setups/tree/main/feast-prometheus-metrics) for a one-command local experience +6. Check out the [Feast documentation](https://docs.feast.dev/) for the full configuration reference +7. Join the [Feast Slack](https://slack.feast.dev) to share feedback and ask questions + +We're excited to bring production-grade observability to Feast and welcome feedback from the community! diff --git a/infra/website/docs/blog/feast-mlflow-kubeflow.md b/infra/website/docs/blog/feast-mlflow-kubeflow.md index 3e15cbda26a..5199da61da5 100644 --- a/infra/website/docs/blog/feast-mlflow-kubeflow.md +++ b/infra/website/docs/blog/feast-mlflow-kubeflow.md @@ -199,43 +199,29 @@ For cross-system lineage that extends beyond Feast into upstream data pipelines ### Data quality monitoring -Feast integrates with data quality frameworks like [Great Expectations](https://greatexpectations.io/) to detect feature drift, stale data, and schema violations before they silently degrade model performance. The workflow centers on Feast's `SavedDataset` and `ValidationReference` APIs: you save a profiled dataset during training, define a profiler using Great Expectations, and then validate new feature data against that reference in subsequent runs. +:::note +The Great Expectations integration described in earlier versions of this post is now **deprecated**. Feast includes a built-in [Feature Quality Monitoring](/docs/how-to-guides/feature-monitoring) system that provides richer metrics, requires no external dependencies, and includes a monitoring UI. +::: -```python -from feast import FeatureStore -from feast.dqm.profilers.ge_profiler import ge_profiler -from great_expectations.core import ExpectationSuite -from great_expectations.dataset import PandasDataset - -store = FeatureStore(repo_path=".") +Feast's native data quality monitoring system automatically computes statistical metrics — null rates, distributions, percentiles, histograms — for every registered feature across both batch data and serving logs. It detects drift by comparing current metrics against baselines computed during `feast apply`. -@ge_profiler -def my_profiler(dataset: PandasDataset) -> ExpectationSuite: - dataset.expect_column_values_to_be_between("conv_rate", min_value=0, max_value=1) - dataset.expect_column_values_to_be_between("acc_rate", min_value=0, max_value=1) - return dataset.get_expectation_suite() - -reference_job = store.get_historical_features( - entity_df=entity_df, - features=["driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate"], -) - -dataset = store.create_saved_dataset( - from_=reference_job, - name="driver_stats_validation", - storage=storage, -) +```yaml +# feature_store.yaml +data_quality_monitoring: + auto_baseline: true +``` -reference = dataset.as_reference(name="driver_stats_ref", profiler=my_profiler) +```bash +# Compute metrics across all granularities (daily, weekly, monthly, quarterly) +feast monitor run -new_job = store.get_historical_features( - entity_df=new_entity_df, - features=["driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate"], -) -new_job.to_df(validation_reference=reference) +# Monitor serving logs +feast monitor run --source-type log ``` -If validation fails, Feast raises a `ValidationFailed` exception with details on which expectations were violated. Monitoring feature distributions over time — and comparing them to the distributions seen during training — allows you to detect training–serving skew early, before it causes silent model degradation in production. +The monitoring UI dashboard (accessible from the sidebar) provides per-feature health status, distribution histograms, time-series drift charts, and configurable filters. Metrics are also available via REST API endpoints for integration with external alerting systems. + +For details, see the [Feature Quality Monitoring guide](/docs/how-to-guides/feature-monitoring). ### Feast Feature Registry vs. MLflow Model Registry diff --git a/infra/website/docs/blog/feast-mlflow-native-integration.md b/infra/website/docs/blog/feast-mlflow-native-integration.md new file mode 100644 index 00000000000..882fd7ef6f6 --- /dev/null +++ b/infra/website/docs/blog/feast-mlflow-native-integration.md @@ -0,0 +1,270 @@ +--- +title: "Native MLflow Integration for Feast: Automatic Feature Lineage for Every Experiment" +description: "Feast now ships native MLflow integration : enable it in feature_store.yaml and every feature retrieval is automatically linked to the MLflow run that consumed it. No glue code, no manual tagging, full model-to-feature traceability." +date: 2026-06-01 +authors: ["Vanshika"] +--- + +
+ Feast Native MLflow Integration +
+ +# Native MLflow Integration for Feast + +## The Problem: Features and Experiments Live in Separate Worlds + +Feast manages your features. MLflow tracks your experiments. But between the two, there has always been a manual gap. + +When a data scientist trains a model, the features that shaped it are retrieved from Feast, but MLflow has no idea which features were used, which feature service they belong to, or what entity DataFrame produced the training set. The result is a familiar set of problems: + +- **"Which features did model v3 use?"** — dig through notebooks and hope the comments are accurate. +- **"Can I reproduce the training data for last month's experiment?"** — re-derive the entity DataFrame from memory. +- **"Which models break if I change `driver_hourly_stats`?"** — grep through repos and ask around. +- **"I promoted a model — which features do I need to serve?"** — read the training script, cross-reference with the feature registry. + +Teams have tried to close this gap with manual `mlflow.log_param("features", ...)` calls, custom wrappers, or convention-based tagging. These approaches are fragile, inconsistent, and the first thing to break when someone new joins the team. + +## The Solution: One Config Line, Automatic Lineage + +Starting with Feast v0.62, the Feast–MLflow integration is **native and zero-code**. Add an `mlflow:` block to your `feature_store.yaml`, and every feature retrieval inside an active MLflow run is automatically tagged with the features, feature views, feature service, entity count, and retrieval duration. + +```yaml +project: driver_ranking +registry: data/registry.db +provider: local +online_store: + type: sqlite + path: data/online_store.db +mlflow: + enabled: true + tracking_uri: http://127.0.0.1:5000 +``` + +That's it. No decorators, no wrappers, no `import mlflow` scattered through your training code. + +## How It Works + +### Auto-Logging: Zero Code, Full Lineage + +When `mlflow.enabled: true` and an active MLflow run exists, Feast hooks into `get_historical_features()` and `get_online_features()` at the end of each call and writes structured metadata to the run: + +| Tag | Example | +|-----|---------| +| `feast.project` | `driver_ranking` | +| `feast.retrieval_type` | `historical` | +| `feast.feature_service` | `driver_activity_v1` | +| `feast.feature_views` | `driver_hourly_stats` | +| `feast.feature_refs` | `driver_hourly_stats:conv_rate, driver_hourly_stats:acc_rate` | +| `feast.entity_count` | `200` | +| `feast.feature_count` | `5` | +| `feast.job_submission_sec` | `0.43` (metric) | + +Even if features are passed as a list of refs rather than a `FeatureService` object, Feast auto resolves the matching feature service from the registry. The resolution is cached with a 5-minute TTL, so there is no registry overhead on every call. + +
+ Model metadata with Feast tags in MLflow + Feature lineage from data source to model +
+ +### The `store.mlflow` API + +The integration surfaces through a single property on `FeatureStore`: + +```python +from feast import FeatureStore +store = FeatureStore(".") + +with store.mlflow.start_run(run_name="v1_training"): + # Auto-logged: feature refs, feature views, entity count, duration + training_df = store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + model = train(training_df) + + # Saves feast_features.json alongside the model artifact + store.mlflow.log_model(model, "model") + + train_run_id = store.mlflow.active_run_id + +# Propagates feast.feature_service to the model version +store.mlflow.register_model(f"runs:/{train_run_id}/model", "driver_model") + +# Prediction: links back to the training run +with store.mlflow.start_run(run_name="batch_prediction"): + model = store.mlflow.load_model("models:/driver_model/1") + features = store.get_online_features( + features=store.get_feature_service("driver_activity_v1"), + entity_rows=[{"driver_id": 1001}], + ) + predictions = model.predict(...) +``` + +`store.mlflow` is lazy-initialized on first access. When MLflow is not installed or `enabled` is `false`, it returns `None` — so existing code that doesn't use MLflow is unaffected. + +### Model-to-Feature Resolution + +This is the capability that closes the loop between experiment tracking and production serving. Given any registered model URI, Feast can tell you exactly which feature service it needs: + +```python +fs_name = store.mlflow.resolve_features("models:/driver_model/1") +# Returns: "driver_activity_v1" +``` + +Resolution follows a precise chain: + +1. Check the model version tag `feast.feature_service` (set by `register_model`) +2. Fall back to the training run tag `feast.feature_service` (set by auto-logging) +3. Validate against the `feast_features.json` artifact to ensure the feature service projections match the features the model was actually trained on + +If there is a mismatch : say someone renamed a feature in the service after training — `resolve_features()` raises `FeastMlflowModelResolutionError` with a clear diff. No silent serving skew. + +This enables a powerful production pattern: your serving pipeline doesn't hardcode feature names. It resolves them from the model: + +```python +fs_name = store.mlflow.resolve_features(f"models:/driver_model/production") +features = store.get_online_features( + features=store.get_feature_service(fs_name), + entity_rows=request_entities, +) +``` + +Promote a new model version that uses different features, and the serving pipeline auto-adapts. + +
+ Registered model with feast.feature_service tag +
+ +### Training Reproducibility + +When `auto_log_entity_df: true`, the integration saves the entity DataFrame as a Parquet artifact on every historical retrieval. Later, you can reconstruct the exact training inputs: + +```python +entity_df = store.mlflow.get_training_entity_df(run_id="abc123") + +with store.mlflow.start_run(run_name="retrain_v2"): + new_df = store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() +``` + +Even without entity DataFrame archival, Feast always logs metadata : row count, column names, date range, or the SQL query — so you have an audit trail of what went into the model. + +
+ Entity DataFrame saved as artifact in MLflow +
+ +### Operations Audit Trail + +When `log_operations: true`, `feast apply` and `feast materialize` are logged to a dedicated MLflow experiment (`{project}-feast-ops`). These are self-contained runs : they don't require a user-initiated active run: + +```yaml +mlflow: + enabled: true + log_operations: true + ops_experiment_suffix: "-feast-ops" +``` + +Apply runs record which feature views, feature services, and entities were created, updated, or deleted. Materialize runs record the feature views, date range, and duration. This gives platform teams a time-series audit trail of every registry and materialization change. + +
+ Operations audit trail in MLflow +
+ +### Dataset Tracking + +For teams that use MLflow's dataset tracking, the integration provides an explicit API: + +```python +store.mlflow.log_training_dataset( + df=training_df, + dataset_name="driver_training_v1", + source="feast.get_historical_features", +) +``` + +This uses `mlflow.data.from_pandas` and `mlflow.log_input` to register the DataFrame as a dataset input on the active run. + +## Two Access Patterns + +The integration provides two ways to access MLflow, depending on your preference: + +### 1. `store.mlflow` — explicit, multi-store safe + +```python +store = FeatureStore(".") +store.mlflow.start_run(run_name="training") +store.mlflow.log_model(model, "model") +``` + +`store.mlflow` only exposes Feast-enhanced methods. For raw MLflow access, use the escape hatches: + +```python +store.mlflow.client # MlflowClient instance +store.mlflow.mlflow # raw mlflow module +``` + +### 2. `feast.mlflow` — drop-in module replacement + +```python +import feast.mlflow + +feast.mlflow.start_run(run_name="training") # Feast-enhanced +feast.mlflow.log_params({"lr": "0.01"}) # passthrough to mlflow +feast.mlflow.log_model(model, "model") # Feast-enhanced +``` + +`feast.mlflow` auto-discovers the most recently created `FeatureStore`. For Feast-specific methods (like `log_model`, `register_model`, `resolve_features`), it uses the enhanced version. For everything else (`log_params`, `set_tag`, `MlflowClient`, ...), it delegates to raw `mlflow`. One import, both worlds. + +## Feast UI Integration + +The Feast UI automatically surfaces MLflow data when the integration is enabled. Three new API endpoints power the UI: + +| Endpoint | What it shows | +|----------|---------------| +| `/api/mlflow-runs` | All Feast-tagged runs with linked registered models | +| `/api/mlflow-feature-usage` | Per-feature-view: run count, last used, associated models | +| `/api/mlflow-feature-models` | Reverse index: feature ref to registered models | + +The feature view detail page shows MLflow training run count, last-used date, and a table of registered models that depend on the view. The registry graph visualization draws edges from feature services through MLflow runs to registered models. + +When MLflow is not enabled, these endpoints return empty responses and the UI components are hidden — no visual noise for users who don't use MLflow. + +
+ Feast UI Feature List with MLflow model associations + Feast UI Feature View detail with MLflow usage +
+ +## Configuration Reference + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | `bool` | `false` | Master switch | +| `tracking_uri` | `string` | (env/default) | MLflow tracking URI | +| `auto_log` | `bool` | `true` | Auto-tag runs on retrieval | +| `auto_log_entity_df` | `bool` | `false` | Save entity DataFrame as artifact | +| `entity_df_max_rows` | `int` | `100000` | Skip artifact for large DataFrames | +| `log_operations` | `bool` | `false` | Log apply/materialize to ops experiment | +| `ops_experiment_suffix` | `string` | `"-feast-ops"` | Ops experiment name suffix | + +## Getting Started + +Install Feast with MLflow support: + +```bash +pip install feast[mlflow] +``` + +Add the `mlflow:` block to your `feature_store.yaml`, start an MLflow tracking server, and run your training code. Features are automatically linked to experiments from the first retrieval. + +
+ End-to-end lineage from data source to registered model +
+ +## Join the Conversation + +We'd love to hear how you're using (or plan to use) the Feast–MLflow integration. Reach out on [Slack](https://slack.feast.dev/) or [GitHub](https://github.com/feast-dev/feast) — issues and PRs welcome! + + diff --git a/infra/website/docs/blog/feast-offline-store-sox-metrics.md b/infra/website/docs/blog/feast-offline-store-sox-metrics.md new file mode 100644 index 00000000000..a41f951f604 --- /dev/null +++ b/infra/website/docs/blog/feast-offline-store-sox-metrics.md @@ -0,0 +1,386 @@ +--- +title: "Extending Feast Observability: Offline Store Metrics and SOX Audit Logging" +description: "Feast now captures RED metrics for offline store retrievals and emits structured SOX audit logs for both online and offline feature access — closing the observability gap between serving and training paths." +date: 2026-06-09 +authors: ["Jitendra Yejare"] +--- + +
+ Feast Offline Store Metrics and SOX Audit Logging — Prometheus metrics for offline retrievals and structured audit logs for compliance +
+ +# Extending Feast Observability: Offline Store Metrics and SOX Audit Logging + +In [our previous post](/blog/feast-feature-server-monitoring), we introduced built-in Prometheus metrics for the Feast feature server — covering the full online serving lifecycle from HTTP request handling through online store reads, on-demand feature transformations, materialization pipelines, and feature freshness tracking. + +That covered the **online** path. But production ML systems don't just serve features in real time — they also build training datasets through offline store retrievals. And for teams operating in regulated environments (financial services, healthcare, government), observability isn't enough. You need an **auditable record** of who accessed what data, when, and how much. + +This post covers two new capabilities added to Feast: + +1. **Offline Store RED Metrics** — Prometheus counters and histograms for offline store retrieval operations (request rate, error rate, latency, row counts) +2. **SOX Audit Logging** — Structured JSON audit log entries for both online and offline feature retrieval paths, routed to a dedicated `feast.audit` logger + +Together, these close the observability gap between online and offline operations and give compliance teams the structured audit trail they need. + +## Offline Store Metrics: Closing the Observability Gap + +The online feature server already had comprehensive metrics, but the offline store — where `get_historical_features` queries execute against your data warehouse to build training datasets — had zero instrumentation. This matters because training-serving skew, stalled pipelines, and data volume anomalies all originate in the offline path. + +### The Problem + +Without offline store metrics, teams faced three blind spots: + +- **Silent training failures** — An offline retrieval that returns incomplete data (or errors out) produces a corrupted training dataset. Models trained on bad data degrade in production, and without metrics, there's no signal until prediction quality drops. +- **Invisible pipeline stalls** — A `get_historical_features` call that normally takes 30 seconds but suddenly takes 10 minutes looks like a "hang" from the orchestrator's perspective. No latency metrics means no alerting until the pipeline times out. +- **Data volume anomalies** — If a typical training query returns 500K rows but suddenly returns 50K, something changed upstream. Without row count tracking, this silently propagates into model training. + +### How Feast Solves It + +Feast now automatically captures RED metrics (Rate, Errors, Duration) for every offline store retrieval — regardless of the backend. Whether you're running against BigQuery, Redshift, Snowflake, DuckDB, or local files, you get the same three Prometheus metrics out of the box: + +- **`feast_offline_store_request_total`** — Counts every retrieval, labeled by success/error. Set an alert and know immediately when training pipelines start failing. +- **`feast_offline_store_request_latency_seconds`** — Latency histogram with buckets tuned for offline workloads (`0.1s` to `10min`). Set SLOs and catch slow queries before pipelines time out. +- **`feast_offline_store_row_count`** — Row count histogram covering `100` to `5M` rows. Detect data volume anomalies before they reach model training. + +Metrics collection never interferes with your queries — if the metrics path fails for any reason, your offline retrieval completes normally. + +``` +# Alert when offline retrievals start failing +- alert: FeastOfflineStoreErrors + expr: rate(feast_offline_store_request_total{status="error"}[15m]) > 0 + for: 5m + labels: + severity: critical + annotations: + summary: > + Offline store retrievals are failing ({{ $value }} errors/sec). + Training pipelines may be producing incomplete datasets. +``` + +## Why SOX Audit Logging Matters + +For organizations subject to SOX (Sarbanes-Oxley), GDPR, HIPAA, or other regulatory frameworks, you need to answer questions like: + +- *Who accessed customer features at 3:47 PM on March 15th?* +- *Which feature views were involved in the training dataset built yesterday?* +- *How many rows of PII-adjacent data were retrieved by the batch scoring pipeline?* + +Before this change, answering these questions required parsing unstructured application logs and correlating timestamps across services. Feature stores sit at the intersection of data access and ML model behavior — yet most have no structured audit trail. + +Feast now emits **structured JSON audit entries** for both online and offline retrieval paths, routed to a dedicated `feast.audit` logger that can be independently sent to your SIEM, log aggregator, or compliance sink — without touching your operational log pipeline. + +What makes this production-ready: + +- **PII-minimized by design.** Entity key *names* are logged, not *values*. A compliance auditor sees "the ML pipeline accessed `user_id` features from `transaction_features` at 3:47 PM" without the log itself containing PII. +- **Dedicated logger.** Audit entries go to `feast.audit`, separate from the application logger. Route them to a SOX-compliant sink (Splunk, ELK with retention policies, S3 with WORM locks) independently. +- **Never breaks your serving path.** Audit logging is best-effort — a broken audit sink never affects feature serving latency or availability. +- **Zero overhead when disabled.** `audit_logging` defaults to `false`. Enable it only when you need it. + +## The New Metrics + +### Offline Store RED Metrics + +| Metric | Type | Labels | What It Answers | +|--------|------|--------|-----------------| +| `feast_offline_store_request_total` | Counter | `method`, `status` | What is my offline retrieval throughput and error rate? | +| `feast_offline_store_request_latency_seconds` | Histogram | `method` | How long are my training data queries taking? | +| `feast_offline_store_row_count` | Histogram | `method` | How much data are my offline retrievals returning? | + +The `method` label captures the retrieval type (`to_arrow`), and `status` is `success` or `error`. The latency histogram uses wide buckets tuned for offline workloads: `0.1s, 0.5s, 1s, 5s, 10s, 30s, 60s, 2min, 5min, 10min` — because offline queries can range from sub-second (small entity sets against local files) to minutes (large point-in-time joins against BigQuery or Redshift). + +The row count histogram uses exponential buckets: `100, 1K, 10K, 100K, 500K, 1M, 5M` — covering the range from small test retrievals to production training datasets. + +### SOX Audit Log Entries + +**Online feature request audit entry:** + +```json +{ + "event": "online_feature_request", + "timestamp": "2026-06-07T14:42:29.739Z", + "requestor_id": "service-account:ml-pipeline", + "entity_keys": ["driver_id"], + "entity_count": 5, + "feature_views": ["driver_hourly_stats"], + "feature_count": 3, + "status": "success", + "latency_ms": 12.45 +} +``` + +**Offline feature retrieval audit entry:** + +```json +{ + "event": "offline_feature_retrieval", + "timestamp": "2026-06-07T14:42:29.739Z", + "method": "to_arrow", + "start_time": "2026-06-07T14:42:29.697Z", + "end_time": "2026-06-07T14:42:29.739Z", + "feature_views": ["driver_hourly_stats"], + "feature_count": 3, + "row_count": 150000, + "status": "success", + "duration_ms": 42.39 +} +``` + +Each entry is a single JSON line, making it trivial to parse with `jq`, ingest into Elasticsearch, or stream to a Kafka topic for compliance processing. + +**Note on accessor identity:** Online audit entries include `requestor_id`, extracted from the Feast authentication layer (SecurityManager). Offline retrievals run as direct SDK calls in the user's own process (a notebook, Airflow task, or training script) — there is no server in the middle to extract auth context. In production SOX environments, offline accessor identity is typically established at the infrastructure level: the Kubernetes service account running the job, the IAM role accessing the data warehouse, or the CI/CD pipeline identity. A future enhancement could optionally capture identity from `os.getenv("USER")` or an explicit SDK parameter. + +## Enabling the New Metrics + +### YAML Configuration + +Add `offline_features` and `audit_logging` to your `feature_store.yaml`: + +```yaml +feature_server: + metrics: + enabled: true + resource: true + request: true + online_features: true + push: true + materialization: true + freshness: true + offline_features: true # NEW: Offline store RED metrics + audit_logging: true # NEW: SOX audit log entries +``` + +`offline_features` defaults to `true` when metrics are enabled (consistent with other categories). `audit_logging` defaults to `false` — it's opt-in because audit entries have a non-trivial cost (JSON serialization + I/O per request) and are only needed in regulated environments. + +### CLI + +When using `feast serve --metrics`, offline store metrics are enabled by default. Audit logging still requires the YAML toggle since it's opt-in. + +### Routing Audit Logs + +The `feast.audit` logger is a standard Python logger. Configure it like any other: + +```python +import logging + +audit_logger = logging.getLogger("feast.audit") +audit_logger.setLevel(logging.INFO) +audit_logger.propagate = False + +handler = logging.FileHandler("/var/log/feast/audit.log") +handler.setFormatter(logging.Formatter("%(message)s")) +audit_logger.addHandler(handler) +``` + +Or route to a JSON-aware sink in production: + +```yaml +# logging.yaml for production +loggers: + feast.audit: + level: INFO + propagate: false + handlers: [audit_file, splunk_forwarder] +``` + +## Key PromQL Queries for Offline Store + +**Throughput and errors:** + +```promql +# Offline retrieval rate +rate(feast_offline_store_request_total[5m]) + +# Offline error rate +sum(rate(feast_offline_store_request_total{status="error"}[5m])) + / sum(rate(feast_offline_store_request_total[5m])) +``` + +**Latency percentiles:** + +```promql +# Offline retrieval p95 latency +histogram_quantile(0.95, + sum(rate(feast_offline_store_request_latency_seconds_bucket[5m])) by (le)) + +# Average offline retrieval duration +rate(feast_offline_store_request_latency_seconds_sum[5m]) + / rate(feast_offline_store_request_latency_seconds_count[5m]) +``` + +**Row count analysis:** + +```promql +# Average rows per retrieval +feast_offline_store_row_count_sum / feast_offline_store_row_count_count + +# p95 row count (detect large retrievals) +histogram_quantile(0.95, + sum(rate(feast_offline_store_row_count_bucket[5m])) by (le)) +``` + +## Building Alerts for Offline Store + +### Offline Retrieval Failures + +```yaml +- alert: FeastOfflineStoreErrors + expr: rate(feast_offline_store_request_total{status="error"}[15m]) > 0 + for: 5m + labels: + severity: critical + annotations: + summary: > + Offline store retrievals are failing. + Training pipelines may be producing incomplete datasets. +``` + +### Slow Offline Queries + +```yaml +- alert: FeastOfflineStoreSlowQuery + expr: | + histogram_quantile(0.95, + sum(rate(feast_offline_store_request_latency_seconds_bucket[5m])) by (le) + ) > 300 + for: 5m + labels: + severity: warning + annotations: + summary: > + Offline store p95 latency is {{ $value | humanizeDuration }}. + Training pipelines may be stalling. +``` + +### Row Count Anomaly + +```yaml +- alert: FeastOfflineStoreRowCountDrop + expr: | + feast_offline_store_row_count_sum / feast_offline_store_row_count_count + < 0.5 * avg_over_time( + (feast_offline_store_row_count_sum / feast_offline_store_row_count_count)[1d:1h]) + for: 10m + labels: + severity: warning + annotations: + summary: > + Average rows per offline retrieval dropped by >50%. + Possible upstream data issue. +``` + +## The Extended Grafana Dashboard + +We've extended the existing Feast Grafana dashboard with a dedicated **Offline Store** section containing six new panels: + +- **Offline Store Request Rate** — Rate of offline retrievals by method and status +- **Offline Store Total Requests** — Cumulative request counts (stat panel) +- **Offline Store Retrieval Latency (p50/p95/p99)** — Latency percentile time series +- **Offline Store Row Count Distribution** — Row count percentiles over time +- **Avg Offline Retrieval Duration** — Average duration per method +- **Offline Store Error Rate** — Gauge showing current error percentage with threshold coloring + +
+ Grafana dashboard showing dedicated offline store containing six new panels +
+ +These panels sit alongside the existing online store panels, giving you a single dashboard that covers both serving paths. + +For SOX compliance, a separate **Audit Trail** dashboard powered by Loki visualizes: + +- **Total Audited Events** — Count of all audited access events +- **Online vs Offline Access Timeline** — Stacked time series showing access patterns +- **Offline Data Volume** — Total rows retrieved over time, flagging bulk data exports +- **Anomaly Detection** — Large row counts and slow queries that may need compliance review + +
+ Grafana dashboard showing SOX compliance and access containing five new panels +
+ +- **Live Audit Log Stream** — Raw structured audit entries, expandable for investigation + +
+ Grafana dashboard showing audit logs for offline store +
+ + +## Updated Metrics Summary + +| Category | Metric | What It Answers | +|----------|--------|-----------------| +| **Online** Request | `feast_feature_server_request_total` | What is my online throughput and error rate? | +| **Online** Request | `feast_feature_server_request_latency_seconds` | What are my online p50/p99 latencies? | +| **Online** Features | `feast_online_features_entity_count` | What is my online traffic shape? | +| **Online** Store Read | `feast_feature_server_online_store_read_duration_seconds` | Is my online store the bottleneck? | +| ODFV Transform | `feast_feature_server_transformation_duration_seconds` | How expensive are my read-path transforms? | +| ODFV Transform | `feast_feature_server_write_transformation_duration_seconds` | How expensive are my write-path transforms? | +| Push | `feast_push_request_total` | Is my ingestion pipeline sending data? | +| Materialization | `feast_materialization_total` | Are my pipelines succeeding? | +| Materialization | `feast_materialization_duration_seconds` | How long do my pipelines take? | +| Freshness | `feast_feature_freshness_seconds` | How stale is the data my models are using? | +| Resource | `feast_feature_server_cpu_usage / memory_usage` | Is my server healthy? | +| **Offline** Request | `feast_offline_store_request_total` | What is my offline retrieval throughput? | +| **Offline** Latency | `feast_offline_store_request_latency_seconds` | How long are my training queries taking? | +| **Offline** Row Count | `feast_offline_store_row_count` | How much data are retrievals returning? | +| **Audit** | `feast.audit` logger (online) | Who requested which features, when? | +| **Audit** | `feast.audit` logger (offline) | Which training datasets were built, with how much data? | + +## How to Try It + +### Automated Demo + +We've extended the [feast-prometheus-metrics](https://github.com/ntkathole/feast-automated-setups/tree/main/feast-prometheus-metrics) automated demo to include offline store metrics and SOX audit logging. The extended traffic generator exercises both online and offline paths: + +```bash +# Clone and run +git clone https://github.com/ntkathole/feast-automated-setups.git +cd feast-automated-setups/feast-prometheus-metrics + +# Run setup (uses feast from your environment) +./setup.sh + +# Generate extended traffic including offline retrievals +python3 generate_traffic_extended.py \ + --url http://localhost:6566 \ + --duration 120 \ + --repo-path workspace/feast_demo/feature_repo \ + --log-dir workspace/logs +``` + +After traffic generation, check the audit log: + +```bash +# View structured audit entries +cat workspace/logs/feast_audit.log | python3 -m json.tool + +# Count by event type +cat workspace/logs/feast_audit.log | \ + python3 -c "import sys,json; events=[json.loads(l)['event'] for l in sys.stdin]; print({e:events.count(e) for e in set(events)})" +``` + +### Manual Verification + +Verify offline store metrics are being emitted: + +```bash +# Check the Prometheus metrics endpoint for offline store metrics +curl -s http://localhost:8000 | grep feast_offline + +# Query Prometheus directly +curl -s 'http://localhost:9090/api/v1/query?query=feast_offline_store_request_total' +``` + +### Enable in Your Deployment + +1. **Update `feature_store.yaml`** — Add `offline_features: true` and `audit_logging: true` to the metrics block +2. **Configure audit log routing** — Set up a handler for the `feast.audit` logger in your logging config +3. **Import the updated Grafana dashboard** — Add the offline store panels to your existing dashboard +4. **Set up alerts** — Start with offline retrieval failures and row count anomalies + + +We're excited to bring full-lifecycle observability to Feast — covering both the real-time serving path and the batch training path — and welcome feedback from the community! + +--- + +*References:* +- *[Existing blog: Monitoring Your Feast Feature Server with Prometheus and Grafana](https://feast.dev/blog/feast-feature-server-monitoring/)* +- *[Feast Prometheus Metrics Demo](https://github.com/ntkathole/feast-automated-setups/tree/main/feast-prometheus-metrics)* diff --git a/infra/website/docs/blog/feast-online-server-performance-tuning.md b/infra/website/docs/blog/feast-online-server-performance-tuning.md new file mode 100644 index 00000000000..ffe29910b9e --- /dev/null +++ b/infra/website/docs/blog/feast-online-server-performance-tuning.md @@ -0,0 +1,338 @@ +--- +title: "Tuning the Feast Feature Server for Sub-2ms Online Serving" +description: "A practical guide to achieving low-latency, high-throughput feature serving with Feast on Kubernetes — from default configuration to production-grade performance with pre-computed feature vectors and benchmarks at every step." +date: 2026-06-02 +authors: ["Nikhil Kathole"] +--- + +**Feast supports production-grade worker configuration, connection pooling, async reads, batched pipelines, serialization optimizations, and pre-computed feature vectors for the Python feature server.** This post walks through a real-world performance tuning exercise in two stages: first, server and client tuning that brings p99 latency down to **sub-5ms** for single-row requests; then, **pre-computed feature vectors** that push it further to **sub-2ms p99** — regardless of how many feature views your FeatureService spans. We share the benchmarking methodology, the exact configuration changes, and the measured impact of each step so you can apply the same approach to your own deployments. + +--- + +## The Problem + +When you deploy Feast on Kubernetes using the [Feast Operator](https://docs.feast.dev/how-to-guides/production-deployment-topologies), the default configuration is designed for simplicity — a single Gunicorn worker, short keep-alive timeouts, and frequent registry refreshes. This is fine for development but leaves significant performance on the table for production workloads where every millisecond matters. + +We set out to answer a practical question: **how low can we push the Feast online server's p99 latency, and what does it take to get there?** + +--- + +## Test Environment + +| Component | Configuration | +|-----------|--------------| +| **Online Store** | Redis 7.0.12 (standalone, in-cluster) | +| **Registry** | PostgreSQL 16 (SQL registry) | +| **Platform** | Kubernetes | +| **Deployment** | Feast Operator with `FeatureStore` CR | + +We used a banking feature store project with multiple feature views spanning customer demographics, transactions, and behavioral profiles. + +All benchmarks run 200 iterations (after 30–50 warmup) for each scenario, measuring p50, p95, p99, and mean latency. Throughput is measured with 10 concurrent workers over 15 seconds. + +--- + +## Three Access Modes + +Feast supports three ways to retrieve online features. Understanding how each one works is key to knowing where latency comes from — and where to optimize. + +### REST API + +``` +Client → HTTP POST (JSON) → Gunicorn/FastAPI Server → Redis mget() → JSON response +``` + +The simplest and most common pattern. Your application sends a JSON request to the feature server's `/get-online-features` endpoint. The server holds persistent Redis connections and a pre-loaded registry, so each request is just a Redis read plus JSON serialization. HTTP keep-alive reuses TCP/TLS connections across requests. + +### Direct SDK + +``` +Client (Python) → FeatureStore SDK → Redis mget() directly +``` + +The Python SDK connects to Redis directly — no HTTP hop, no JSON overhead. However, it pays for in-process registry lookups and entity key serialization on every call, and reads each FeatureView sequentially. + +### Remote SDK + +``` +Client (Python SDK) → HTTP POST → Feature Server → Redis → JSON → Client +``` + +The SDK delegates feature retrieval to a remote feature server over HTTP. This combines the worst of both worlds: SDK-side overhead *plus* an HTTP round-trip. Without connection pooling, each call creates a new TCP connection and TLS handshake. + +--- + +## Baseline: Default Configuration + +With no tuning applied — a single Gunicorn worker, default timeouts, and no connection pooling: + +| Mode | p99 (1 row) | p99 (5 rows) | Throughput | +|------|----------------|-------------------|------------| +| **REST API** | 6.92 ms | 4.94 ms | 480 RPS | +| **Direct SDK** | 5.83 ms | 5.59 ms | — | +| **Remote SDK** | 11.71 ms | **74.31 ms** | ~2 RPS | + +The REST API and Direct SDK are already in the 5–7ms range out of the box, but the Remote SDK fails badly — p99 spiking to **74ms** at just 5 rows due to per-request TCP/TLS setup overhead. This is our starting point. + +--- + +## Server-Side Configuration + +These are changes you apply to the **feature server deployment** — no code changes needed, just configuration via the `FeatureStore` CR and Redis runtime settings. + +### Worker Tuning via the Feast Operator + +The Feast Operator exposes `workerConfigs` in the `FeatureStore` CR, letting you tune the Gunicorn server without rebuilding images: + +```yaml +apiVersion: feast.dev/v1alpha1 +kind: FeatureStore +spec: + services: + onlineStore: + server: + workerConfigs: + workers: -1 # Auto: 2 × CPU cores + 1 + keepAliveTimeout: 120 # Reuse connections longer + maxRequests: 5000 # Recycle workers to prevent memory leaks + maxRequestsJitter: 200 # Stagger recycling + registryTTLSeconds: 300 # Reduce registry refresh overhead + workerConnections: 2000 # High-concurrency support +``` + +Setting `workers: -1` on a 4-core pod gives 9 Gunicorn workers, each with its own event loop and Redis connection. This is the **single most impactful change** — it transforms the server from single-threaded to multi-process, dropping 5-row p99 from ~10ms to ~8ms and putting us on the path to sub-5ms. + +### Redis Runtime Tuning + +Three Redis settings made a measurable difference: + +- **`hz 100`** (default 10) — Redis processes expired keys and timeouts 10x faster, reducing tail latency spikes. +- **`tcp-keepalive 60`** (default 300) — Detects dead connections 5x faster, freeing resources sooner. +- **`save ""`** (disable RDB persistence) — Eliminates periodic snapshot I/O that causes 10–50ms p99 spikes. Since features are materialized from the offline store and reconstructible at any time, persistence is unnecessary. + +### High Availability and Auto-Scaling + +For production, we added horizontal scaling and availability guarantees using the Feast Operator's [built-in HA support](https://docs.feast.dev/how-to-guides/feast-snowflake-gcp-aws/scaling-feast): + +```yaml +spec: + replicas: 2 + services: + onlineStore: + server: + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "2" + memory: 2Gi + scaling: + autoscaling: + minReplicas: 2 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + pdb: + minAvailable: 1 +``` + +When scaling is enabled, the operator auto-injects pod anti-affinity and zone topology spread constraints, ensuring replicas land on different nodes for resilience. With HPA, the cluster auto-scales based on CPU utilization — we observed it scaling from 2 to 3 pods in response to load during benchmarks. At 10 pods with 9 workers each, theoretical throughput reaches ~7,180 RPS (~25.8M RPH). + +### Server-side quick wins summary + +1. **Set `workers: -1`** — single most impactful change +2. **Disable Redis persistence** — `CONFIG SET save ""` +3. **Set `registryTTLSeconds: 300`** — reduce registry refresh overhead +4. **Use `replicas: 2`** minimum with HPA for burst capacity +5. **Set resource limits** — defaults are far too low for production + +--- + +## Client-Side Configuration + +These are changes you apply on the **client** — how the SDK connects to the feature server and which access mode you choose. + +### Connection Pooling for the Remote SDK + +The biggest problem with the Remote SDK was that every call created a brand-new `requests.Session`, established a fresh TCP connection, negotiated TLS, and then threw it all away — adding 2–4ms per call for HTTPS endpoints. + +Feast now includes `HttpSessionManager` — a thread-safe, singleton session manager that reuses HTTP connections across requests with configurable pooling and retry: + +```yaml +online_store: + type: remote + path: https://feast-server:443 + connection_pool_size: 50 + connection_idle_timeout: 300 + connection_retries: 3 +``` + +This dropped Remote SDK 5-row p99 from **74ms to 21ms** — a 72% reduction — by eliminating the per-request TLS handshake. + +### Choosing the right access mode + +| Use Case | Recommended Mode | Why | +|----------|-----------------|-----| +| **Application serving** | REST API | Sub-5ms single-row p99, simplest integration, 718 RPS per pod | +| **Python ML pipeline** | Direct SDK | No HTTP hop, sub-5ms p99, native protobuf | +| **Async Python applications** | Async Direct SDK | Non-blocking, batched pipeline, sub-5ms p99 | +| **Cross-cluster serving** | Remote SDK + pooling | When the client can't reach Redis directly; 760 RPS with pooling | + +--- + +## Code Enhancements in Feast + +Beyond configuration, several code-level improvements in Feast itself contributed to reaching sub-5ms p99. These require no user configuration — just upgrading to the latest Feast version. + +### Serialization Optimization + +The feature server used `google.protobuf.json_format.MessageToDict` to convert protobuf responses to JSON — a generic, reflection-based serializer that was a meaningful fraction of server-side latency. Replacing it with an optimized custom dict builder delivered a **66% throughput increase** (432 to 718 RPS) and **72% reduction in tail latency under load** (132ms to 37ms p99). + +### Async Redis Reads with Batched Pipeline + +The `RedisOnlineStore` had async support (`online_read_async` with `redis_asyncio`), but the `async_supported` property was not overridden, so the feature server never used it. Enabling it unlocks non-blocking I/O on the server side — the FastAPI handler calls `get_online_features_async` directly instead of wrapping the sync path in `run_in_threadpool`. + +Additionally, the base class async path issued O(N_feature_views) separate round trips to Redis via `asyncio.gather`. We added a `get_online_features_async` override to `RedisOnlineStore` that batches all HMGET commands across all feature views into a **single async pipeline execution** (O(1) round trips), matching the existing sync batched pipeline. This cut async 5-row p99 from ~11ms to **5.6ms** — a 49% improvement. + +### Cached Per-Request Checks + +`_check_versioned_read_support()` performed up to 7 lazy module imports on **every request** to determine if the current online store supports versioned reads. We cache the result per store instance, resolving imports once and eliminating ~0.5–1ms of overhead per request. + +### Skip Duplicate Feature Resolution + +When auth is `no_auth` (the common case), the feature server was resolving feature views solely to check permissions (which are no-ops), then resolving them again inside `get_online_features`. We skip the first resolution entirely, avoiding a redundant registry lookup. + +### Session Wrapping Fix + +The `rest_error_handling_decorator` re-wrapped cached `requests.Session` HTTP methods on every call. After ~1000 requests, this caused progressive performance degradation and eventually a `RecursionError`. We now wrap each method exactly once per session lifetime, fixing Remote SDK stability and enabling it to sustain **760 RPS**. + +--- + +## Final Results + +After applying all server-side configuration, client-side configuration, and code enhancements: + +### Stage 1: Tuning only (sub-5ms target) + +| Mode | p50 (1 row) | p99 (1 row) | p50 (5 rows) | p99 (5 rows) | Throughput | +|------|----------|----------|----------|----------|------------| +| **REST API** | 3.34 ms | **4.61 ms** | 7.88 ms | 11.32 ms | 718 RPS | +| **REST API (FeatureService)** | 4.21 ms | **6.15 ms** | 9.15 ms | 17.43 ms | — | +| **Direct SDK** | 3.12 ms | **4.21 ms** | 3.29 ms | **4.60 ms** | 402 RPS | +| **Direct SDK (FeatureService)** | 3.48 ms | **5.70 ms** | 3.44 ms | **5.10 ms** | — | +| **Async Direct SDK** | 3.25 ms | **6.25 ms** | 3.47 ms | **8.72 ms** | — | +| **Async Direct SDK (FeatureService)** | 3.60 ms | **4.84 ms** | 3.76 ms | **5.13 ms** | — | +| **Remote SDK** | 3.34 ms | **5.30 ms** | 8.15 ms | 11.63 ms | 760 RPS | +| **Remote SDK (FeatureService)** | 3.78 ms | **5.17 ms** | 9.86 ms | 16.06 ms | — | + +### Stage 2: Pre-computed vectors (sub-2ms target) + +| Batch Size | p50 Regular | p99 Regular | p50 Precomputed | p99 Precomputed | Speedup (p50) | +|---|---|---|---|---|---| +| 1 | 5.95 ms | 10.74 ms | **0.98 ms** | **1.70 ms** | 6.1x | +| 5 | 9.66 ms | 44.91 ms | **1.37 ms** | **3.00 ms** | 7.1x | +| 10 | 16.60 ms | 60.37 ms | **1.81 ms** | **2.07 ms** | 9.2x | +| 50 | 60.07 ms | 120.12 ms | **5.27 ms** | **7.49 ms** | 11.4x | +| 100 | 85.58 ms | 208.18 ms | **9.48 ms** | **114.38 ms** | 9.0x | +| 500 | 218.79 ms | 424.91 ms | **40.25 ms** | **198.13 ms** | 5.4x | + +**Key takeaways:** + +- **Stage 1 (tuning)** gets all SDK modes to **sub-5ms p99** for single-row requests — REST API at 4.61ms, Direct SDK at 4.21ms, Async SDK at 4.84ms. +- **Stage 2 (pre-computed vectors)** pushes latency to **sub-2ms p99** for single-row requests — a 6x improvement over the tuned regular path. +- **REST API** delivers the best throughput at **718 RPS** (2.6M RPH); **Remote SDK** sustains **760 RPS** after the session wrapping fix. +- For FeatureServices spanning multiple feature views, **`precompute_online=True` is the single most impactful optimization** — it changes the read complexity from O(N feature views) to O(1). +- At large batch sizes, the bottleneck shifts from store I/O to Python CPU overhead (protobuf deserialization). For these workloads, split large requests into smaller batches on the client side. + +--- + +## A Note on Online Store Selection + +All benchmarks in this post used a **standalone Redis pod** running in the same Kubernetes cluster as the feature server. Production deployments often use managed services — here's how that changes the picture. + +**Managed Redis** (ElastiCache, Memorystore, Azure Cache for Redis) provides dedicated compute, optimized networking, cluster mode for sharding, and automatic failover. In our benchmarks, Redis RTT was ~0.5ms (in-cluster). A managed instance in the **same availability zone** would deliver comparable latency with more consistent tail behavior. Cross-AZ hops add 1–2ms per request. + +**DynamoDB** offers zero operational overhead and automatic scaling. When the feature server runs in the **same AWS region and VPC**, single-digit millisecond reads are typical (1–5ms for eventually consistent reads). With [DAX](https://aws.amazon.com/dynamodb/dax/), read latency drops to microseconds for cached items. A same-region setup could deliver comparable sub-5ms p99 for single-row reads. + +Feast also supports PostgreSQL, SQLite, Snowflake, Bigtable, and more. The general rule is: **the online store is the single largest factor in `get_online_features()` latency** — choose based on your latency budget, throughput needs, and operational requirements. The tuning steps in this post (worker configuration, registry caching, connection pooling, serialization optimization) apply equally to all stores — they optimize the layers above. + +--- + +## Pre-computed Feature Vectors + +The tuning steps above achieve our first target: **sub-5ms p99** for single-row requests. But for FeatureServices spanning multiple feature views, per-FV read fan-out becomes the dominant bottleneck — each request issues N separate store reads, N protobuf deserializations, and N response assemblies. To reach our final target of **sub-2ms**, we need to eliminate this fan-out entirely. + +**Pre-computed feature vectors** do exactly that: at materialize time, all features for a FeatureService are assembled into a single serialized blob per entity. At read time, one key lookup replaces N feature-view reads — reducing the operation from O(N feature views) to O(1) and delivering **sub-2ms p99 latency**. + +### How it works + +1. **Define** a FeatureService with `precompute_online=True`: + +```python +scoring_service = FeatureService( + name="realtime_scoring", + features=[user_profile_fv, transaction_fv, risk_fv], + precompute_online=True, +) +``` + +2. **Apply** and **materialize** as usual — vectors are built automatically: + +```bash +feast apply +feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S") +``` + +Feast detects which FeatureServices have `precompute_online=True` and rebuilds their pre-computed vectors after the per-feature-view writes complete. Vectors are also refreshed automatically on `feast push`. + +3. **Read** features as usual — the server automatically uses the pre-computed path: + +```python +features = store.get_online_features( + features=store.get_feature_service("realtime_scoring"), + entity_rows=[{"user_id": "U12345"}], + full_feature_names=True, +) +``` + +### Design decisions + +- **Store-agnostic**: The pre-computed logic lives in the base `OnlineStore` class and works with all backends (Redis, DynamoDB, PostgreSQL, etc.). No store-specific code is needed. +- **Opt-in**: `precompute_online` defaults to `False`. Existing deployments are completely unaffected. +- **Strict error handling**: When `precompute_online=True`, there is no silent fallback to per-FV reads. If vectors are missing or stale, the server raises a `RuntimeError`, making problems visible immediately. +- **Schema-aware**: A fingerprint of feature names detects schema changes and rejects stale vectors, with column-order-independent comparison. +- **Per-FV TTL enforcement**: Individual feature view TTLs are checked within the pre-computed blob. +- **Materialized view pattern**: Conceptually similar to a database materialized view — trades storage for read speed with explicit refresh. + +### Benchmark: precomputed vs regular path + +We benchmarked a FeatureService spanning multiple feature views against the same features read via the regular per-feature-view path. All numbers from the same pod, same run, 200 iterations with 30 warmup. + +| Batch Size (rows/request) | p50 Regular | p50 Precomputed | p99 Regular | p99 Precomputed | Speedup (p50) | +|---|---|---|---|---|---| +| 1 | 5.95 ms | **0.98 ms** | 10.74 ms | **1.70 ms** | 6.1x | +| 5 | 9.66 ms | **1.37 ms** | 44.91 ms | **3.00 ms** | 7.1x | +| 10 | 16.60 ms | **1.81 ms** | 60.37 ms | **2.07 ms** | 9.2x | +| 50 | 60.07 ms | **5.27 ms** | 120.12 ms | **7.49 ms** | 11.4x | + +For the typical production use case of 1–10 rows per inference request, pre-computed vectors deliver **sub-2ms p99** — well under any reasonable SLA target. The speedup ranges from **6x to 9x** depending on batch size, with p50 consistently under 2ms for up to 10 rows. + +--- + +## Try It Yourself + +To deploy the same setup: + +1. Deploy Feast with the Feast Operator using a `FeatureStore` CR with `workerConfigs` +2. Use Redis as the online store and PostgreSQL for the registry +3. Apply the [production tuning guide](https://docs.feast.dev/how-to-guides/online-server-performance-tuning) for worker configuration, registry caching, and scaling +4. For FeatureServices spanning multiple feature views, enable `precompute_online=True` and materialize — see the [feature service docs](https://docs.feast.dev/getting-started/concepts/feature-retrieval#pre-computed-feature-vectors-precompute_online) +5. Monitor with [built-in Prometheus metrics](https://docs.feast.dev/reference/feature-servers/python-feature-server) — `feast_feature_server_request_latency_seconds` is your primary SLI + +We'd love to hear about your production performance results. Join the conversation on [Feast Slack](https://slack.feast.dev) or open an issue on [GitHub](https://github.com/feast-dev/feast). diff --git a/infra/website/docs/blog/feast-oracle-offline-store.md b/infra/website/docs/blog/feast-oracle-offline-store.md new file mode 100644 index 00000000000..e8ce13d81ae --- /dev/null +++ b/infra/website/docs/blog/feast-oracle-offline-store.md @@ -0,0 +1,274 @@ +--- +title: "Feast Meets Oracle: Unlocking Feature Store for Oracle Database Users" +description: Oracle Database is now a fully featured Feast offline store, integrated with Kubernetes-native operators. This enables teams to leverage their existing Oracle infrastructure for scalable, production ML feature engineering. +date: 2026-03-16 +authors: ["Aniket Paluskar", "Srihari Venkataramaiah"] +--- + +
+ Feast and Oracle Database +
+ +# Feast Meets Oracle: Unlocking Feature Store for Oracle Database Users + +## The Problem: Your Data Is Already in Oracle — Why Move It? + +If you work in a Fortune 500 company, chances are your most valuable data lives in Oracle Database. It is the one of the most widely used enterprise database for a reason — decades of battle-tested reliability, performance, and governance have made it the backbone of mission-critical systems across finance, healthcare, telecommunications, government, and retail. + +But here's the friction: when ML teams want to build features for their models, they typically export data *out* of Oracle into some other system — a data lake, a warehouse, a CSV on someone's laptop. That data movement introduces latency, staleness bugs, security blind spots, and an entire class of silent failures that only surface when a model starts degrading in production. + +**What if you didn't have to move your data at all?** + +With Feast's new Oracle offline store support — now fully integrated into the Feast Kubernetes operator — you can define, compute, and serve ML features directly from your existing Oracle infrastructure. No data migration. No pipeline duct tape. No compromises. + +--- + +## What's New + +Oracle Database is now a first-class offline store in Feast, supported across the full stack: + +| Layer | What Changed | +|---|---| +| **Python SDK** | `OracleOfflineStore` and `OracleSource` — a complete offline store implementation built on `ibis-framework[oracle]` | +| **Feast Operator (v1 API)** | `oracle` is a validated persistence type in the `FeatureStore` CRD, with Secret-backed credential management | +| **CRD & Validation** | Kubernetes validates `oracle` at admission time — bad configs are rejected before they ever reach the operator | +| **Type System** | Full Oracle-to-Feast type mapping covering `NUMBER`, `VARCHAR2`, `CLOB`, `BLOB`, `BINARY_FLOAT`, `TIMESTAMP`, and more | +| **Documentation** | Reference docs for the [Oracle offline store](https://docs.feast.dev/reference/offline-stores/oracle) and [Oracle data source](https://docs.feast.dev/reference/data-sources/oracle) | + +This isn't a thin wrapper or a partial integration. The Oracle offline store supports the complete Feast offline store interface: + +- **`get_historical_features`** — point-in-time correct feature retrieval for training datasets, preventing future data leakage +- **`pull_latest_from_table_or_query`** — fetch the most recent feature values +- **`pull_all_from_table_or_query`** — full table scans for batch processing +- **`offline_write_batch`** — write feature data back to Oracle +- **`write_logged_features`** — persist logged features for monitoring and debugging + +--- + +## Why This Matters: Oracle Is Where the Enterprise Lives + +Oracle Database isn't just another backend option. It is the database that runs the world's banks, hospitals, supply chains, and telecom networks. When we say "number one enterprise database," we mean it in terms of: + +- **Installed base** — More Fortune 100 companies run Oracle than any other database +- **Data gravity** — Petabytes of the world's most regulated, most valuable data already sits in Oracle +- **Operational maturity** — Decades of enterprise features: partitioning, RAC, Data Guard, Advanced Security, Audit Vault + +For ML teams in these organizations, the path to production has always involved a painful detour: extract data from Oracle, load it somewhere else, build features there, then figure out how to serve them. Every step in that chain is a potential point of failure, a security review, and a compliance headache. + +Feast's Oracle integration eliminates the detour entirely. Your features are computed where your data already has governance, backup, encryption, and access controls in place. + +--- + +## How It Works: From Oracle Table to Production Features + +### Step 1: Configure your feature store + +Point Feast at your Oracle database in `feature_store.yaml`: + +```yaml +project: my_project +registry: data/registry.db +provider: local +offline_store: + type: oracle + host: oracle-db.example.com + port: 1521 + user: feast_user + password: ${DB_PASSWORD} + service_name: ORCL +online_store: + path: data/online_store.db +``` + +Feast supports three Oracle connection modes — `service_name`, `sid`, or `dsn` — so it fits however your DBA has set things up: + +```yaml +# Using SID +offline_store: + type: oracle + host: oracle-db.example.com + port: 1521 + user: feast_user + password: ${DB_PASSWORD} + sid: ORCL + +# Using full DSN +offline_store: + type: oracle + host: oracle-db.example.com + port: 1521 + user: feast_user + password: ${DB_PASSWORD} + dsn: "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle-db.example.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)))" +``` + +### Step 2: Define features backed by Oracle tables + +```python +from feast import FeatureView, Field, Entity +from feast.types import Float64, Int64 +from feast.infra.offline_stores.contrib.oracle_offline_store.oracle_source import OracleSource +from datetime import timedelta + +customer = Entity(name="customer_id", join_keys=["customer_id"]) + +customer_transactions = OracleSource( + name="customer_txn_source", + table_ref="ANALYTICS.CUSTOMER_TRANSACTIONS", + event_timestamp_column="TXN_TIMESTAMP", +) + +customer_features = FeatureView( + name="customer_transaction_features", + entities=[customer], + ttl=timedelta(days=30), + schema=[ + Field(name="avg_txn_amount_30d", dtype=Float64), + Field(name="txn_count_7d", dtype=Int64), + Field(name="max_txn_amount_90d", dtype=Float64), + ], + source=customer_transactions, +) +``` + +### Step 3: Retrieve features for training + +```python +from feast import FeatureStore +import pandas as pd + +store = FeatureStore(repo_path=".") + +entity_df = pd.DataFrame({ + "customer_id": [101, 102, 103, 104], + "event_timestamp": pd.to_datetime(["2026-01-15", "2026-01-16", "2026-02-01", "2026-02-15"]), +}) + +training_df = store.get_historical_features( + entity_df=entity_df, + features=[ + "customer_transaction_features:avg_txn_amount_30d", + "customer_transaction_features:txn_count_7d", + "customer_transaction_features:max_txn_amount_90d", + ], +).to_df() +``` + +Feast performs point-in-time correct joins against Oracle — no future data leaks into your training set, and the query runs *inside* Oracle, not in some external compute engine. + +### Step 4: Serve features in production + +```python +store.materialize_incremental(end_date=datetime.utcnow()) + +features = store.get_online_features( + features=[ + "customer_transaction_features:avg_txn_amount_30d", + "customer_transaction_features:txn_count_7d", + ], + entity_rows=[{"customer_id": 101}], +).to_dict() +``` + +--- + +## Kubernetes-Native: The Feast Operator and Oracle + +For teams running Feast on Kubernetes, the Feast operator now natively manages Oracle-backed feature stores through the `FeatureStore` custom resource. + +### Create a Secret with your Oracle credentials + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: oracle-offline-store +type: Opaque +stringData: + oracle: | + host: oracle-db.example.com + port: "1521" + user: feast_user + password: changeme + service_name: ORCL +``` + +### Define a FeatureStore custom resource + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: production-feature-store +spec: + services: + offlineStore: + persistence: + store: + type: oracle + secretRef: + name: oracle-offline-store +``` + +### Apply and let the operator do the rest + +```bash +kubectl apply -f feature-store.yaml +``` + +The operator validates the configuration against the CRD schema (rejecting invalid types at admission), reads the Secret, merges the Oracle connection parameters into the generated Feast config, and deploys the offline store service. Credential rotation, version upgrades, and config changes are all handled through Kubernetes-native reconciliation — the same operational model your platform team already knows. + +Because credentials live in Kubernetes Secrets, they integrate naturally with external secret managers like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault through standard Kubernetes mechanisms. Oracle credentials never appear in plain text in your manifests or CI/CD logs. + +--- + +## Real-World Use Cases + +### Financial Services: Fraud Detection Without Data Movement + +A global bank running Oracle for core banking can now build fraud detection features — transaction velocity, merchant category patterns, geographic anomaly scores — directly from their existing Oracle tables. The features stay within the same security perimeter, audit trail, and encryption boundary as the source data. No ETL pipeline to a secondary warehouse means no replication lag and no additional attack surface. + +### Healthcare: Predictive Models on Regulated Data + +Hospitals and insurers with patient data in Oracle can compute ML features (readmission risk scores, treatment outcome signals, resource utilization patterns) without copying PHI into a less governed system. Feast's feature definitions become the documented lineage trail that compliance teams need. + +### Telecommunications: Network Optimization at Scale + +Telcos managing billions of CDRs and network metrics in Oracle can build churn prediction, capacity forecasting, and service quality features on top of the data they already have — avoiding the cost and latency of replicating to a separate analytical platform. + +### Retail: Demand Forecasting from Point-of-Sale Data + +Retailers with Oracle-backed inventory and transaction systems can build demand forecasting and recommendation features without standing up a parallel data infrastructure. Features computed in Oracle can be materialized to the online store for real-time serving at the edge. + +--- + +## Under the Hood: Built on ibis + +The Oracle offline store is built on the [ibis framework](https://ibis-project.org/), a portable Python dataframe API that compiles to native SQL for each backend. This means: + +- **Queries execute inside Oracle** — ibis translates Feast's retrieval operations into Oracle SQL, pushing computation to where the data lives +- **No intermediate data movement** — results are streamed back as Arrow tables without staging in a temporary system +- **Full Oracle type fidelity** — the type mapping covers the complete spectrum of Oracle data types, including `NUMBER`, `VARCHAR2`, `NVARCHAR2`, `CHAR`, `CLOB`, `NCLOB`, `BLOB`, `RAW`, `BINARY_FLOAT`, `BINARY_DOUBLE`, `DATE`, `TIMESTAMP`, `INTEGER`, `SMALLINT`, and `FLOAT` +- **Automatic DATE-to-TIMESTAMP casting** — Oracle's `DATE` type (which includes time components, unlike SQL standard) is properly handled + +--- + +## Getting Started + +Install Feast with Oracle support: + +```bash +pip install 'feast[oracle]' +``` + +For Kubernetes deployments, ensure you're running Feast operator v0.61.0+ with the v1 API. + +The full configuration reference, functionality matrix, and data source documentation are available in the Feast docs: + +- [Oracle Offline Store Reference](https://docs.feast.dev/reference/offline-stores/oracle) +- [Oracle Data Source Reference](https://docs.feast.dev/reference/data-sources/oracle) +- [Feast Operator Documentation](https://docs.feast.dev/) + +--- + +*Get started with the [Feast documentation](https://docs.feast.dev/) and join the community on [GitHub](https://github.com/feast-dev/feast) and [Slack](https://feastopensource.slack.com/). We'd love to hear how you're using Feast with Oracle.* diff --git a/infra/website/docs/blog/feature-view-versioning.md b/infra/website/docs/blog/feature-view-versioning.md new file mode 100644 index 00000000000..574dac54cc1 --- /dev/null +++ b/infra/website/docs/blog/feature-view-versioning.md @@ -0,0 +1,244 @@ +--- +title: Feast Introduces Experimental Feature View Versioning +description: Feast now supports experimental feature view versioning — bringing automatic version tracking, safe rollback, and multi-version online serving to your feature store. Only supported for SQLite today; we're inviting the community to test and give feedback. +date: 2026-03-31 +authors: ["Francisco Javier Arceo"] +--- + +
+ Feast Feature Versioning +
+ +# Feast Introduces Experimental Feature View Versioning 🚀 + +We are excited to announce the experimental release of **Feature View Versioning** in Feast — a [long-requested capability](https://github.com/feast-dev/feast/issues/2728) that brings automatic version tracking, safe rollback, and multi-version online serving to your feature store. + +This feature is still **experimental** and we would love to hear your feedback. Try it out and let us know what works, what doesn't, and which online stores you'd like to see supported next. + +## Why Feature Versioning Matters + +Serving data in production AI applications is one of the hardest problems in ML engineering. The Feast community is built on practitioners who run these high-stakes pipelines every day — where **point-in-time correctness** is not just a nice-to-have but a hard requirement for model integrity. A feature value seen by the wrong model at the wrong time can silently corrupt predictions and, in high stakes scenarios, impact critical business applications. This is the most important motivating factor behind our versioning work. + +Feature versioning solves two distinct but equally real problems: + +### Case 1: Fixing Forward in Production (the critical path) + +A live feature view powering a production model needs to be updated — perhaps a critical bug in a transformation logic, a renamed column, or a changed data source. In an ideal world you'd cut over to a brand-new feature view and update every downstream consumer atomically. In practice that's rarely viable: models are already deployed, consumers are already reading that name, and a rename causes an immediate outage. + +With feature versioning you can overwrite the existing feature view definition while retaining the complete history as a recoverable snapshot. If the change turns out to break something, you can roll back to the previous version. You always have an audit trail: who changed what, when, and what the feature looked like at every prior point in time. + +This case is the hardest to get right. When your feature is live in production, correctness is non-negotiable. The materialized data that feeds real-time predictions must stay consistent with the schema that was active when it was written — otherwise you risk serving stale rows with the wrong columns to models that expect the new schema, or vice versa. Our per-version table design (see below) exists precisely to prevent that class of failure. + +### Case 2: Offline Experimentation Before Production + +During active feature development, multiple data scientists may be building and evaluating competing versions of the same feature simultaneously — different transformations, different data sources, different schemas. Today there is no first-class way to manage this in Feast without creating separate feature views with different names and hoping teams don't collide. + +With versioning, teams can stage a new feature version using `--no-promote`, test it in isolation, and only promote it to the active (default) definition once it has been validated. The rest of the system sees no change until the promotion happens. + +### The Persistent Pain Points + +Both cases expose the same underlying gaps that exist today: + +1. **No audit trail.** Teams struggle to answer "what did this feature view look like last week?" or "when was this schema changed and by whom?" +2. **No safe rollback.** If a schema change breaks a downstream model, the only recourse is to manually reconstruct the old definition — often from memory or version control history. +3. **No multi-version serving.** During a migration, Model A might rely on the old feature schema while Model B needs the new one. Without versioning, serving both simultaneously requires duplicating the entire feature view under a different name. + +## How It Works + +Version tracking is fully automatic. You don't need to change anything about how you write or apply feature views: + +```bash +feast apply # First apply → saved as v0 +# ... edit schema ... +feast apply # Detects change → saved as v1 +feast apply # No change detected → still v1 (idempotent) +# ... edit source or UDF ... +feast apply # Detects change → saved as v2 +``` + +Every time `feast apply` detects a real change to a feature view's schema or transformation logic, it automatically saves a versioned snapshot to the registry. Metadata-only changes (description, tags, TTL) are updated in place without creating a new version. + +### What Gets Versioned + +- Changes to the feature schema (adding, removing, or renaming fields) +- Changes to batch or stream data sources +- Changes to on-demand feature view UDFs +- Any other structural change that affects data layout or derivation + +### What Does Not Trigger a New Version + +- Tag or description updates +- TTL changes +- Re-applying an identical definition (idempotent behavior) + +## Exploring Version History + +You can list all recorded versions of a feature view from the CLI: + +```bash +feast feature-views list-versions driver_stats +``` + +``` +VERSION TYPE CREATED VERSION_ID +v0 feature_view 2026-01-15 10:30:00 a1b2c3d4-... +v1 feature_view 2026-01-16 14:22:00 e5f6g7h8-... +v2 feature_view 2026-01-20 09:15:00 i9j0k1l2-... +``` + +Or programmatically: + +```python +store = FeatureStore(repo_path=".") +versions = store.list_feature_view_versions("driver_stats") +for v in versions: + print(f"{v['version']} created at {v['created_timestamp']}") +``` + +## Multi-Version Online Serving + +When `enable_online_feature_view_versioning: true` is set in your `feature_store.yaml`, you can read features from a specific version using the `@v` syntax: + +```yaml +registry: + path: data/registry.db + enable_online_feature_view_versioning: true +``` + +```python +online_features = store.get_online_features( + features=[ + "driver_stats:trips_today", # latest version (default) + "driver_stats@v1:trips_today", # read from v1 + "driver_stats@v2:avg_rating", # read from v2 + ], + entity_rows=[{"driver_id": 1001}], +) +``` + +Multiple versions can be queried in a single call, making gradual migrations straightforward: keep serving the old version to existing consumers while routing new consumers to the latest. **By default, unversioned requests always resolve to the latest promoted version** — opting into a specific version requires the explicit `@v` syntax. + +### Online Store Table Naming + +Each version owns its own isolated online table (see [The Challenges of Correctness](#the-challenges-of-correctness-in-feature-versioning) below for why this design is necessary for point-in-time correctness): + +- v0 continues to use the existing, unversioned table (e.g., `project_driver_stats`) — fully backward compatible +- v1 and later use suffixed tables (e.g., `project_driver_stats_v1`, `project_driver_stats_v2`) + +Each version requires its own materialization: + +```bash +feast materialize --views driver_stats --version v2 +``` + +## Safe Rollback + +You can pin a feature view to a specific historical version by setting the `version` parameter. `feast apply` will replace the active definition with the stored snapshot: + +```python +# Revert to v1 — restores schema, source, and transformations from the v1 snapshot +driver_stats = FeatureView( + name="driver_stats", + entities=[driver], + schema=[...], + source=my_source, + version="v1", +) +``` + +After running `feast apply`, the active feature view will match the v1 snapshot exactly. Remove the `version` parameter (or set it to `"latest"`) to resume auto-incrementing behavior. + +## Staged Publishing with `--no-promote` + +For breaking schema changes, you may want to publish a new version without immediately making it the default for unversioned consumers. Use the `--no-promote` flag: + +```bash +feast apply --no-promote +``` + +This saves the version snapshot without updating the active definition. Unversioned consumers (`driver_stats:trips_today`) continue reading from the previous version, while opted-in consumers can start using `driver_stats@v2:trips_today` right away. When you're ready to make the new schema the default, run `feast apply` without the flag. + +## The Challenges of Correctness in Feature Versioning + +Feature versioning might sound simple in principle, but **getting it right is surprisingly hard**, especially for materialization. This is particularly acute for Case 1 above — production systems where the consistency of data matters and the cost of a mistake is high. + +### Why We Can't Share a Single Online Table + +The naive approach to versioning would be to keep a single online table and tag rows with a version column. We explicitly rejected this design. + +Each version of a feature view may have a completely different schema — different columns, different types, different derivation logic. A single shared table would require the union of all column schemas across all versions, leading to sparse rows, broken type contracts, and materialization jobs that cannot safely run in parallel. More fundamentally, it makes **point-in-time correctness impossible**: a model trained against v1 of a feature must retrieve v1 rows, not v2 rows that happen to occupy the same table. + +Instead, we give each version its own online table: + +- v0 continues to use the existing, unversioned table (e.g., `project_driver_stats`) — fully backward compatible +- v1 and later use suffixed tables (e.g., `project_driver_stats_v1`, `project_driver_stats_v2`) + +This is more operationally complex — more tables to manage, more materialization jobs to schedule — but it is the **only design that guarantees correctness**. Each version's materialized data is isolated, independently freshed, and independently queryable. A buggy v2 materialization cannot corrupt v1 data. + +### The Core Tension + +Each version of a feature view may have a completely different schema, source, or transformation. This means: + +- Each version needs its own online store table with the right columns +- Materializing one version must not corrupt data in another version's table +- Version-qualified online reads must resolve the snapshot at the right point in time before looking up the online table +- The active (promoted) version and historical snapshots must stay consistent + +### Materialization Complexity + +Today, running `feast materialize` without specifying a version fills the **active** version's table. To populate a historical version's table, you must explicitly pass `--version v` so Feast can reconstruct the schema from the saved snapshot and target the correct online table. + +This matters for correctness: if you apply v2 of a feature view (which drops a column) and then run an unversioned `feast materialize`, the v1 online table is not automatically backfilled or maintained. Teams need to think carefully about which versions they want to keep materialized and for how long. + +### What This Means for Clients + +The multi-table design does introduce a responsibility shift toward the client. By default, unversioned feature requests (`driver_stats:trips_today`) resolve to the **latest promoted version** — no change to existing consumers. But clients that need to pin to a specific version must opt in explicitly using the `@v` syntax (`driver_stats@v1:trips_today`). + +This is an intentional design choice. Automatic version following would hide schema changes from consumers that may not be ready for them. Explicit version pinning keeps the contract between producers and consumers clear and auditable — each consumer controls exactly which version of a feature it reads. + +### Tradeoffs + +| Concern | Tradeoff | +|---|---| +| Storage cost | Each active version requires its own online table — storage scales with the number of versions kept live | +| Operational complexity | Teams must manage materialization schedules per version | +| Consistency windows | Because each version has its own materialization job, two versions of the same feature for the same entity may have different freshness | +| Concurrency | Two simultaneous `feast apply` calls can race on version number assignment — the registry backends use optimistic locking to handle this, but teams should be aware | + +These tradeoffs are real and we're still refining the model based on community experience. We've tried to make the defaults safe (versioning is opt-in for online reads, backward compatible for unversioned access) while giving teams the controls they need. + +## Current Limitations + +This is an experimental feature and there are known gaps: + +- **Online store support** — Version-qualified reads (`@v`) are **SQLite-only** today. We plan to add Redis, DynamoDB, Bigtable, Postgres, and others based on community demand. If you need a specific store, [comment or upvote on the appropriate the child GitHub issue of the main GitHub issue](https://github.com/feast-dev/feast/issues/2728) and let us know. +- **Offline store versioning** — Versioned historical retrieval is not yet supported. +- **Version deletion** — There is no mechanism today to prune old versions from the registry. +- **Feature services** — Feature services always resolve to the active (promoted) version. `--no-promote` versions are not accessible through feature services until promoted. + +## Supported Feature View Types + +Versioning works across all three feature view types: + +- `FeatureView` (and `BatchFeatureView`) +- `StreamFeatureView` +- `OnDemandFeatureView` + +## Getting Started + +1. Upgrade to the latest version of Feast. +2. Add `enable_online_feature_view_versioning: true` to your registry config in `feature_store.yaml` (only needed for versioned online reads). +3. Run `feast apply` as usual — version history tracking starts automatically. +4. Explore your version history with `feast feature-views list-versions `. + +For full details, see the [Feature View Versioning documentation](https://docs.feast.dev/reference/alpha-feature-view-versioning). + +## Share Your Feedback + +We want to hear from you! Try out feature view versioning and tell us: + +- Which online stores you need supported next +- Which workflows feel awkward or incomplete +- How the materialization model fits your real-world pipelines + +Join the conversation on [GitHub](https://github.com/feast-dev/feast/issues) or in the [Feast Slack community](https://slack.feast.dev/). Your feedback directly shapes what we build next. diff --git a/infra/website/docs/blog/mongodb-feast-integration.md b/infra/website/docs/blog/mongodb-feast-integration.md new file mode 100644 index 00000000000..8a9ea4c255b --- /dev/null +++ b/infra/website/docs/blog/mongodb-feast-integration.md @@ -0,0 +1,210 @@ +--- +title: "Native MongoDB Support in Feast: One Database for Operational Data, Features, and Vectors" +description: Feast now ships first-class support for MongoDB as both an online and an offline store, plus native Vector Search for embedding-based retrieval. Machine Learning teams running on MongoDB can serve features at low latency, generate point-in-time-correct training datasets, and power RAG or recommender workloads, all from a single MongoDB Atlas cluster, with no separate cache, no separate warehouse, and no parallel vector database to keep in sync. +date: 2026-05-07 +authors: ["Rishabh Bisht"] +--- + + +
+MongoDB Feast Stores +
+ + +## The three-database problem in production ML + +A typical Feast deployment runs three different databases: + +1. The **application's primary database** where the operational data that features are derived from actually lives. +2. A dedicated **online store** used to serve features at low latency to live models. +3. A **separate warehouse** used as the offline store for training-set generation and historical retrieval. + +That's three sets of credentials, three security postures, three monitoring stacks, and a constant feedback loop of "the feature is in the warehouse but stale in the online store" or "we materialized last night but the model is reading yesterday's values." + +For teams whose operational data already lives in MongoDB, this was especially painful. Until now, Feast had no native MongoDB option so teams either stood up parallel infrastructure they didn't want, or settled for community plugins of varying maturity. + +With this release, both types of the feature store run on MongoDB - same connection string, same auth, same backups, same observability. The features sit next to the operational data they were derived from. + +## What's in the integration + +Three components ship together as generally available: + +### 1. MongoDBOnlineStore - low-latency feature serving + +Available in Feast `v0.61.0` and above. Built on the official PyMongo driver, with both sync and native async paths (the async implementation uses PyMongo's `AsyncMongoClient`). It supports `online_write_batch`, `online_read`, and their async equivalents. + +Features from multiple feature views for the same entity are colocated in a single MongoDB collection keyed by the serialized entity key, so a read for an entity is a single primary-key lookup, not a fan-out across collections. + +### 2. MongoDBOfflineStore - historical retrieval and training-set generation + +Available in `v0.63.0` and above. Uses the MongoDB aggregation framework for retrieval, with `pandas.merge_asof` for the point-in-time join when entities repeat across timestamps. Ships with `MongoDBSource` (the `DataSource` class), `offline_write_batch` for ingest, and `persist` to write joined results to Parquet for downstream training pipelines. + +### 3. MongoDB Vector Search - embeddings as first-class features + +When you set `vector_enabled: true` on the online store, Feast automatically creates and manages MongoDB vector search indexes on any `FeatureView` field marked with `vector_index=True`. The `retrieve_online_documents_v2()` method runs a `$vectorSearch` aggregation under the hood and returns nearest-neighbor results as `(event_ts, entity_key, feature_dict)` tuples with a similarity score - with `top_k` limiting and configurable distance metrics (`cosine`, `dot product`, `euclidean`). + +The result: a team running RAG, recommenders, or agent workloads can store, serve, and similarity-search feature embeddings in the same Atlas cluster as their other features — with no separate vector database to bolt on. + +## **Quick start** + +### Install + +```shell +pip install 'feast[mongodb]' +``` + +### Configure your `feature_store.yaml` + +Point both the online and offline store at the same Atlas cluster. No separate Atlas feature flag or opt-in required. + +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local + +online_store: + type: mongodb + connection_string: "mongodb+srv://:@.mongodb.net" + database: "feast_online" + +offline_store: + type: mongodb + connection_string: "mongodb+srv://:@.mongodb.net" + database: "feast_offline" + +entity_key_serialization_version: 3 +``` + +### Define a feature view backed by `MongoDBSource` + +```py +from datetime import timedelta +from feast import Entity, FeatureView, Field +from feast.types import Float32, Int64 +from feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb_source import ( + MongoDBSource, +) + +driver = Entity(name="driver", join_keys=["driver_id"]) + +driver_stats_source = MongoDBSource( + name="driver_stats_source", + database="feast_offline", + collection="driver_stats", + timestamp_field="event_timestamp", + created_timestamp_column="created", +) + +driver_stats_fv = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=7), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + ], + online=True, + source=driver_stats_source, +) +``` + +### Apply, materialize, and serve + +```shell +feast apply +feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S") +``` + +```py +from feast import FeatureStore + +store = FeatureStore(repo_path=".") + +features = store.get_online_features( + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + ], + entity_rows=[{"driver_id": 1001}, {"driver_id": 1002}], +).to_dict() +``` + +That's it. Same connection string, same auth model, same cluster - features in, features out. + +## RAG and embeddings: vector search in the same cluster + +If you're building a RAG pipeline, a recommender, or an agent that needs nearest-neighbor lookup over feature embeddings, the online store doubles as a vector store when `vector_enabled` is set: + +```yaml +online_store: + type: mongodb + connection_string: "mongodb+srv://:@.mongodb.net" + database: "feast_online" + vector_enabled: true + vector_index_wait_timeout: 60 + vector_index_wait_poll_interval: 2 +``` + +Mark the embedding field on your `FeatureView`: + +```py +from feast import FeatureView, Field +from feast.types import Array, Float32, Int64, String, UnixTimestamp + +document_embeddings = FeatureView( + name="embedded_documents", + entities=[item], + schema=[ + Field( + name="vector", + dtype=Array(Float32), + vector_index=True, # ← enable vector index + vector_search_metric="COSINE", # cosine | dot product | euclidean + ), + Field(name="item_id", dtype=Int64), + Field(name="sentence_chunks", dtype=String), + Field(name="event_timestamp", dtype=UnixTimestamp), + ], + source=rag_documents_source, +) +``` + +When you run `feast apply`, Feast creates the corresponding Atlas vector search index. When the feature view is removed, the index is dropped. The `vector_index_wait_timeout` and `vector_index_wait_poll_interval` settings control how long Feast waits for newly created Atlas Search indexes to become queryable before returning. + +Querying nearest neighbors is then one call: + +```py +results = store.retrieve_online_documents_v2( + features=[ + "embedded_documents:vector", + "embedded_documents:item_id", + "embedded_documents:sentence_chunks", + ], + query=query_embedding, # list[float] of the same dim + top_k=5, + distance_metric="COSINE", +).to_df() +``` + +Under the hood, this becomes a `$vectorSearch` aggregation against your Atlas cluster - no second system to provision, no vector data to keep in sync with the rest of your features. + +## Why this matters + +A few reasons we think this lands in the right place for ML teams already on MongoDB: + +* **One database for training and inference.** The same Atlas cluster powers historical retrieval, materialization, and online serving. No ETL pipelines pushing features from a warehouse. Update a feature once, see it everywhere. +* **One security and compliance posture.** Atlas networking, IAM, encryption, and audit logging cover both halves of the feature store. Architects don't have to add a new database vendor and a new threat model to say yes to ML. +* **Vector and operational data colocated.** For RAG, recommenders, and agents, the embeddings live next to the entity data they describe. Filter your vector search on operational fields with the same query language you already use. +* **Flexible schema where it helps.** Feature engineering is iterative. MongoDB's document model means adding a field to a feature view doesn't require a schema migration on day one. +* **Async serving when you need it.** The online store ships a native async path on `AsyncMongoClient`, so feature lookups don't block the rest of your serving stack. + +## Where to next + +* **Online store reference:** [Feast docs - MongoDB online store](https://docs.feast.dev/master/reference/online-stores/mongodb) +* **Offline store reference:** [Feast docs - MongoDB offline store](https://docs.feast.dev/master/reference/offline-stores/mongodb) +* **Vector search:** [Feast docs - Vector Search](https://docs.feast.dev/master/reference/data-sources/mongodb#vector-search) +* **Tutorial:** [Integrate MongoDB with Feast](https://www.mongodb.com/docs/atlas/ai-integrations/feast/) + +If you're already on MongoDB and want to standardize your ML stack on a single backend, this is the time to try it. Spin up a feature repo, point both stores at your cluster, and let us know how it goes - issues and PRs welcome on GitHub. \ No newline at end of file diff --git a/infra/website/public/images/blog/end_to_end_lineage.png b/infra/website/public/images/blog/end_to_end_lineage.png new file mode 100644 index 00000000000..8d49cd2ec74 Binary files /dev/null and b/infra/website/public/images/blog/end_to_end_lineage.png differ diff --git a/infra/website/public/images/blog/entity_dataframe.png b/infra/website/public/images/blog/entity_dataframe.png new file mode 100644 index 00000000000..5588c9260d8 Binary files /dev/null and b/infra/website/public/images/blog/entity_dataframe.png differ diff --git a/infra/website/public/images/blog/feast-feature-versioning-hero.png b/infra/website/public/images/blog/feast-feature-versioning-hero.png new file mode 100644 index 00000000000..d40d71a16dd Binary files /dev/null and b/infra/website/public/images/blog/feast-feature-versioning-hero.png differ diff --git a/infra/website/public/images/blog/feast-mcp-agent-workflow-prod.png b/infra/website/public/images/blog/feast-mcp-agent-workflow-prod.png new file mode 100644 index 00000000000..5cf94df580b Binary files /dev/null and b/infra/website/public/images/blog/feast-mcp-agent-workflow-prod.png differ diff --git a/infra/website/public/images/blog/feast-mcp-agent-workflow.png b/infra/website/public/images/blog/feast-mcp-agent-workflow.png new file mode 100644 index 00000000000..87504642e39 Binary files /dev/null and b/infra/website/public/images/blog/feast-mcp-agent-workflow.png differ diff --git a/infra/website/public/images/blog/feast-mcp-agent.png b/infra/website/public/images/blog/feast-mcp-agent.png new file mode 100644 index 00000000000..191e97517fe Binary files /dev/null and b/infra/website/public/images/blog/feast-mcp-agent.png differ diff --git a/infra/website/public/images/blog/feast-metrics-dashboard-overview.png b/infra/website/public/images/blog/feast-metrics-dashboard-overview.png new file mode 100644 index 00000000000..21293e8499e Binary files /dev/null and b/infra/website/public/images/blog/feast-metrics-dashboard-overview.png differ diff --git a/infra/website/public/images/blog/feast-metrics-hero.png b/infra/website/public/images/blog/feast-metrics-hero.png new file mode 100644 index 00000000000..b7c11e13e8d Binary files /dev/null and b/infra/website/public/images/blog/feast-metrics-hero.png differ diff --git a/infra/website/public/images/blog/feast-metrics-odfv-latency.png b/infra/website/public/images/blog/feast-metrics-odfv-latency.png new file mode 100644 index 00000000000..d6d33c0e5db Binary files /dev/null and b/infra/website/public/images/blog/feast-metrics-odfv-latency.png differ diff --git a/infra/website/public/images/blog/feast-mlflow-native-integration.png b/infra/website/public/images/blog/feast-mlflow-native-integration.png new file mode 100644 index 00000000000..83df6a2c990 Binary files /dev/null and b/infra/website/public/images/blog/feast-mlflow-native-integration.png differ diff --git a/infra/website/public/images/blog/feast-oracle-offline-store.png b/infra/website/public/images/blog/feast-oracle-offline-store.png new file mode 100644 index 00000000000..425c7fda0cc Binary files /dev/null and b/infra/website/public/images/blog/feast-oracle-offline-store.png differ diff --git a/infra/website/public/images/blog/lineage_till_training.png b/infra/website/public/images/blog/lineage_till_training.png new file mode 100644 index 00000000000..a91adf8bf0e Binary files /dev/null and b/infra/website/public/images/blog/lineage_till_training.png differ diff --git a/infra/website/public/images/blog/mlflow_dashboard.png b/infra/website/public/images/blog/mlflow_dashboard.png new file mode 100644 index 00000000000..1d9896a0880 Binary files /dev/null and b/infra/website/public/images/blog/mlflow_dashboard.png differ diff --git a/infra/website/public/images/blog/mlflow_featurelist.png b/infra/website/public/images/blog/mlflow_featurelist.png new file mode 100644 index 00000000000..23920c179ff Binary files /dev/null and b/infra/website/public/images/blog/mlflow_featurelist.png differ diff --git a/infra/website/public/images/blog/model_metadata.png b/infra/website/public/images/blog/model_metadata.png new file mode 100644 index 00000000000..7ef300d9b2b Binary files /dev/null and b/infra/website/public/images/blog/model_metadata.png differ diff --git a/infra/website/public/images/blog/mongodb-feature-stores.png b/infra/website/public/images/blog/mongodb-feature-stores.png new file mode 100644 index 00000000000..c0705834dc9 Binary files /dev/null and b/infra/website/public/images/blog/mongodb-feature-stores.png differ diff --git a/infra/website/public/images/blog/offline_store_operational_metrics.png b/infra/website/public/images/blog/offline_store_operational_metrics.png new file mode 100644 index 00000000000..12006128d81 Binary files /dev/null and b/infra/website/public/images/blog/offline_store_operational_metrics.png differ diff --git a/infra/website/public/images/blog/operation.png b/infra/website/public/images/blog/operation.png new file mode 100644 index 00000000000..43b6500faee Binary files /dev/null and b/infra/website/public/images/blog/operation.png differ diff --git a/infra/website/public/images/blog/registered_model_with_feature_service.png b/infra/website/public/images/blog/registered_model_with_feature_service.png new file mode 100644 index 00000000000..1195d4c3cbb Binary files /dev/null and b/infra/website/public/images/blog/registered_model_with_feature_service.png differ diff --git a/infra/website/public/images/blog/sox_compliance_and_access.png b/infra/website/public/images/blog/sox_compliance_and_access.png new file mode 100644 index 00000000000..0236e5b5cdc Binary files /dev/null and b/infra/website/public/images/blog/sox_compliance_and_access.png differ diff --git a/infra/website/public/images/blog/sox_offline_store_audit_logs.png b/infra/website/public/images/blog/sox_offline_store_audit_logs.png new file mode 100644 index 00000000000..fa7be01ebcc Binary files /dev/null and b/infra/website/public/images/blog/sox_offline_store_audit_logs.png differ diff --git a/infra/website/src/layouts/BaseLayout.astro b/infra/website/src/layouts/BaseLayout.astro index d73c7b0ebde..05d940005ba 100644 --- a/infra/website/src/layouts/BaseLayout.astro +++ b/infra/website/src/layouts/BaseLayout.astro @@ -4,9 +4,17 @@ import '../styles/global.css'; interface Props { title: string; description?: string; + socialImage?: string; + ogUrl?: string; } -const { title, description = "Feast is an end-to-end open source feature store for machine learning. It allows teams to define, manage, discover, and serve features." } = Astro.props; +const defaultSocialImage = "https://feast.dev/wp-content/uploads/2023/01/feast-og@2x.png"; +const { + title, + description = "Feast is an end-to-end open source feature store for machine learning. It allows teams to define, manage, discover, and serve features.", + socialImage = defaultSocialImage, + ogUrl = "https://feast.dev/", +} = Astro.props; --- @@ -25,16 +33,16 @@ const { title, description = "Feast is an end-to-end open source feature store f - + - + - + @@ -51,4 +59,4 @@ const { title, description = "Feast is an end-to-end open source feature store f - \ No newline at end of file + diff --git a/infra/website/src/pages/blog/[slug].astro b/infra/website/src/pages/blog/[slug].astro index 7d6a780a14c..90e8572d0b2 100644 --- a/infra/website/src/pages/blog/[slug].astro +++ b/infra/website/src/pages/blog/[slug].astro @@ -1,6 +1,25 @@ --- import BaseLayout from '../../layouts/BaseLayout.astro'; import Navigation from '../../components/Navigation.astro'; +import { readFileSync } from 'node:fs'; + +const SITE_URL = 'https://feast.dev'; + +function toAbsoluteUrl(path: string): string { + if (/^https?:\/\//i.test(path)) { + return path; + } + return new URL(path, SITE_URL).toString(); +} + +function extractHeroImage(markdown: string): string | undefined { + const heroContainerMatch = markdown.match(/]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>([\s\S]*?)<\/div>/i); + if (!heroContainerMatch?.[1]) { + return undefined; + } + const imageMatch = heroContainerMatch[1].match(/]*\bsrc=["']([^"']+)["'][^>]*>/i); + return imageMatch?.[1]; +} export async function getStaticPaths() { const posts = await Astro.glob('../../../docs/blog/*.md'); @@ -17,9 +36,13 @@ export async function getStaticPaths() { const { post } = Astro.props; const { title, description, date, authors = [] } = post.frontmatter; +const blogUrl = `${SITE_URL}/blog/${Astro.params.slug}/`; +const frontmatterImage = post.frontmatter.hero_image || post.frontmatter.heroImage || post.frontmatter.image; +const heroImage = frontmatterImage || extractHeroImage(readFileSync(post.file, 'utf-8')); +const socialImage = heroImage ? toAbsoluteUrl(heroImage) : undefined; --- - +
@@ -316,4 +339,4 @@ const { title, description, date, authors = [] } = post.frontmatter; font-size: 18px; } } - \ No newline at end of file + diff --git a/java/pom.xml b/java/pom.xml index 4ba8b6d211d..4654d87c349 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.61.0 + 0.64.0 https://github.com/feast-dev/feast UTF-8 diff --git a/pixi.lock b/pixi.lock index f1606c89743..4aee7c1ca70 100644 --- a/pixi.lock +++ b/pixi.lock @@ -5,26 +5,26 @@ environments: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda @@ -32,83 +32,84 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/d8/09bfa816572a4d83bccd6750df1926f79158b1c36c5f73786e26dbe4ee38/greenlet-3.3.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/96/4efd6fa5c62c85426a0c19077a586258ebc3a2a146ff2493e4312a697a22/greenlet-3.5.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/53/771bd891eb0f236f32145d6a1775777ec85745f3cc983a1f23d1a3b8ddfe/httptools-0.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/96/ef04902aad1424fd7299b62d1890e803e6ab4018c3044dca5922319c4b97/librt-0.8.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0a/7e/f5d92af8486b8272c23b3e686b46ff72d89c8169585eb61eef01a2ac7147/librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ca/e0/78adf4104c425606a9ce33fb351f790c76a6c2314969c4a517d1ffc92196/mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b6/71/c1a60c1652b8813ef9de6d289784847355417ee0f2980bca002fe87f4ae5/mmh3-5.2.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c2/8b/ecdad52d0b38d4b8f514be603e69ccd5eacf4e7241f972e37e79792212ec/orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/57/89727baef7578897af5ed166735ceb315819f1c184da8c3441271dbcfde7/protobuf-7.34.0-cp310-abi3-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/70/5b/6baf9008817964454055ff3fe65f1de0b5f1e26c80c82f7fb108b7cd4ea3/protobuf-7.35.0-cp310-abi3-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/36/2e/c0f017c405fcdc252dbccafbe05e36b0d0eb1ea9a958f081e01c6972927f/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/3a/28ba9c1c1ebdbb5f1b94dfebb46f207e52e6a554b7fe4132540fde29a3a0/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/c8/d63bb75b68afe77b229e3021c6031bcaf01da5db5b0e69d0d10f9ba679a7/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/5e/327428a034407651a048f5e624361adf3f9fbac9d0fa98e981e9c6ff2f5e/sqlalchemy-2.0.48-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/26/ef168b184a25701f9995e8fb7e503fafd7a99c1c77cda1bc1a26ea2ed486/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7c/8a/3076c496ca8dafe0e8cd03fcebdfc47be4b1174b4e5b24ff6e396e6b3af2/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.2-h8f8c405_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.5-h7c6738f_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda @@ -116,84 +117,84 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/ae/8bffcbd373b57a5992cd077cbe8858fff39110480a9d50697091faea6f39/greenlet-3.3.2-cp314-cp314-macosx_11_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/cb/c62454606daf5640369c94d8a9dd540599b1bfc090e2d2180cb77f4038d2/greenlet-3.5.1-cp314-cp314-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/12/fa3fbf5f9517b273edea2dc982aa82a8c634091e67c590792b729017bc6f/httptools-0.8.0-cp314-cp314-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/6a/907ef6800f7bca71b525a05f1839b21f708c09043b1c6aa77b6b827b3996/librt-0.8.1-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/29/eb/dbce197da4e227779e56b5735f2decc3eb36e55a1cdbf1bd65d6639d76c1/librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/70/1f/f87e3d34d83032b4f3f0f528c6d95a98290fcacf019da61343a49dccfd51/mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6f/75/2c24517d4b2ce9e4917362d24f274d3d541346af764430249ddcc4cb3a08/mmh3-5.2.1-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/83/ee/93d06e358a4aa32280b00e722d3ea0a1f25fc3cc5778d80581c9cca2c10e/protobuf-7.35.0-cp310-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ae/b5/d58a241fbe324dbaeb8df07be6af8752c846192d78d2272e551098f74e88/pyarrow-23.0.1-cp314-cp314-macosx_12_0_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/ff/f01485fda6f4e5d441afb8dd5e7681e4db18826c1e271852f5d3957d6a80/pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/6f/19c1918a4b590d8de87e712e4abe4b3875771eff60216fb6153cf6665c68/rpds_py-2026.5.1-cp314-cp314-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/9664130905f03db57961b8980b05cab624afd114bf2be2576628a9f22da4/sqlalchemy-2.0.48-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/54/a9c7ea9a82a4ac65e7004c0a03920b5cdd2f9c3b678757d9cd425aa51d53/watchfiles-1.2.0-cp314-cp314-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.5-h4c637c5_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda @@ -201,174 +202,174 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/fc/5e7c4cb443370f2090a3aba0453a07384d29ff66b7435bb90e77e1037599/httptools-0.8.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1b/18/25e991cd5640c9fb0f8d91b18797b29066b792f17bf8493da183bf5caabe/librt-0.8.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/76/a3/254bebd0c11c8ba684018efb8006ff22e466abce445215cca6c778e7d9de/librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/a6/e2/db849eaed07117086f3452feca8c839d30d38b830ac59fe1ce65af8be5ad/mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/bf/b9/e4a360164365ac9f07a25f0f7928e3a66eb9ecc989384060747aa170e6aa/mmh3-5.2.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/83/ee/93d06e358a4aa32280b00e722d3ea0a1f25fc3cc5778d80581c9cca2c10e/protobuf-7.35.0-cp310-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8d/1b/6da9a89583ce7b23ac611f183ae4843cd3a6cf54f079549b0e8c14031e73/pyarrow-23.0.1-cp314-cp314-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ad/80/d022a34ff05d2cbedd8ccf841fc1f532ecfa9eb5ed1711b56d0e0ea71fc9/pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/60/a06fe7da34eca79dacbf958a2ba0c6eea85bc2b29de20080bf40f72f66fa/rpds_py-2026.5.1-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/b3/f437eaa1cf028bb3c927172c7272366393e73ccd104dcf5b6963f4ab5318/sqlalchemy-2.0.48-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/32/10ac51b4be7cdecd7e93d069251c86dfbf70b7adbd7c67b48ccea6c49e1c/sqlalchemy-2.0.50-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/aa/5d/c9ab3534374a4a67450696905d6ef16a04405448b8dc52bd752ae50423d4/watchfiles-1.2.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl duckdb-tests: channels: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/c0/271f3e1e3502a8decb8ee5c680dbed2d8dc2cd504f5e20f7ed491d5f37e1/atpublic-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6e/24/e6b7a8fe8b9e336d684779a88027b261374417f2be7c5a0fcdb40f0c8cc5/deltalake-0.25.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/76/5c/bdb735011131c429cdb6d9e12e12fc8f1c8622158890d76a25819a58efc2/duckdb-1.5.3-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/58/2f/f3fc773270cf17e7ca076c1f6435278f58641d475a25cdeea5b2d8d4845b/grpcio-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/b8/8b83d18ae07c46c019617f35afd7b47aab7f9b4fbb12fc637d681e10bdd8/greenlet-3.5.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9a/df/ec0a4e04472df2618f8741151fa026bc877648e952ebb0e421169e0b992b/grpcio-1.81.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/71/b0a9193641d9e2471ac541d3b1b869538a5fb6419d52fd2669fa9c79e4b8/httptools-0.7.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9d/b3/11d406849715b47c9d69bb22f50874f80caee96bd1cbe7b61abbebbf5a05/ibis_framework-12.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/99/f85130582f05dcf0c8902f3d629270231d2f4afdfc567f8305a952ac7f14/librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/50/5ec949d7f9ce1a07af903aa3e13abb98b717923bdead6e719b2f824ccc07/librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/8e/29306d5eca6dfda4b899d22c95b5420db4e0ffb7e0b6389b17379654ece5/mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c6/b1/e20d5f0d19c4c0f3df213fa7dcfa0942c4fb127d38e11f398ae8ddf6cccc/mmh3-5.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/41/5a/93093f0b29a9e982deafde698f740a2eb2e05886e79ccf0594c7fd5413a3/mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/77/fc/8cb9073bb1bee54eb49a1ae501a36402d01763812962ac811cdc1c81a9d7/parsy-2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/57/89727baef7578897af5ed166735ceb315819f1c184da8c3441271dbcfde7/protobuf-7.34.0-cp310-abi3-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/82/c40b68001dbec8a3faa4c08cd8c200798ac732d2854537c5449dc859f55a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/67/33/f75e91b9a64c3f33c787e263c93b871ad91b8a4a68c1d5cebddd9840e835/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2e/c3/94ade4906a2f88bc935772f59c934013b4205e773bcb4239db114a6da136/pyarrow_hotfix-0.7-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -381,124 +382,125 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/ad/6c4395649a212a6c603a72c5b9ab5dce3135a1546cfdffa3c427e71fd535/sqlalchemy-2.0.48-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ad/c9/f58c3a17beb650700f9d2eccd410726b6d96df8953663700764ca48636c7/sqlglot-29.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/55/b260d8df2adc9bb0bf294f67b5f802ff0d84d99442b536b9efd0ea72d447/sqlalchemy-2.0.50-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/13/4c/41b222c130950a077e1a0ba311df84a29b818db7c136ecc1aafbfad42e26/sqlglot-30.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/f6/21657bb3beb5f8c57ce8be3b83f653dd7933c2fd00545ed1b092d464799a/uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/dc/1a680b7458ffa3b14bb64878112aefc8f2e4f73c5af763cbf0bd43100658/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/02/c8/79eee650c62d2c186598489814468e389b5def0ebe755399ff645b35b1b2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9d/2f/4b3ca7e106bc608744b1cdae041e005e446124bebb037b18799c2d356864/websockets-16.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/79/4c755b45df6ef30c0dd628ecfaa0c808854be147ca438429da70a162833c/wrapt-2.1.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/c2/3d186944aae923631d1def58f4c4ff8f0b6309906afc0b6978de3e69b3e0/wrapt-2.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.19-h988dfef_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.2-h8f8c405_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.20-hea035f4_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/c0/271f3e1e3502a8decb8ee5c680dbed2d8dc2cd504f5e20f7ed491d5f37e1/atpublic-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/0e/f372bb290cef68c67331cd649b94d62220183ddc1b5bf3a9351ea6e9c8ec/deltalake-0.25.5-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a0/ed/03ccf15147db7468f65891b5daa8489aa755d8cfcf75b24e7a4e4720e28c/duckdb-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1d/21/117c8710abb7f146d804a124c07eb5964a60b90d02b72452885aecc18efa/greenlet-3.5.1-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/e5/c07e0bcf4ec8db8164e9f6738c048b2e66aabf30e7506f440c4cc6953f60/httptools-0.7.1-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9d/b3/11d406849715b47c9d69bb22f50874f80caee96bd1cbe7b61abbebbf5a05/ibis_framework-12.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/5f/63f5fa395c7a8a93558c0904ba8f1c8d1b997ca6a3de61bc7659970d66bf/librt-0.8.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/10/37fd9e9ba96cb0bd742dfb20fc3d082e54bdbec759d7300df927f360ef07/librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/88/eb9a55b3f3cf43a74d6bfa8db0e2e209f966007777a1dc897c52c008314c/mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cc/bf/5404c2fd6ac84819e8ff1b7e34437b37cf55a2b11318894909e7bb88de3f/mmh3-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a4/71/d351dca3e9b30da2328ee9d445c88b8388072808ebfbc49eb69d30b67749/mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/77/fc/8cb9073bb1bee54eb49a1ae501a36402d01763812962ac811cdc1c81a9d7/parsy-2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/8e/4be5617b4aaae0287f621ad31c6036e5f63118cfca0dc57d42121ff49b51/pyarrow-23.0.1-cp310-cp310-macosx_12_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1d/41/64180033d7027afce12dc96d0fe1f504c6fa112190582b458acea2399530/pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2e/c3/94ade4906a2f88bc935772f59c934013b4205e773bcb4239db114a6da136/pyarrow_hotfix-0.7-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -511,124 +513,124 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/9664130905f03db57961b8980b05cab624afd114bf2be2576628a9f22da4/sqlalchemy-2.0.48-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/c9/f58c3a17beb650700f9d2eccd410726b6d96df8953663700764ca48636c7/sqlglot-29.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/4c/41b222c130950a077e1a0ba311df84a29b818db7c136ecc1aafbfad42e26/sqlglot-30.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/ae/6f6f9af7f590b319c94532b9567409ba11f4fa71af1148cab1bf48a07048/uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a7/1a/206e8cf2dd86fddf939165a57b4df61607a1e0add2785f170a3f616b7d9f/watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0d/5a/2bf22ecb24916983bf1cc0095e7dea2741d14d6553b0d6a2ac8bc96eca93/watchfiles-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/19/0f/22ef6107ee52ab7f0b710d55d36f5a5d3ef19e8a205541a6d7ffa7994e5a/websockets-16.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ca/21/293b657a27accfbbbb6007ebd78af0efa2083dac83e8f523272ea09b4638/wrapt-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b4/8b/84bc1ea68b620fe0e2696a8cff07e82f4b962d952ab14efee8955997bb70/wrapt-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.20-h1b19095_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/c0/271f3e1e3502a8decb8ee5c680dbed2d8dc2cd504f5e20f7ed491d5f37e1/atpublic-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/7a/ec22ff9d5c891b4f9ae834ef70524c92bd59d1408e9944e2652c87bc3f02/deltalake-0.25.5-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/80/bd/ffc9e7a52731eec047dd49d45f029580dc8f3a6f8e8802a9e1c4138b0f8a/duckdb-1.5.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/4f/35e3a63f863a659f92ffd92bef131f3e81cf849af26e6435b49bd9f6f751/httptools-0.7.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9d/b3/11d406849715b47c9d69bb22f50874f80caee96bd1cbe7b61abbebbf5a05/ibis_framework-12.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/e0/0472cf37267b5920eff2f292ccfaede1886288ce35b7f3203d8de00abfe6/librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cf/72/1b1466f358e4a0b728051f69bc27e67b432c6eaa2e05b88db49d3785ae0d/librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/4c/8e4b3878bf8435c697d7ce99940a3784eb864521768069feaccaff884a17/mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/de/0b/52bffad0b52ae4ea53e222b594bd38c08ecac1fc410323220a7202e43da5/mmh3-5.2.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2f/45/7d51594b644c17c0bcf74ed8cd5fc33b324276d708e8506f220b70dab9d9/mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/77/fc/8cb9073bb1bee54eb49a1ae501a36402d01763812962ac811cdc1c81a9d7/parsy-2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/a8/24e5dc6855f50a62936ceb004e6e9645e4219a8065f304145d7fb8a79d5d/pyarrow-23.0.1-cp310-cp310-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a5/bf/a34fee1d624152124fa8355c42f34195ad5fe5233ce5bb87946432047d52/pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2e/c3/94ade4906a2f88bc935772f59c934013b4205e773bcb4239db114a6da136/pyarrow_hotfix-0.7-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -641,135 +643,148 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/67/1235676e93dd3b742a4a8eddfae49eea46c85e3eed29f0da446a8dd57500/sqlalchemy-2.0.48-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/ad/c9/f58c3a17beb650700f9d2eccd410726b6d96df8953663700764ca48636c7/sqlglot-29.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/a9/812a775bd8c1af0966d660238d005baf25e9bced1f038c8e71f00aa637a7/sqlalchemy-2.0.50-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/13/4c/41b222c130950a077e1a0ba311df84a29b818db7c136ecc1aafbfad42e26/sqlglot-30.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/14/ecceb239b65adaaf7fde510aa8bd534075695d1e5f8dadfa32b5723d9cfb/uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b3/0f/abaf5262b9c496b5dad4ed3c0e799cbecb1f8ea512ecb6ddd46646a9fca3/watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/55/70/dea1f6a0e76607841a60fb51af150e70124864673f61704abb62b90cdcc7/watchfiles-1.2.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/25/e9/96dd77728b54a899d4ce2798d7b1296989ce687ed3c0cb917d6b3154bf5d/wrapt-2.1.1-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/8f/64ec81194a0bc708d9720174c998c8a32116e82b5b32c04e20a7fe01176c/wrapt-2.2.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ ray-tests: channels: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/32/5a05303b0874458920b73f48b8779cc3a93d503f121b38dcc0456dbd698c/aiohttp-3.14.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/66/73034ad30b59f13439b75e620989dacba4c047256e358ba7c2e9ec98ea22/datasets-5.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/58/2f/f3fc773270cf17e7ca076c1f6435278f58641d475a25cdeea5b2d8d4845b/grpcio-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/b8/8b83d18ae07c46c019617f35afd7b47aab7f9b4fbb12fc637d681e10bdd8/greenlet-3.5.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9a/df/ec0a4e04472df2618f8741151fa026bc877648e952ebb0e421169e0b992b/grpcio-1.81.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/49/4d/103f76b04310e5e57656696cc184690d20c466af0bca3ca88f8c8ea5d4f3/hf_xet-1.5.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/71/b0a9193641d9e2471ac541d3b1b869538a5fb6419d52fd2669fa9c79e4b8/httptools-0.7.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/03/40a05316cb6616e5b7efd7773656441ab04b4b022c2199e79bb4622a92a3/huggingface_hub-1.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/99/f85130582f05dcf0c8902f3d629270231d2f4afdfc567f8305a952ac7f14/librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/50/5ec949d7f9ce1a07af903aa3e13abb98b717923bdead6e719b2f824ccc07/librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/8e/29306d5eca6dfda4b899d22c95b5420db4e0ffb7e0b6389b17379654ece5/mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c6/b1/e20d5f0d19c4c0f3df213fa7dcfa0942c4fb127d38e11f398ae8ddf6cccc/mmh3-5.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b7/09/2a06956383c0fdebaef5aa9246e2356776f12ea6f2a44bd1368abf0e46c4/msgpack-1.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/ac/b605473de2bb404e742f2cc3583d12aedb2352a70e49ae8fce455b50c5aa/multidict-6.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/5a/93093f0b29a9e982deafde698f740a2eb2e05886e79ccf0594c7fd5413a3/mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/57/89727baef7578897af5ed166735ceb315819f1c184da8c3441271dbcfde7/protobuf-7.34.0-cp310-abi3-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/39/6e/899fed76dc1942b8a64193a4f059d7f1a2c7ef65085e8a9366ed8ec0d199/propcache-0.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/82/c40b68001dbec8a3faa4c08cd8c200798ac732d2854537c5449dc859f55a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/67/33/f75e91b9a64c3f33c787e263c93b871ad91b8a4a68c1d5cebddd9840e835/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -782,117 +797,136 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b0/b1/8cc4e45a3ce87aabcb70696b448b20840bcbaa5c98bdb4807a2749541fda/ray-2.54.0-cp310-cp310-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b4/64/640f5525bac171282c6f76f3ecc9c4cfef60149ac0d00231afb22018ebe5/ray-2.55.1-cp310-cp310-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/ad/6c4395649a212a6c603a72c5b9ab5dce3135a1546cfdffa3c427e71fd535/sqlalchemy-2.0.48-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/55/b260d8df2adc9bb0bf294f67b5f802ff0d84d99442b536b9efd0ea72d447/sqlalchemy-2.0.50-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/f6/21657bb3beb5f8c57ce8be3b83f653dd7933c2fd00545ed1b092d464799a/uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/dc/1a680b7458ffa3b14bb64878112aefc8f2e4f73c5af763cbf0bd43100658/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/02/c8/79eee650c62d2c186598489814468e389b5def0ebe755399ff645b35b1b2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9d/2f/4b3ca7e106bc608744b1cdae041e005e446124bebb037b18799c2d356864/websockets-16.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/79/4c755b45df6ef30c0dd628ecfaa0c808854be147ca438429da70a162833c/wrapt-2.1.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/c2/3d186944aae923631d1def58f4c4ff8f0b6309906afc0b6978de3e69b3e0/wrapt-2.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a4/db/268012153eb7f6bf2c8a0491fdcde11e093f166990821a2ab754fe95537d/xxhash-3.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/02/ad/0b9cc9f38a7324a7eb1d80f834eaa5283d17e9271bbda3186e598dddaeac/yarl-1.24.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.19-h988dfef_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.2-h8f8c405_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.20-hea035f4_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/54/444d37eebf0f15db661ca44ec7caf93962f3c5ca92eb4c9a5d888b70aaa2/aiohttp-3.14.0-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/66/73034ad30b59f13439b75e620989dacba4c047256e358ba7c2e9ec98ea22/datasets-5.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/fb/c85f9fed3ea8fe8740e5b46a59cc141c23b842eca617da8876cfce5f760e/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1d/21/117c8710abb7f146d804a124c07eb5964a60b90d02b72452885aecc18efa/greenlet-3.5.1-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/fb/69ff198a82cae7eb1a69fb84d93b3a3e4816564d76817fe541ddc96874eb/hf_xet-1.5.0-cp37-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/e5/c07e0bcf4ec8db8164e9f6738c048b2e66aabf30e7506f440c4cc6953f60/httptools-0.7.1-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/03/40a05316cb6616e5b7efd7773656441ab04b4b022c2199e79bb4622a92a3/huggingface_hub-1.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/5f/63f5fa395c7a8a93558c0904ba8f1c8d1b997ca6a3de61bc7659970d66bf/librt-0.8.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/10/37fd9e9ba96cb0bd742dfb20fc3d082e54bdbec759d7300df927f360ef07/librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/88/eb9a55b3f3cf43a74d6bfa8db0e2e209f966007777a1dc897c52c008314c/mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cc/bf/5404c2fd6ac84819e8ff1b7e34437b37cf55a2b11318894909e7bb88de3f/mmh3-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f5/a2/3b68a9e769db68668b25c6108444a35f9bd163bb848c0650d516761a59c0/msgpack-1.1.2-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ef/04/9de3f8077852e3d438215c81e9b691244532d2e05b4270e89ce67b7d103c/multidict-6.7.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/71/d351dca3e9b30da2328ee9d445c88b8388072808ebfbc49eb69d30b67749/mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/1a/55/1140a8e067b8ec093a18a4ae7bb0045d9db65da38a08618ddc5e2f1994aa/propcache-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/8e/4be5617b4aaae0287f621ad31c6036e5f63118cfca0dc57d42121ff49b51/pyarrow-23.0.1-cp310-cp310-macosx_12_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1d/41/64180033d7027afce12dc96d0fe1f504c6fa112190582b458acea2399530/pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -905,117 +939,135 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/61/c5/c2ceba832fe3f47cfd7e11cd7cc7a1bbc2c028424c5bca70435aa4ca1dec/ray-2.49.2-cp310-cp310-macosx_12_0_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/9664130905f03db57961b8980b05cab624afd114bf2be2576628a9f22da4/sqlalchemy-2.0.48-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/ae/6f6f9af7f590b319c94532b9567409ba11f4fa71af1148cab1bf48a07048/uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a7/1a/206e8cf2dd86fddf939165a57b4df61607a1e0add2785f170a3f616b7d9f/watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0d/5a/2bf22ecb24916983bf1cc0095e7dea2741d14d6553b0d6a2ac8bc96eca93/watchfiles-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/19/0f/22ef6107ee52ab7f0b710d55d36f5a5d3ef19e8a205541a6d7ffa7994e5a/websockets-16.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ca/21/293b657a27accfbbbb6007ebd78af0efa2083dac83e8f523272ea09b4638/wrapt-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b4/8b/84bc1ea68b620fe0e2696a8cff07e82f4b962d952ab14efee8955997bb70/wrapt-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/92/49/e4b575b4ed170a7f640c8bd69cfadfa81c7b700191fde5e72228762b9f73/xxhash-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/48/41/7daafb32dd7562bf45b1ce56562e7e1a9146f6479b6456873eb8a3413c40/yarl-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.20-h1b19095_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d1/da280e23321c132c0a3fa7c8cc2830621d79174edc64c829443346489a36/aiohttp-3.14.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/66/73034ad30b59f13439b75e620989dacba4c047256e358ba7c2e9ec98ea22/datasets-5.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/70/26ca3f06aace16f2352796b08704338d74b6d1a24ca38f2771afbb7ed915/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/ff/edcc2b40162bef3ff78e14ab637e5f3b89243d6aee72f5949d3bb6a5af83/hf_xet-1.5.0-cp37-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/4f/35e3a63f863a659f92ffd92bef131f3e81cf849af26e6435b49bd9f6f751/httptools-0.7.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/03/40a05316cb6616e5b7efd7773656441ab04b4b022c2199e79bb4622a92a3/huggingface_hub-1.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/e0/0472cf37267b5920eff2f292ccfaede1886288ce35b7f3203d8de00abfe6/librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cf/72/1b1466f358e4a0b728051f69bc27e67b432c6eaa2e05b88db49d3785ae0d/librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/4c/8e4b3878bf8435c697d7ce99940a3784eb864521768069feaccaff884a17/mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/de/0b/52bffad0b52ae4ea53e222b594bd38c08ecac1fc410323220a7202e43da5/mmh3-5.2.1-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/5b/e1/2b720cc341325c00be44e1ed59e7cfeae2678329fbf5aa68f5bda57fe728/msgpack-1.1.2-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/31/5c/08c7f7fe311f32e83f7621cd3f99d805f45519cd06fafb247628b861da7d/multidict-6.7.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/45/7d51594b644c17c0bcf74ed8cd5fc33b324276d708e8506f220b70dab9d9/mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/20/42/0e7443c90310498561addf346e7d57fe3c6ba1914e1ba938b5464c7bbfd2/propcache-0.5.2-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/a8/24e5dc6855f50a62936ceb004e6e9645e4219a8065f304145d7fb8a79d5d/pyarrow-23.0.1-cp310-cp310-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a5/bf/a34fee1d624152124fa8355c42f34195ad5fe5233ce5bb87946432047d52/pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -1028,177 +1080,182 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/64/13/b86d791b41f33220335eba18fc4841f1ebddae41e562c6a216846404c88d/ray-2.54.0-cp310-cp310-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7e/d0/a85097dd53aaca1a44acc4dd0b3d2c0e9233179433e2ee326e4018ab3cf7/ray-2.55.1-cp310-cp310-macosx_12_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/67/1235676e93dd3b742a4a8eddfae49eea46c85e3eed29f0da446a8dd57500/sqlalchemy-2.0.48-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/a9/812a775bd8c1af0966d660238d005baf25e9bced1f038c8e71f00aa637a7/sqlalchemy-2.0.50-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/14/ecceb239b65adaaf7fde510aa8bd534075695d1e5f8dadfa32b5723d9cfb/uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b3/0f/abaf5262b9c496b5dad4ed3c0e799cbecb1f8ea512ecb6ddd46646a9fca3/watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/55/70/dea1f6a0e76607841a60fb51af150e70124864673f61704abb62b90cdcc7/watchfiles-1.2.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/25/e9/96dd77728b54a899d4ce2798d7b1296989ce687ed3c0cb917d6b3154bf5d/wrapt-2.1.1-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/8f/64ec81194a0bc708d9720174c998c8a32116e82b5b32c04e20a7fe01176c/wrapt-2.2.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/07/61/40f0155b0b09988eb6cdbfc52652f2f371810b0c58163208cb05667757bd/xxhash-3.7.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a8/8f/7b3ec212f1ea0683f55f978e3246bc313c38818664edfc97a9f349a4901e/yarl-1.24.2-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ registration-tests: channels: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - pypi: https://files.pythonhosted.org/packages/92/d9/25a697a959a7149c93efa4d849421aa5f22bcb82350ac89b4284b0b88aa8/aiobotocore-2.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/c0/cfcc3d2e11b477f86e1af2863f3858c8850d751ce8dc39c4058a072c9e54/aiohttp-3.13.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/90/5f/85535dfb3cfd6442d66d1df1694062c5d6df02f895329e7e120b2a3d2b8b/aiobotocore-3.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/32/5a05303b0874458920b73f48b8779cc3a93d503f121b38dcc0456dbd698c/aiohttp-3.14.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8b/b2361188bd1e293eede1bc165e2461d390394f71ec0c8c21211c8dabf62c/boto3-1.38.27-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/00/dd90b7a0255587ba1c9754d32a221adb4a9022f181df3eef401b0b9fadfc/botocore-1.38.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/a0/3e6a0b1c1ea6bec76f71473727ef27abf3cd40e9709b3ebcbfbcfaae6f79/boto3-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/4b/afc1fef8a43bafb139f57f73bbd70df82807af5934321e8112ae50668827/botocore-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/80/171c7c5b78e60ab25d6f11e3d38675fe7ef843ddc79a7fd26916d3a6ca05/db_dtypes-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7a/797ed371bde520223e49dbbe0f8762fa4cc724d0e21fc6af944bb8f82150/db_dtypes-1.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1d/a0/6aaea0c2fbea2f89bfd5db25fb1e3481896a423002ebe4e55288907a97a3/fsspec-2024.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/45/27/09c33d67f7e0dcf06d7ac17d196594e66989299374bfb0d4331d1038e76b/google_api_core-2.30.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/1d/d6466de3a5249d35e832a52834115ca9d1d0de6abc22065f049707516d47/google_auth-2.48.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/56/909fd5632226d3fba31d7aeffd4754410735d49362f5809956fe3e9af344/google_auth_oauthlib-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/f5/081cf5b90adfe524ae0d671781b0d497a75a0f2601d075af518828e22d8f/google_cloud_bigquery-3.40.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1f/07/62dbe78ef773569be0a1d2c1b845e9214889b404e506126519b4d33ee999/google_cloud_bigquery_storage-2.36.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/69/03eed134d71f6117ffd9efac2d1033bb2fa2522e9e82545a0828061d32f4/google_cloud_bigtable-2.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/20/bfa472e327c8edee00f04beecc80baeddd2ab33ee0e86fd7654da49d45e9/google_cloud_core-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/88/348c09570a03886356c02337f06d69532fa17a66ad2a9dff584f7b60eb04/google_cloud_datastore-2.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/c9/db44165ba7c581268c6d46017ef63339110378305062830104fc7fa144cb/google_auth-2.53.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/d3/d7dff0d58a9e9244b48044bfb6a898bfcc8ecc42e0031d1bebc695344725/google_auth_oauthlib-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/33/1d3902efadef9194566d499d61507e1f038454e0b55499d2d7f8ab2a4fee/google_cloud_bigquery-3.41.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/f6/4157466c10181907d07786fb41df5d0a9ff339c1770b9e2a15cfe483e845/google_cloud_bigquery_storage-2.39.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9d/9c0a81aa9cf6c058b02d3be194d70bcd7e4bd82f631c8110560c3908dbc4/google_cloud_bigtable-2.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/b2/fd5a3e55a5f698fd527f783ce27368e8e9c3d872bd1e1c39dd377b2b9f14/google_cloud_datastore-2.25.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3d/63/bec827e70b7a0d4094e7476f863c0dbd6b5f0f1f91d9c9b32b76dcdfeb4e/google_crc32c-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1f/0b/93afde9cfe012260e9fe1522f35c9b72d6ee222f316586b1f23ecf44d518/google_resumable_media-2.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/4a/bd/330a1bbdb1afe0b96311249e699b6dc9cfc17916394fd4503ac5aca2514b/grpc_google_iam_v1-0.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/58/2f/f3fc773270cf17e7ca076c1f6435278f58641d475a25cdeea5b2d8d4845b/grpcio-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/b8/8b83d18ae07c46c019617f35afd7b47aab7f9b4fbb12fc637d681e10bdd8/greenlet-3.5.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/df/ec0a4e04472df2618f8741151fa026bc877648e952ebb0e421169e0b992b/grpcio-1.81.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/b7/5aa346bf1cdecd4ed64b86c10a4d5a089ce3da89145f8328caf0b22b240d/grpcio_status-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/69/cc76b0ef3248cb5f8389fabb9d69e23c597664e5f7f40861e3ebb04bd46b/grpcio_testing-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/6e/8adaefff7e3e216b0f7bd6cafce6d5d06798f31c3e2852dc3db6a7d758c9/hiredis-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/26/c9/4e9cd249afc101ac283943295fe3359bdd711a0bb8c667752eb0da80609d/hiredis-3.4.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/71/b0a9193641d9e2471ac541d3b1b869538a5fb6419d52fd2669fa9c79e4b8/httptools-0.7.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/99/f85130582f05dcf0c8902f3d629270231d2f4afdfc567f8305a952ac7f14/librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/50/5ec949d7f9ce1a07af903aa3e13abb98b717923bdead6e719b2f824ccc07/librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/8e/29306d5eca6dfda4b899d22c95b5420db4e0ffb7e0b6389b17379654ece5/mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c6/b1/e20d5f0d19c4c0f3df213fa7dcfa0942c4fb127d38e11f398ae8ddf6cccc/mmh3-5.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/4b/ac/b605473de2bb404e742f2cc3583d12aedb2352a70e49ae8fce455b50c5aa/multidict-6.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/41/5a/93093f0b29a9e982deafde698f740a2eb2e05886e79ccf0594c7fd5413a3/mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/26/b7/e805de93e3aa78813912b19edc9c8b037d6cd1c302ab339b895f305cf9a5/pandas_gbq-0.33.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/3d/2f0e9c5cbc456d34f48215645d876f7885a15e09a72a07d1de3ddb181c38/pandas_gbq-0.35.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5d/79/ac273cbbf744691821a9cca88957257f41afe271637794975ca090b9588b/proto_plus-1.27.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9b/53/a9443aa3ca9ba8724fdfa02dd1887c1bcd8e89556b715cfbacca6b63dbec/protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/39/6e/899fed76dc1942b8a64193a4f059d7f1a2c7ef65085e8a9366ed8ec0d199/propcache-0.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/18/f3/14a1370b1449ca875d5e353ef02cb9db6b70bd46ec361c236176837c0be1/psycopg-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/90/9f2c41b3b42d8cd8b9866f0bbd27a5796a1ca8042a1a019b39a6645df523/psycopg_binary-3.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/26b8a0908a9db249de3b4169692e1c7c19048a9bc41a4d3209cee7dbb758/psycopg_pool-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/9a/f088207b4cd6772f9e0d8a91807e79fa2458d4eb9eb1ae406c68415f2bec/psycopg_binary-3.3.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/37/ed/89c2c620af0e1660354cd8aabf9f5b21f911597ce22acb37c805d6c86bc8/psycopg_pool-3.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/db/ea0203e495be491c85af87b66e37acfd3bf756fd985f87e46fc5e3bf022c/py4j-0.10.9.9-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/82/c40b68001dbec8a3faa4c08cd8c200798ac732d2854537c5449dc859f55a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/33/f75e91b9a64c3f33c787e263c93b871ad91b8a4a68c1d5cebddd9840e835/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ca/cb/cdeaba62aa3c48f0d8834afb82b4a21463cd83df34fe01f9daa89a08ec6c/pydata_google_auth-1.9.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/28/2659c02301b9500751f8d42f9a6632e1508aa5120de5e43042b8b30f8d5d/pyopenssl-25.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/bf/58ee13add151469c25825b7125bbf62c3bdcec05eec4d458fcb5c5516066/pyspark-4.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/bd/2534e130295c8cfd4f0a2e31623baab7502278f1e97bcfe61db75656a77f/pymysql-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/71/4dd20c69332a2a4bf7ece8a655c9da98e4bd9b6bcea235349c1a00399d57/pyspark-4.1.2.tar.gz - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -1211,169 +1268,169 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/2e/409703d645363352a20c944f5d119bdae3eb3034051a53724a7c5fee12b8/redis-4.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/2e/2677f3f93dae0497e7e33b6637302e7f3744efc553f34231183e32584885/redis-7.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/dd/904873250a6554fbae40cddbf9198e3cc37a2f1319d5e1a5ce82fe269c17/s3transfer-0.17.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/60/e6/30c4015e2712bf8bf83b54ddadeee0494b68ae6d0f6d49d9373f463305d4/snowflake_connector_python-4.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/74/19/996b45846fcc5f2015bd70ed98420b11c847c1b79b57b82b250e0a409f49/snowflake_connector_python-4.6.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/ad/6c4395649a212a6c603a72c5b9ab5dce3135a1546cfdffa3c427e71fd535/sqlalchemy-2.0.48-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/55/b260d8df2adc9bb0bf294f67b5f802ff0d84d99442b536b9efd0ea72d447/sqlalchemy-2.0.50-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/fa/4f4d3bfca9ef6dd17d69ed18b96564c53b32d3ce774132308d0bee849f10/types_pymysql-1.1.0.20251220-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/5a/db02b5e6633fbe49eaf4e3194bc64ec031e6436a0cfcc610cbda4f1b6a24/types_pymysql-1.1.0.20260518-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/f6/21657bb3beb5f8c57ce8be3b83f653dd7933c2fd00545ed1b092d464799a/uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/dc/1a680b7458ffa3b14bb64878112aefc8f2e4f73c5af763cbf0bd43100658/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/02/c8/79eee650c62d2c186598489814468e389b5def0ebe755399ff645b35b1b2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9d/2f/4b3ca7e106bc608744b1cdae041e005e446124bebb037b18799c2d356864/websockets-16.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/c2/3d186944aae923631d1def58f4c4ff8f0b6309906afc0b6978de3e69b3e0/wrapt-2.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/02/ad/0b9cc9f38a7324a7eb1d80f834eaa5283d17e9271bbda3186e598dddaeac/yarl-1.24.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.19-h988dfef_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.2-h8f8c405_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.20-hea035f4_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - pypi: https://files.pythonhosted.org/packages/92/d9/25a697a959a7149c93efa4d849421aa5f22bcb82350ac89b4284b0b88aa8/aiobotocore-2.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/03/8fa90a7e6d11ff20a18837a8e2b5dd23db01aabc475aa9271c8ad33299f5/aiohttp-3.13.3-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/90/5f/85535dfb3cfd6442d66d1df1694062c5d6df02f895329e7e120b2a3d2b8b/aiobotocore-3.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/54/444d37eebf0f15db661ca44ec7caf93962f3c5ca92eb4c9a5d888b70aaa2/aiohttp-3.14.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8b/b2361188bd1e293eede1bc165e2461d390394f71ec0c8c21211c8dabf62c/boto3-1.38.27-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/00/dd90b7a0255587ba1c9754d32a221adb4a9022f181df3eef401b0b9fadfc/botocore-1.38.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/a0/3e6a0b1c1ea6bec76f71473727ef27abf3cd40e9709b3ebcbfbcfaae6f79/boto3-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/4b/afc1fef8a43bafb139f57f73bbd70df82807af5934321e8112ae50668827/botocore-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/80/171c7c5b78e60ab25d6f11e3d38675fe7ef843ddc79a7fd26916d3a6ca05/db_dtypes-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7a/797ed371bde520223e49dbbe0f8762fa4cc724d0e21fc6af944bb8f82150/db_dtypes-1.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a2/fb/c85f9fed3ea8fe8740e5b46a59cc141c23b842eca617da8876cfce5f760e/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1d/a0/6aaea0c2fbea2f89bfd5db25fb1e3481896a423002ebe4e55288907a97a3/fsspec-2024.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/45/27/09c33d67f7e0dcf06d7ac17d196594e66989299374bfb0d4331d1038e76b/google_api_core-2.30.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/1d/d6466de3a5249d35e832a52834115ca9d1d0de6abc22065f049707516d47/google_auth-2.48.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/56/909fd5632226d3fba31d7aeffd4754410735d49362f5809956fe3e9af344/google_auth_oauthlib-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/f5/081cf5b90adfe524ae0d671781b0d497a75a0f2601d075af518828e22d8f/google_cloud_bigquery-3.40.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1f/07/62dbe78ef773569be0a1d2c1b845e9214889b404e506126519b4d33ee999/google_cloud_bigquery_storage-2.36.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/69/03eed134d71f6117ffd9efac2d1033bb2fa2522e9e82545a0828061d32f4/google_cloud_bigtable-2.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/20/bfa472e327c8edee00f04beecc80baeddd2ab33ee0e86fd7654da49d45e9/google_cloud_core-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/88/348c09570a03886356c02337f06d69532fa17a66ad2a9dff584f7b60eb04/google_cloud_datastore-2.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/c9/db44165ba7c581268c6d46017ef63339110378305062830104fc7fa144cb/google_auth-2.53.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/d3/d7dff0d58a9e9244b48044bfb6a898bfcc8ecc42e0031d1bebc695344725/google_auth_oauthlib-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/33/1d3902efadef9194566d499d61507e1f038454e0b55499d2d7f8ab2a4fee/google_cloud_bigquery-3.41.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/f6/4157466c10181907d07786fb41df5d0a9ff339c1770b9e2a15cfe483e845/google_cloud_bigquery_storage-2.39.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9d/9c0a81aa9cf6c058b02d3be194d70bcd7e4bd82f631c8110560c3908dbc4/google_cloud_bigtable-2.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/b2/fd5a3e55a5f698fd527f783ce27368e8e9c3d872bd1e1c39dd377b2b9f14/google_cloud_datastore-2.25.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/97/a5accde175dee985311d949cfcb1249dcbb290f5ec83c994ea733311948f/google_crc32c-1.8.0-cp310-cp310-macosx_12_0_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1f/0b/93afde9cfe012260e9fe1522f35c9b72d6ee222f316586b1f23ecf44d518/google_resumable_media-2.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/4a/bd/330a1bbdb1afe0b96311249e699b6dc9cfc17916394fd4503ac5aca2514b/grpc_google_iam_v1-0.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1d/21/117c8710abb7f146d804a124c07eb5964a60b90d02b72452885aecc18efa/greenlet-3.5.1-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/b7/5aa346bf1cdecd4ed64b86c10a4d5a089ce3da89145f8328caf0b22b240d/grpcio_status-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/69/cc76b0ef3248cb5f8389fabb9d69e23c597664e5f7f40861e3ebb04bd46b/grpcio_testing-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/70/3f39ebfb3824578c34400df3b037b268abb5af0abaa789b430ffd17dd74e/hiredis-2.4.0-cp310-cp310-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6f/75/2a08a6062228720747570a07ab42e6f5826725f09c9a95d75b7b5b938022/hiredis-3.4.0-cp310-cp310-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/e5/c07e0bcf4ec8db8164e9f6738c048b2e66aabf30e7506f440c4cc6953f60/httptools-0.7.1-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/5f/63f5fa395c7a8a93558c0904ba8f1c8d1b997ca6a3de61bc7659970d66bf/librt-0.8.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/10/37fd9e9ba96cb0bd742dfb20fc3d082e54bdbec759d7300df927f360ef07/librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/88/eb9a55b3f3cf43a74d6bfa8db0e2e209f966007777a1dc897c52c008314c/mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cc/bf/5404c2fd6ac84819e8ff1b7e34437b37cf55a2b11318894909e7bb88de3f/mmh3-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ef/04/9de3f8077852e3d438215c81e9b691244532d2e05b4270e89ce67b7d103c/multidict-6.7.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a4/71/d351dca3e9b30da2328ee9d445c88b8388072808ebfbc49eb69d30b67749/mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/26/b7/e805de93e3aa78813912b19edc9c8b037d6cd1c302ab339b895f305cf9a5/pandas_gbq-0.33.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/3d/2f0e9c5cbc456d34f48215645d876f7885a15e09a72a07d1de3ddb181c38/pandas_gbq-0.35.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5d/79/ac273cbbf744691821a9cca88957257f41afe271637794975ca090b9588b/proto_plus-1.27.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/1a/55/1140a8e067b8ec093a18a4ae7bb0045d9db65da38a08618ddc5e2f1994aa/propcache-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/18/f3/14a1370b1449ca875d5e353ef02cb9db6b70bd46ec361c236176837c0be1/psycopg-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/30/af3806081adc75b5a8addde839d4c6b171a8c5d0d07dd92de20ca4dd6717/psycopg_binary-3.2.5-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/26b8a0908a9db249de3b4169692e1c7c19048a9bc41a4d3209cee7dbb758/psycopg_pool-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/bf/70d8a60488f9955cbbcd538beae44d56bb2f1d19e673b72788f2d343ff55/psycopg_binary-3.3.4-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/37/ed/89c2c620af0e1660354cd8aabf9f5b21f911597ce22acb37c805d6c86bc8/psycopg_pool-3.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/db/ea0203e495be491c85af87b66e37acfd3bf756fd985f87e46fc5e3bf022c/py4j-0.10.9.9-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/8e/4be5617b4aaae0287f621ad31c6036e5f63118cfca0dc57d42121ff49b51/pyarrow-23.0.1-cp310-cp310-macosx_12_0_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1d/41/64180033d7027afce12dc96d0fe1f504c6fa112190582b458acea2399530/pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ca/cb/cdeaba62aa3c48f0d8834afb82b4a21463cd83df34fe01f9daa89a08ec6c/pydata_google_auth-1.9.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/28/2659c02301b9500751f8d42f9a6632e1508aa5120de5e43042b8b30f8d5d/pyopenssl-25.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/bf/58ee13add151469c25825b7125bbf62c3bdcec05eec4d458fcb5c5516066/pyspark-4.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/bd/2534e130295c8cfd4f0a2e31623baab7502278f1e97bcfe61db75656a77f/pymysql-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/71/4dd20c69332a2a4bf7ece8a655c9da98e4bd9b6bcea235349c1a00399d57/pyspark-4.1.2.tar.gz - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -1386,169 +1443,168 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/2e/409703d645363352a20c944f5d119bdae3eb3034051a53724a7c5fee12b8/redis-4.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/2e/2677f3f93dae0497e7e33b6637302e7f3744efc553f34231183e32584885/redis-7.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/dd/904873250a6554fbae40cddbf9198e3cc37a2f1319d5e1a5ce82fe269c17/s3transfer-0.17.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/80/3a7e36a9e53beeb27c0599d2703f33bb812be931b469b154b08df0eeeaf5/snowflake_connector_python-4.0.0-cp310-cp310-macosx_11_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/49/4d/7e6a9088381386b4cfae4c5d1d23ea0c3618ca694bc2290118737af59f36/snowflake_connector_python-4.6.0.tar.gz - pypi: https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/9664130905f03db57961b8980b05cab624afd114bf2be2576628a9f22da4/sqlalchemy-2.0.48-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/fa/4f4d3bfca9ef6dd17d69ed18b96564c53b32d3ce774132308d0bee849f10/types_pymysql-1.1.0.20251220-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/5a/db02b5e6633fbe49eaf4e3194bc64ec031e6436a0cfcc610cbda4f1b6a24/types_pymysql-1.1.0.20260518-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/ae/6f6f9af7f590b319c94532b9567409ba11f4fa71af1148cab1bf48a07048/uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a7/1a/206e8cf2dd86fddf939165a57b4df61607a1e0add2785f170a3f616b7d9f/watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0d/5a/2bf22ecb24916983bf1cc0095e7dea2741d14d6553b0d6a2ac8bc96eca93/watchfiles-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/19/0f/22ef6107ee52ab7f0b710d55d36f5a5d3ef19e8a205541a6d7ffa7994e5a/websockets-16.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b4/8b/84bc1ea68b620fe0e2696a8cff07e82f4b962d952ab14efee8955997bb70/wrapt-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/48/41/7daafb32dd7562bf45b1ce56562e7e1a9146f6479b6456873eb8a3413c40/yarl-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.20-h1b19095_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - pypi: https://files.pythonhosted.org/packages/92/d9/25a697a959a7149c93efa4d849421aa5f22bcb82350ac89b4284b0b88aa8/aiobotocore-2.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/23/b81f744d402510a8366b74eb420fc0cc1170d0c43daca12d10814df85f10/aiohttp-3.13.3-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/90/5f/85535dfb3cfd6442d66d1df1694062c5d6df02f895329e7e120b2a3d2b8b/aiobotocore-3.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d1/da280e23321c132c0a3fa7c8cc2830621d79174edc64c829443346489a36/aiohttp-3.14.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8b/b2361188bd1e293eede1bc165e2461d390394f71ec0c8c21211c8dabf62c/boto3-1.38.27-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/00/dd90b7a0255587ba1c9754d32a221adb4a9022f181df3eef401b0b9fadfc/botocore-1.38.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/a0/3e6a0b1c1ea6bec76f71473727ef27abf3cd40e9709b3ebcbfbcfaae6f79/boto3-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/4b/afc1fef8a43bafb139f57f73bbd70df82807af5934321e8112ae50668827/botocore-1.43.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/80/171c7c5b78e60ab25d6f11e3d38675fe7ef843ddc79a7fd26916d3a6ca05/db_dtypes-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7a/797ed371bde520223e49dbbe0f8762fa4cc724d0e21fc6af944bb8f82150/db_dtypes-1.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/63/70/26ca3f06aace16f2352796b08704338d74b6d1a24ca38f2771afbb7ed915/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1d/a0/6aaea0c2fbea2f89bfd5db25fb1e3481896a423002ebe4e55288907a97a3/fsspec-2024.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/45/27/09c33d67f7e0dcf06d7ac17d196594e66989299374bfb0d4331d1038e76b/google_api_core-2.30.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/1d/d6466de3a5249d35e832a52834115ca9d1d0de6abc22065f049707516d47/google_auth-2.48.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/56/909fd5632226d3fba31d7aeffd4754410735d49362f5809956fe3e9af344/google_auth_oauthlib-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/f5/081cf5b90adfe524ae0d671781b0d497a75a0f2601d075af518828e22d8f/google_cloud_bigquery-3.40.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1f/07/62dbe78ef773569be0a1d2c1b845e9214889b404e506126519b4d33ee999/google_cloud_bigquery_storage-2.36.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/69/03eed134d71f6117ffd9efac2d1033bb2fa2522e9e82545a0828061d32f4/google_cloud_bigtable-2.35.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/20/bfa472e327c8edee00f04beecc80baeddd2ab33ee0e86fd7654da49d45e9/google_cloud_core-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/88/348c09570a03886356c02337f06d69532fa17a66ad2a9dff584f7b60eb04/google_cloud_datastore-2.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/c9/db44165ba7c581268c6d46017ef63339110378305062830104fc7fa144cb/google_auth-2.53.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/d3/d7dff0d58a9e9244b48044bfb6a898bfcc8ecc42e0031d1bebc695344725/google_auth_oauthlib-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/33/1d3902efadef9194566d499d61507e1f038454e0b55499d2d7f8ab2a4fee/google_cloud_bigquery-3.41.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/f6/4157466c10181907d07786fb41df5d0a9ff339c1770b9e2a15cfe483e845/google_cloud_bigquery_storage-2.39.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9d/9c0a81aa9cf6c058b02d3be194d70bcd7e4bd82f631c8110560c3908dbc4/google_cloud_bigtable-2.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/b2/fd5a3e55a5f698fd527f783ce27368e8e9c3d872bd1e1c39dd377b2b9f14/google_cloud_datastore-2.25.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/95/ac/6f7bc93886a823ab545948c2dd48143027b2355ad1944c7cf852b338dc91/google_crc32c-1.8.0-cp310-cp310-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1f/0b/93afde9cfe012260e9fe1522f35c9b72d6ee222f316586b1f23ecf44d518/google_resumable_media-2.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/bd/330a1bbdb1afe0b96311249e699b6dc9cfc17916394fd4503ac5aca2514b/grpc_google_iam_v1-0.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/b7/5aa346bf1cdecd4ed64b86c10a4d5a089ce3da89145f8328caf0b22b240d/grpcio_status-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/69/cc76b0ef3248cb5f8389fabb9d69e23c597664e5f7f40861e3ebb04bd46b/grpcio_testing-1.81.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/b7/26a56a3b991abe7fcf7bcfa8e0a08de3c3766c6caecb1ba46239342792ff/hiredis-2.4.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e0/3d/28c61f9c628dfaf1f96bb8b8592cb006eaad3747248c95f9ae7f694abb47/hiredis-3.4.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/4f/35e3a63f863a659f92ffd92bef131f3e81cf849af26e6435b49bd9f6f751/httptools-0.7.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/e0/0472cf37267b5920eff2f292ccfaede1886288ce35b7f3203d8de00abfe6/librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cf/72/1b1466f358e4a0b728051f69bc27e67b432c6eaa2e05b88db49d3785ae0d/librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b6/9e/8d9f6b9746f8ede78b0a4e4b8908e4d80bd609fca0b3e3195a07dda29534/minio-7.2.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/4c/8e4b3878bf8435c697d7ce99940a3784eb864521768069feaccaff884a17/mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/de/0b/52bffad0b52ae4ea53e222b594bd38c08ecac1fc410323220a7202e43da5/mmh3-5.2.1-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/31/5c/08c7f7fe311f32e83f7621cd3f99d805f45519cd06fafb247628b861da7d/multidict-6.7.1-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2f/45/7d51594b644c17c0bcf74ed8cd5fc33b324276d708e8506f220b70dab9d9/mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/26/b7/e805de93e3aa78813912b19edc9c8b037d6cd1c302ab339b895f305cf9a5/pandas_gbq-0.33.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/3d/2f0e9c5cbc456d34f48215645d876f7885a15e09a72a07d1de3ddb181c38/pandas_gbq-0.35.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5d/79/ac273cbbf744691821a9cca88957257f41afe271637794975ca090b9588b/proto_plus-1.27.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/20/42/0e7443c90310498561addf346e7d57fe3c6ba1914e1ba938b5464c7bbfd2/propcache-0.5.2-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/18/f3/14a1370b1449ca875d5e353ef02cb9db6b70bd46ec361c236176837c0be1/psycopg-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/77/31968655db2efe83c519e6296ff3a85a0c9e50432e0c11c8ffae1b404870/psycopg_binary-3.2.5-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/26b8a0908a9db249de3b4169692e1c7c19048a9bc41a4d3209cee7dbb758/psycopg_pool-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/b0/29e98ba210c9dbc75a6dc91e3f99b9e06ea901a62ca95804e02a1ae13e6b/psycopg_binary-3.3.4-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/37/ed/89c2c620af0e1660354cd8aabf9f5b21f911597ce22acb37c805d6c86bc8/psycopg_pool-3.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/db/ea0203e495be491c85af87b66e37acfd3bf756fd985f87e46fc5e3bf022c/py4j-0.10.9.9-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bc/a8/24e5dc6855f50a62936ceb004e6e9645e4219a8065f304145d7fb8a79d5d/pyarrow-23.0.1-cp310-cp310-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/bf/a34fee1d624152124fa8355c42f34195ad5fe5233ce5bb87946432047d52/pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/ca/cb/cdeaba62aa3c48f0d8834afb82b4a21463cd83df34fe01f9daa89a08ec6c/pydata_google_auth-1.9.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/28/2659c02301b9500751f8d42f9a6632e1508aa5120de5e43042b8b30f8d5d/pyopenssl-25.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/bf/58ee13add151469c25825b7125bbf62c3bdcec05eec4d458fcb5c5516066/pyspark-4.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/bd/2534e130295c8cfd4f0a2e31623baab7502278f1e97bcfe61db75656a77f/pymysql-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/71/4dd20c69332a2a4bf7ece8a655c9da98e4bd9b6bcea235349c1a00399d57/pyspark-4.1.2.tar.gz - pypi: https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/60/423a63fb190a0483d049786a121bd3dfd7d93bb5ff1bb5b5cd13e5df99a7/pytest_benchmark-3.4.1-py2.py3-none-any.whl @@ -1561,44 +1617,43 @@ environments: - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2e/2e/dfbd2c9b3edf6a5a8cd9e66090221046839b488ea27824970426bf06b242/python_keycloak-4.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/20/2e/409703d645363352a20c944f5d119bdae3eb3034051a53724a7c5fee12b8/redis-4.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/2e/2677f3f93dae0497e7e33b6637302e7f3744efc553f34231183e32584885/redis-7.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/dd/904873250a6554fbae40cddbf9198e3cc37a2f1319d5e1a5ce82fe269c17/s3transfer-0.17.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/75/f845ca5079a6b911023fa945dbf1bac0ed1c2f5967108b14440c740cb410/snowflake_connector_python-4.0.0-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/49/4d/7e6a9088381386b4cfae4c5d1d23ea0c3618ca694bc2290118737af59f36/snowflake_connector_python-4.6.0.tar.gz - pypi: https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/67/1235676e93dd3b742a4a8eddfae49eea46c85e3eed29f0da446a8dd57500/sqlalchemy-2.0.48-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/a9/812a775bd8c1af0966d660238d005baf25e9bced1f038c8e71f00aa637a7/sqlalchemy-2.0.50-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/fa/4f4d3bfca9ef6dd17d69ed18b96564c53b32d3ce774132308d0bee849f10/types_pymysql-1.1.0.20251220-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/5a/db02b5e6633fbe49eaf4e3194bc64ec031e6436a0cfcc610cbda4f1b6a24/types_pymysql-1.1.0.20260518-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/14/ecceb239b65adaaf7fde510aa8bd534075695d1e5f8dadfa32b5723d9cfb/uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/b3/0f/abaf5262b9c496b5dad4ed3c0e799cbecb1f8ea512ecb6ddd46646a9fca3/watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/55/70/dea1f6a0e76607841a60fb51af150e70124864673f61704abb62b90cdcc7/watchfiles-1.2.0-cp310-cp310-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/8f/64ec81194a0bc708d9720174c998c8a32116e82b5b32c04e20a7fe01176c/wrapt-2.2.1-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a8/8f/7b3ec212f1ea0683f55f978e3246bc313c38818664edfc97a9f349a4901e/yarl-1.24.2-cp310-cp310-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl - pypi: ./ packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda @@ -1615,31 +1670,30 @@ packages: purls: [] size: 28948 timestamp: 1770939786096 -- pypi: https://files.pythonhosted.org/packages/92/d9/25a697a959a7149c93efa4d849421aa5f22bcb82350ac89b4284b0b88aa8/aiobotocore-2.23.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/90/5f/85535dfb3cfd6442d66d1df1694062c5d6df02f895329e7e120b2a3d2b8b/aiobotocore-3.7.0-py3-none-any.whl name: aiobotocore - version: 2.23.1 - sha256: d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 + version: 3.7.0 + sha256: 680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e requires_dist: - - aiohttp>=3.9.2,<4.0.0 + - aiohttp>=3.12.0,<4.0.0 - aioitertools>=0.5.1,<1.0.0 - - botocore>=1.38.40,<1.38.47 + - botocore>=1.42.90,<1.43.1 - python-dateutil>=2.1,<3.0.0 - jmespath>=0.7.1,<2.0.0 - multidict>=6.0.0,<7.0.0 - - wrapt>=1.10.10,<2.0.0 - - awscli>=1.40.39,<1.40.46 ; extra == 'awscli' - - boto3>=1.38.40,<1.38.47 ; extra == 'boto3' + - typing-extensions>=4.14.0,<5.0.0 ; python_full_version < '3.11' + - wrapt>=1.10.10,<3.0.0 - httpx>=0.25.1,<0.29 ; extra == 'httpx' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl name: aiohappyeyeballs - version: 2.6.1 - sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2c/c0/cfcc3d2e11b477f86e1af2863f3858c8850d751ce8dc39c4058a072c9e54/aiohttp-3.13.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + version: 2.6.2 + sha256: 4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/22/32/5a05303b0874458920b73f48b8779cc3a93d503f121b38dcc0456dbd698c/aiohttp-3.14.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: aiohttp - version: 3.13.3 - sha256: de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 + version: 3.14.0 + sha256: 1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -1648,16 +1702,17 @@ packages: - frozenlist>=1.1.1 - multidict>=4.5,<7.0 - propcache>=0.2.0 + - typing-extensions>=4.4 ; python_full_version < '3.13' - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - aiodns>=3.3.0 ; sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/68/03/8fa90a7e6d11ff20a18837a8e2b5dd23db01aabc475aa9271c8ad33299f5/aiohttp-3.13.3-cp310-cp310-macosx_10_9_x86_64.whl + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d0/d1/da280e23321c132c0a3fa7c8cc2830621d79174edc64c829443346489a36/aiohttp-3.14.0-cp310-cp310-macosx_11_0_arm64.whl name: aiohttp - version: 3.13.3 - sha256: 147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 + version: 3.14.0 + sha256: 02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -1666,16 +1721,17 @@ packages: - frozenlist>=1.1.1 - multidict>=4.5,<7.0 - propcache>=0.2.0 + - typing-extensions>=4.4 ; python_full_version < '3.13' - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - aiodns>=3.3.0 ; sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d2/23/b81f744d402510a8366b74eb420fc0cc1170d0c43daca12d10814df85f10/aiohttp-3.13.3-cp310-cp310-macosx_11_0_arm64.whl + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f6/54/444d37eebf0f15db661ca44ec7caf93962f3c5ca92eb4c9a5d888b70aaa2/aiohttp-3.14.0-cp310-cp310-macosx_10_9_x86_64.whl name: aiohttp - version: 3.13.3 - sha256: 859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 + version: 3.14.0 + sha256: 40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -1684,12 +1740,13 @@ packages: - frozenlist>=1.1.1 - multidict>=4.5,<7.0 - propcache>=0.2.0 + - typing-extensions>=4.4 ; python_full_version < '3.13' - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - aiodns>=3.3.0 ; sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl name: aioitertools version: 0.13.0 @@ -1717,17 +1774,16 @@ packages: requires_dist: - typing-extensions>=4.0.0 ; python_full_version < '3.9' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl name: anyio - version: 4.12.1 - sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c + version: 4.13.0 + sha256: 08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 requires_dist: - exceptiongroup>=1.0.2 ; python_full_version < '3.11' - idna>=2.8 - typing-extensions>=4.5 ; python_full_version < '3.13' - - trio>=0.32.0 ; python_full_version >= '3.10' and extra == 'trio' - - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' - requires_python: '>=3.9' + - trio>=0.32.0 ; extra == 'trio' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl name: argon2-cffi version: 25.1.0 @@ -1763,6 +1819,21 @@ packages: name: asn1crypto version: 1.5.1 sha256: db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 +- pypi: https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl + name: ast-serialize + version: 0.5.0 + sha256: bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: ast-serialize + version: 0.5.0 + sha256: b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl + name: ast-serialize + version: 0.5.0 + sha256: 0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/c7/80/9f608d13b4b3afcebd1dd13baf9551c95fc424d6390e4b1cfd7b1810cd06/async_property-0.2.2-py2.py3-none-any.whl name: async-property version: 0.2.2 @@ -1777,15 +1848,15 @@ packages: version: 7.0.0 sha256: 6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl name: attrs - version: 25.4.0 - sha256: adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 + version: 26.1.0 + sha256: c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b3/72/6102c002b1b4c04f8c5ed870f102f576a5fbd6a41cdb3e49ed339aa95dfe/bigtree-1.3.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/66/a2/31e6f5248053956b32093f0596b1d90dc0130db126d788c83eb37d51734e/bigtree-1.4.1-py3-none-any.whl name: bigtree - version: 1.3.1 - sha256: c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 + version: 1.4.1 + sha256: 78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 requires_dist: - lark ; extra == 'all' - matplotlib ; extra == 'all' @@ -1804,27 +1875,26 @@ packages: - rich ; extra == 'rich' - pyvis ; extra == 'vis' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/43/8b/b2361188bd1e293eede1bc165e2461d390394f71ec0c8c21211c8dabf62c/boto3-1.38.27-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b3/a0/3e6a0b1c1ea6bec76f71473727ef27abf3cd40e9709b3ebcbfbcfaae6f79/boto3-1.43.0-py3-none-any.whl name: boto3 - version: 1.38.27 - sha256: 95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 + version: 1.43.0 + sha256: 8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b requires_dist: - - botocore>=1.38.27,<1.39.0 + - botocore>=1.43.0,<1.44.0 - jmespath>=0.7.1,<2.0.0 - - s3transfer>=0.13.0,<0.14.0 + - s3transfer>=0.17.0,<0.18.0 - botocore[crt]>=1.21.0,<2.0a0 ; extra == 'crt' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a4/00/dd90b7a0255587ba1c9754d32a221adb4a9022f181df3eef401b0b9fadfc/botocore-1.38.46-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/4b/afc1fef8a43bafb139f57f73bbd70df82807af5934321e8112ae50668827/botocore-1.43.0-py3-none-any.whl name: botocore - version: 1.38.46 - sha256: 89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b + version: 1.43.0 + sha256: cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 requires_dist: - jmespath>=0.7.1,<2.0.0 - python-dateutil>=2.1,<3.0.0 - - urllib3>=1.25.4,<1.27 ; python_full_version < '3.10' - - urllib3>=1.25.4,!=2.2.0,<3 ; python_full_version >= '3.10' - - awscrt==0.23.8 ; extra == 'crt' - requires_python: '>=3.9' + - urllib3>=1.25.4,!=2.2.0,<3 + - awscrt==0.32.2 ; extra == 'crt' + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 md5: d2ffd7602c02f2b316fd921d39876885 @@ -1856,19 +1926,19 @@ packages: purls: [] size: 124834 timestamp: 1771350416561 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc - md5: 4492fd26db29495f0ba23f146cd5638d +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b + md5: 489b8e97e666c93f68fdb35c3c9b957f depends: - __unix license: ISC purls: [] - size: 147413 - timestamp: 1772006283803 -- pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + size: 129868 + timestamp: 1779289852439 +- pypi: https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl name: certifi - version: 2026.2.25 - sha256: 027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa + version: 2026.5.20 + sha256: 3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl name: cffi @@ -1891,30 +1961,30 @@ packages: requires_dist: - pycparser ; implementation_name != 'PyPy' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: charset-normalizer - version: 3.4.4 - sha256: e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d + version: 3.4.7 + sha256: cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl +- pypi: https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl name: charset-normalizer - version: 3.4.4 - sha256: da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd + version: 3.4.7 + sha256: cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: charset-normalizer - version: 3.4.4 - sha256: 9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 + version: 3.4.7 + sha256: bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl name: charset-normalizer - version: 3.4.4 - sha256: ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 + version: 3.4.7 + sha256: c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl name: click - version: 8.3.1 - sha256: 981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 + version: 8.4.1 + sha256: 482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 requires_dist: - colorama ; sys_platform == 'win32' requires_python: '>=3.10' @@ -1928,64 +1998,28 @@ packages: version: 0.4.6 sha256: 4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' -- pypi: https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl name: cryptography - version: 43.0.3 - sha256: 8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 + version: 48.0.0 + sha256: 2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c requires_dist: - - cffi>=1.12 ; platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; platform_python_implementation != 'PyPy' + - typing-extensions>=4.13.2 ; python_full_version < '3.11' - bcrypt>=3.1.5 ; extra == 'ssh' - - nox ; extra == 'nox' - - cryptography-vectors==43.0.3 ; extra == 'test' - - pytest>=6.2.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - - pretend ; extra == 'test' - - certifi ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' - - sphinx>=5.3.0 ; extra == 'docs' - - sphinx-rtd-theme>=1.1.1 ; extra == 'docs' - - pyenchant>=1.6.11 ; extra == 'docstest' - - readme-renderer ; extra == 'docstest' - - sphinxcontrib-spelling>=4.0.1 ; extra == 'docstest' - - build ; extra == 'sdist' - - ruff ; extra == 'pep8test' - - mypy ; extra == 'pep8test' - - check-sdist ; extra == 'pep8test' - - click ; extra == 'pep8test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl + requires_python: '>=3.9,!=3.9.0,!=3.9.1' +- pypi: https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl name: cryptography - version: 43.0.3 - sha256: c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 + version: 48.0.0 + sha256: 58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 requires_dist: - - cffi>=1.12 ; platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; platform_python_implementation != 'PyPy' + - typing-extensions>=4.13.2 ; python_full_version < '3.11' - bcrypt>=3.1.5 ; extra == 'ssh' - - nox ; extra == 'nox' - - cryptography-vectors==43.0.3 ; extra == 'test' - - pytest>=6.2.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - - pretend ; extra == 'test' - - certifi ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' - - sphinx>=5.3.0 ; extra == 'docs' - - sphinx-rtd-theme>=1.1.1 ; extra == 'docs' - - pyenchant>=1.6.11 ; extra == 'docstest' - - readme-renderer ; extra == 'docstest' - - sphinxcontrib-spelling>=4.0.1 ; extra == 'docstest' - - build ; extra == 'sdist' - - ruff ; extra == 'pep8test' - - mypy ; extra == 'pep8test' - - check-sdist ; extra == 'pep8test' - - click ; extra == 'pep8test' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/e5/23/d39ccc4ed76222db31530b0a7d38876fdb7673e23f838e8d8f0ed4651a4f/dask-2026.1.2-py3-none-any.whl + requires_python: '>=3.9,!=3.9.0,!=3.9.1' +- pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl name: dask - version: 2026.1.2 - sha256: 46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 + version: 2026.3.0 + sha256: be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d requires_dist: - click>=8.1 - cloudpickle>=3.0.0 @@ -1999,7 +2033,7 @@ packages: - dask[array] ; extra == 'dataframe' - pandas>=2.0 ; extra == 'dataframe' - pyarrow>=16.0 ; extra == 'dataframe' - - distributed>=2026.1.2,<2026.1.3 ; extra == 'distributed' + - distributed>=2026.3.0,<2026.3.1 ; extra == 'distributed' - bokeh>=3.1.0 ; extra == 'diagnostics' - jinja2>=2.10.3 ; extra == 'diagnostics' - dask[array,dataframe,diagnostics,distributed] ; extra == 'complete' @@ -2014,17 +2048,166 @@ packages: - pytest-xdist ; extra == 'test' - pre-commit ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/01/80/171c7c5b78e60ab25d6f11e3d38675fe7ef843ddc79a7fd26916d3a6ca05/db_dtypes-1.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/05/66/73034ad30b59f13439b75e620989dacba4c047256e358ba7c2e9ec98ea22/datasets-5.0.0-py3-none-any.whl + name: datasets + version: 5.0.0 + sha256: 7dd34927a0fd7046e98aad5cb9430e699c373238a15befa7b9bf22b991a7fee6 + requires_dist: + - filelock + - numpy>=1.17 + - pyarrow>=21.0.0 + - dill>=0.3.0,<0.4.2 + - pandas + - requests>=2.32.2 + - httpx<1.0.0 + - tqdm>=4.66.3 + - xxhash + - multiprocess<0.70.20 + - fsspec[http]>=2023.1.0,<=2026.4.0 + - huggingface-hub>=0.25.0,<2.0 + - packaging + - pyyaml>=5.1 + - torchcodec>=0.6.0 ; extra == 'audio' + - torch>=2.8.0 ; extra == 'audio' + - pillow>=9.4.0 ; extra == 'vision' + - trimesh>=4.10.0 ; extra == 'mesh' + - tensorflow>=2.6.0 ; extra == 'tensorflow' + - tensorflow>=2.6.0 ; extra == 'tensorflow-gpu' + - torch ; extra == 'torch' + - jax>=0.3.14 ; extra == 'jax' + - jaxlib>=0.3.14 ; extra == 'jax' + - numba>=0.56.4 ; python_full_version < '3.14' and extra == 'dev' + - absl-py ; extra == 'dev' + - decorator ; extra == 'dev' + - joblib<1.3.0 ; extra == 'dev' + - joblibspark ; python_full_version < '3.14' and extra == 'dev' + - pytest ; extra == 'dev' + - pytest-datadir ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - aiohttp ; extra == 'dev' + - elasticsearch>=7.17.12,<8.0.0 ; extra == 'dev' + - faiss-cpu>=1.8.0.post1 ; extra == 'dev' + - h5py ; extra == 'dev' + - pylance ; extra == 'dev' + - pyiceberg[pyarrow,sql-sqlite] ; extra == 'dev' + - jax>=0.3.14 ; sys_platform != 'win32' and extra == 'dev' + - jaxlib>=0.3.14 ; sys_platform != 'win32' and extra == 'dev' + - lz4 ; python_full_version < '3.14' and extra == 'dev' + - moto[server] ; extra == 'dev' + - pyspark>=3.4 ; extra == 'dev' + - py7zr ; extra == 'dev' + - rarfile>=4.0 ; extra == 'dev' + - sqlalchemy ; extra == 'dev' + - protobuf<4.0.0 ; extra == 'dev' + - tensorflow>=2.6.0 ; python_full_version < '3.10' and sys_platform != 'win32' and extra == 'dev' + - tensorflow>=2.16.0 ; python_full_version >= '3.10' and python_full_version < '3.14' and sys_platform != 'win32' and extra == 'dev' + - tiktoken ; extra == 'dev' + - torch>=2.8.0 ; extra == 'dev' + - torchdata ; extra == 'dev' + - transformers>=4.42.0 ; extra == 'dev' + - zstandard ; extra == 'dev' + - polars[timezone]>=0.20.0 ; extra == 'dev' + - pillow>=9.4.0 ; extra == 'dev' + - torchcodec>=0.7.0 ; python_full_version < '3.14' and extra == 'dev' + - nibabel>=5.3.1 ; extra == 'dev' + - trimesh>=4.10.0 ; extra == 'dev' + - teich==0.1.1a76 ; extra == 'dev' + - ruff>=0.3.0 ; extra == 'dev' + - transformers ; extra == 'dev' + - torch ; extra == 'dev' + - tensorflow>=2.6.0 ; extra == 'dev' + - numba>=0.56.4 ; python_full_version < '3.14' and extra == 'tests' + - absl-py ; extra == 'tests' + - decorator ; extra == 'tests' + - joblib<1.3.0 ; extra == 'tests' + - joblibspark ; python_full_version < '3.14' and extra == 'tests' + - pytest ; extra == 'tests' + - pytest-datadir ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - aiohttp ; extra == 'tests' + - elasticsearch>=7.17.12,<8.0.0 ; extra == 'tests' + - faiss-cpu>=1.8.0.post1 ; extra == 'tests' + - h5py ; extra == 'tests' + - pylance ; extra == 'tests' + - pyiceberg[pyarrow,sql-sqlite] ; extra == 'tests' + - jax>=0.3.14 ; sys_platform != 'win32' and extra == 'tests' + - jaxlib>=0.3.14 ; sys_platform != 'win32' and extra == 'tests' + - lz4 ; python_full_version < '3.14' and extra == 'tests' + - moto[server] ; extra == 'tests' + - pyspark>=3.4 ; extra == 'tests' + - py7zr ; extra == 'tests' + - rarfile>=4.0 ; extra == 'tests' + - sqlalchemy ; extra == 'tests' + - protobuf<4.0.0 ; extra == 'tests' + - tensorflow>=2.6.0 ; python_full_version < '3.10' and sys_platform != 'win32' and extra == 'tests' + - tensorflow>=2.16.0 ; python_full_version >= '3.10' and python_full_version < '3.14' and sys_platform != 'win32' and extra == 'tests' + - tiktoken ; extra == 'tests' + - torch>=2.8.0 ; extra == 'tests' + - torchdata ; extra == 'tests' + - transformers>=4.42.0 ; extra == 'tests' + - zstandard ; extra == 'tests' + - polars[timezone]>=0.20.0 ; extra == 'tests' + - pillow>=9.4.0 ; extra == 'tests' + - torchcodec>=0.7.0 ; python_full_version < '3.14' and extra == 'tests' + - nibabel>=5.3.1 ; extra == 'tests' + - trimesh>=4.10.0 ; extra == 'tests' + - teich==0.1.1a76 ; extra == 'tests' + - numba>=0.56.4 ; python_full_version < '3.14' and extra == 'tests-numpy2' + - absl-py ; extra == 'tests-numpy2' + - decorator ; extra == 'tests-numpy2' + - joblib<1.3.0 ; extra == 'tests-numpy2' + - joblibspark ; python_full_version < '3.14' and extra == 'tests-numpy2' + - pytest ; extra == 'tests-numpy2' + - pytest-datadir ; extra == 'tests-numpy2' + - pytest-xdist ; extra == 'tests-numpy2' + - aiohttp ; extra == 'tests-numpy2' + - elasticsearch>=7.17.12,<8.0.0 ; extra == 'tests-numpy2' + - h5py ; extra == 'tests-numpy2' + - pylance ; extra == 'tests-numpy2' + - pyiceberg[pyarrow,sql-sqlite] ; extra == 'tests-numpy2' + - jax>=0.3.14 ; sys_platform != 'win32' and extra == 'tests-numpy2' + - jaxlib>=0.3.14 ; sys_platform != 'win32' and extra == 'tests-numpy2' + - lz4 ; python_full_version < '3.14' and extra == 'tests-numpy2' + - moto[server] ; extra == 'tests-numpy2' + - pyspark>=3.4 ; extra == 'tests-numpy2' + - py7zr ; extra == 'tests-numpy2' + - rarfile>=4.0 ; extra == 'tests-numpy2' + - sqlalchemy ; extra == 'tests-numpy2' + - protobuf<4.0.0 ; extra == 'tests-numpy2' + - tiktoken ; extra == 'tests-numpy2' + - torch>=2.8.0 ; extra == 'tests-numpy2' + - torchdata ; extra == 'tests-numpy2' + - transformers>=4.42.0 ; extra == 'tests-numpy2' + - zstandard ; extra == 'tests-numpy2' + - polars[timezone]>=0.20.0 ; extra == 'tests-numpy2' + - pillow>=9.4.0 ; extra == 'tests-numpy2' + - torchcodec>=0.7.0 ; python_full_version < '3.14' and extra == 'tests-numpy2' + - nibabel>=5.3.1 ; extra == 'tests-numpy2' + - trimesh>=4.10.0 ; extra == 'tests-numpy2' + - teich==0.1.1a76 ; extra == 'tests-numpy2' + - ruff>=0.3.0 ; extra == 'quality' + - tensorflow==2.12.0 ; extra == 'benchmarks' + - torch==2.0.1 ; extra == 'benchmarks' + - transformers==4.30.1 ; extra == 'benchmarks' + - transformers ; extra == 'docs' + - torch ; extra == 'docs' + - tensorflow>=2.6.0 ; extra == 'docs' + - pdfplumber>=0.11.4 ; extra == 'pdfs' + - nibabel>=5.3.2 ; extra == 'nibabel' + - ipyniivue==2.4.2 ; extra == 'nibabel' + - pyiceberg>=0.7.0 ; extra == 'iceberg' + requires_python: '>=3.10.0' +- pypi: https://files.pythonhosted.org/packages/be/7a/797ed371bde520223e49dbbe0f8762fa4cc724d0e21fc6af944bb8f82150/db_dtypes-1.7.0-py3-none-any.whl name: db-dtypes - version: 1.5.0 - sha256: abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a + version: 1.7.0 + sha256: c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 requires_dist: - numpy>=1.24.0,<=2.2.6 ; python_full_version == '3.10.*' - numpy>=1.24.0 ; python_full_version != '3.10.*' - packaging>=24.2.0 - - pandas>=1.5.3,<3.0.0 + - pandas>=1.5.3,<4.0.0 - pyarrow>=13.0.0 - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/6e/24/e6b7a8fe8b9e336d684779a88027b261374417f2be7c5a0fcdb40f0c8cc5/deltalake-0.25.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: deltalake version: 0.25.5 @@ -2138,10 +2321,10 @@ packages: - paramiko>=2.4.3 ; extra == 'ssh' - websocket-client>=1.3.0 ; extra == 'websockets' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/4a/96/3a7630d2779d2bae6f3cdf540a088ed45166adefd3c429971e5b85ce8f84/duckdb-1.4.4-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/76/5c/bdb735011131c429cdb6d9e12e12fc8f1c8622158890d76a25819a58efc2/duckdb-1.5.3-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl name: duckdb - version: 1.4.4 - sha256: 5e1933fac5293fea5926b0ee75a55b8cfe7f516d867310a5b251831ab61fe62b + version: 1.5.3 + sha256: a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd requires_dist: - ipython ; extra == 'all' - fsspec ; extra == 'all' @@ -2149,11 +2332,11 @@ packages: - pandas ; extra == 'all' - pyarrow ; extra == 'all' - adbc-driver-manager ; extra == 'all' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/6b/7a/e9277d0567884c21f345ad43cc01aeaa2abe566d5fdf22e35c3861dd44fa/duckdb-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl + requires_python: '>=3.10.0' +- pypi: https://files.pythonhosted.org/packages/80/bd/ffc9e7a52731eec047dd49d45f029580dc8f3a6f8e8802a9e1c4138b0f8a/duckdb-1.5.3-cp310-cp310-macosx_11_0_arm64.whl name: duckdb - version: 1.4.4 - sha256: 49123b579e4a6323e65139210cd72dddc593a72d840211556b60f9703bda8526 + version: 1.5.3 + sha256: 50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 requires_dist: - ipython ; extra == 'all' - fsspec ; extra == 'all' @@ -2161,11 +2344,11 @@ packages: - pandas ; extra == 'all' - pyarrow ; extra == 'all' - adbc-driver-manager ; extra == 'all' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/a2/5f/23bd586ecb21273b41b5aa4b16fd88b7fecb53ed48d897273651c0c3d66f/duckdb-1.4.4-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + requires_python: '>=3.10.0' +- pypi: https://files.pythonhosted.org/packages/a0/ed/03ccf15147db7468f65891b5daa8489aa755d8cfcf75b24e7a4e4720e28c/duckdb-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl name: duckdb - version: 1.4.4 - sha256: 453b115f4777467f35103d8081770ac2f223fb5799178db5b06186e3ab51d1f2 + version: 1.5.3 + sha256: dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 requires_dist: - ipython ; extra == 'all' - fsspec ; extra == 'all' @@ -2173,7 +2356,7 @@ packages: - pandas ; extra == 'all' - pyarrow ; extra == 'all' - adbc-driver-manager ; extra == 'all' - requires_python: '>=3.9.0' + requires_python: '>=3.10.0' - pypi: https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl name: exceptiongroup version: 1.3.1 @@ -2192,17 +2375,18 @@ packages: - pytest ; extra == 'testing' - tox ; extra == 'testing' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e4/72/42e900510195b23a56bde950d26a51f8b723846bfcaa0286e90287f0422b/fastapi-0.135.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl name: fastapi - version: 0.135.1 - sha256: 46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e + version: 0.136.3 + sha256: 3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 requires_dist: - starlette>=0.46.0 - - pydantic>=2.7.0 + - pydantic>=2.9.0 - typing-extensions>=4.8.0 - typing-inspection>=0.4.2 - annotated-doc>=0.0.2 - fastapi-cli[standard]>=0.0.8 ; extra == 'standard' + - fastar>=0.9.0 ; extra == 'standard' - httpx>=0.23.0,<1.0.0 ; extra == 'standard' - jinja2>=3.1.5 ; extra == 'standard' - python-multipart>=0.0.18 ; extra == 'standard' @@ -2231,8 +2415,8 @@ packages: requires_python: '>=3.10' - pypi: ./ name: feast - version: 0.1.dev4414+gb54c2a2a3 - sha256: b245861d71391e9e14579d8128b91ccccce38bfa6510b11c09ea61a9806cb45b + version: 0.63.1.dev73+g8ef7bbb43.d20260609 + sha256: c4aa74a7fb1f093d840415413f0bf26a93aac6b5ad2eab94621a7f60a0f1f37b requires_dist: - click>=7.0.0,<9.0.0 - colorama>=0.3.9,<1 @@ -2243,7 +2427,8 @@ packages: - mmh3 - numpy>=2.0.0,<3 - pandas>=1.4.3,<3 - - pyarrow>=21.0.0 + - pyarrow>=21.0.0 ; extra != 'flink' + - pyarrow>=16.1.0,<21.0.0 ; extra == 'flink' - pydantic>=2.10.6 - pygments>=2.12.0,<3 - pyyaml>=5.4.0,<7 @@ -2255,18 +2440,18 @@ packages: - tqdm>=4,<5 - typeguard>=4.0.0 - fastapi>=0.68.0 + - starlette>=1.0.1 - uvicorn[standard]>=0.30.6,<=0.34.0 - uvicorn-worker - gunicorn ; sys_platform != 'win32' - dask[dataframe]>=2024.2.1 - - prometheus-client + - prometheus-client>=0.20.0,<0.25.0 - psutil - bigtree>=0.19.2 - pyjwt - - orjson>=3.9.0 - - boto3==1.38.27 ; extra == 'aws' - - fsspec<=2024.9.0 ; extra == 'aws' - - aiobotocore>2,<3 ; extra == 'aws' + - boto3>=1.38.27 ; extra == 'aws' + - fsspec>=2024.1.0 ; extra == 'aws' + - aiobotocore>=2 ; extra == 'aws' - azure-storage-blob>=0.37.0 ; extra == 'azure' - azure-identity>=1.6.1 ; extra == 'azure' - sqlalchemy>=1.4.19 ; extra == 'azure' @@ -2281,6 +2466,7 @@ packages: - ibis-framework[duckdb]>=10.0.0 ; extra == 'duckdb' - elasticsearch>=8.13.0 ; extra == 'elasticsearch' - faiss-cpu>=1.7.0,<=1.10.0 ; extra == 'faiss' + - apache-flink>=2.2.1,<3 ; extra == 'flink' - google-api-core>=1.23.0,<3 ; extra == 'gcp' - googleapis-common-protos>=1.52.0,<2 ; extra == 'gcp' - google-cloud-bigquery[pandas]>=2,<4 ; extra == 'gcp' @@ -2288,12 +2474,12 @@ packages: - google-cloud-datastore>=2.16.0,<3 ; extra == 'gcp' - google-cloud-storage>=1.34.0,<3 ; extra == 'gcp' - google-cloud-bigtable>=2.11.0,<3 ; extra == 'gcp' - - fsspec<=2024.9.0 ; extra == 'gcp' + - fsspec>=2024.1.0 ; extra == 'gcp' - great-expectations>=0.15.41,<1 ; extra == 'ge' - cffi>=1.15.0 ; extra == 'go' - - grpcio>=1.56.2,<=1.62.3 ; extra == 'grpcio' - - grpcio-reflection>=1.56.2,<=1.62.3 ; extra == 'grpcio' - - grpcio-health-checking>=1.56.2,<=1.62.3 ; extra == 'grpcio' + - grpcio>=1.56.2 ; extra == 'grpcio' + - grpcio-reflection>=1.56.2 ; extra == 'grpcio' + - grpcio-health-checking>=1.56.2 ; extra == 'grpcio' - hazelcast-python-client>=5.1 ; extra == 'hazelcast' - happybase>=1.2.0,<3 ; extra == 'hbase' - ibis-framework>=10.0.0 ; extra == 'ibis' @@ -2302,7 +2488,7 @@ packages: - timm>=0.6.0 ; extra == 'image' - pillow>=8.0.0 ; extra == 'image' - scikit-learn>=1.0.0 ; extra == 'image' - - pymilvus>2.5 ; extra == 'milvus' + - pymilvus>=2.5,<3 ; extra == 'milvus' - milvus-lite==2.4.12 ; extra == 'milvus' - feast[setuptools] ; extra == 'milvus' - pymongo>=4.13.0,<5.0.0 ; extra == 'mongodb' @@ -2317,21 +2503,24 @@ packages: - pyspark>=4.0.0 ; extra == 'spark' - trino>=0.305.0,<0.400.0 ; extra == 'trino' - regex ; extra == 'trino' - - psycopg[binary,pool]==3.2.5 ; extra == 'postgres' - - psycopg[c,pool]==3.2.5 ; extra == 'postgres-c' + - psycopg[binary,pool]>=3.2.5 ; extra == 'postgres' + - psycopg[c,pool]>=3.2.5 ; extra == 'postgres-c' - torch>=2.7.0 ; extra == 'pytorch' - torchvision>=0.22.1 ; extra == 'pytorch' - qdrant-client>=1.12.0 ; extra == 'qdrant' - transformers>=4.36.0 ; extra == 'rag' - datasets>=3.6.0 ; extra == 'rag' + - sentence-transformers>=3.0.0 ; extra == 'rag' - ray>=2.47.0 ; python_full_version == '3.10.*' and extra == 'ray' - codeflare-sdk>=0.31.1 ; python_full_version >= '3.11' and extra == 'ray' - - redis>=4.2.2,<5 ; extra == 'redis' - - hiredis>=2.0.0,<3 ; extra == 'redis' + - datasets>=3.6.0 ; extra == 'ray' + - redis>=4.2.2,<8 ; extra == 'redis' + - hiredis>=2.0.0,<4 ; extra == 'redis' - singlestoredb<1.8.0 ; extra == 'singlestore' - snowflake-connector-python[pandas]>=3.7,<5 ; extra == 'snowflake' - sqlite-vec==0.1.6 ; extra == 'sqlite-vec' - fastapi-mcp ; extra == 'mcp' + - mlflow>=2.10.0 ; extra == 'mlflow' - dbt-artifacts-parser ; extra == 'dbt' - pytest>=6.0.0,<8 ; extra == 'test' - pytest-xdist>=3.8.0 ; extra == 'test' @@ -2343,18 +2532,18 @@ packages: - pytest-benchmark>=3.4.1,<4 ; extra == 'test' - pytest-asyncio<=0.24.0 ; extra == 'test' - py>=1.11.0 ; extra == 'test' - - testcontainers==4.9.0 ; extra == 'test' + - testcontainers>=4.15.0rc2 ; extra == 'test' - minio==7.2.11 ; extra == 'test' - python-keycloak==4.2.2 ; extra == 'test' - - cryptography>=43.0,<44 ; extra == 'test' - - feast[aws,azure,cassandra,clickhouse,couchbase,delta,docling,duckdb,elasticsearch,faiss,gcp,ge,go,grpcio,hazelcast,hbase,ibis,image,k8s,mcp,milvus,mssql,mysql,openlineage,opentelemetry,oracle,postgres,pytorch,qdrant,rag,ray,redis,singlestore,snowflake,spark,sqlite-vec,test,trino] ; extra == 'ci' + - cryptography>=43.0 ; extra == 'test' + - feast[aws,azure,cassandra,clickhouse,couchbase,delta,docling,duckdb,elasticsearch,faiss,gcp,ge,go,grpcio,hazelcast,hbase,ibis,image,k8s,mcp,milvus,mlflow,mongodb,mssql,mysql,openlineage,opentelemetry,oracle,postgres,pytorch,qdrant,rag,ray,redis,singlestore,snowflake,spark,sqlite-vec,test,trino] ; extra == 'ci' - build ; extra == 'ci' - virtualenv==20.23.0 ; extra == 'ci' - dbt-artifacts-parser ; extra == 'ci' - ruff>=0.8.0 ; extra == 'ci' - mypy-protobuf>=3.1 ; extra == 'ci' - - grpcio-tools>=1.56.2,<=1.62.3 ; extra == 'ci' - - grpcio-testing>=1.56.2,<=1.62.3 ; extra == 'ci' + - grpcio-tools>=1.56.2 ; extra == 'ci' + - grpcio-testing>=1.56.2 ; extra == 'ci' - httpx==0.27.2 ; extra == 'ci' - mock==2.0.0 ; extra == 'ci' - moto<5 ; extra == 'ci' @@ -2399,11 +2588,10 @@ packages: - calver<2025.4.1 ; extra == 'minimal-sdist-build' - setuptools>=60,<81 ; extra == 'setuptools' requires_python: '>=3.10.0' - editable: true -- pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl name: filelock - version: 3.25.0 - sha256: 5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 + version: 3.29.1 + sha256: 85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/5d/ed/c7895fd2fde7f3ee70d248175f9b6cdf792fb741ab92dc59cd9ef3bd241b/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: frozenlist @@ -2420,118 +2608,10 @@ packages: version: 1.8.0 sha256: ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1d/a0/6aaea0c2fbea2f89bfd5db25fb1e3481896a423002ebe4e55288907a97a3/fsspec-2024.9.0-py3-none-any.whl - name: fsspec - version: 2024.9.0 - sha256: a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b - requires_dist: - - adlfs ; extra == 'abfs' - - adlfs ; extra == 'adl' - - pyarrow>=1 ; extra == 'arrow' - - dask ; extra == 'dask' - - distributed ; extra == 'dask' - - pre-commit ; extra == 'dev' - - ruff ; extra == 'dev' - - numpydoc ; extra == 'doc' - - sphinx ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - yarl ; extra == 'doc' - - dropbox ; extra == 'dropbox' - - dropboxdrivefs ; extra == 'dropbox' - - requests ; extra == 'dropbox' - - adlfs ; extra == 'full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' - - dask ; extra == 'full' - - distributed ; extra == 'full' - - dropbox ; extra == 'full' - - dropboxdrivefs ; extra == 'full' - - fusepy ; extra == 'full' - - gcsfs ; extra == 'full' - - libarchive-c ; extra == 'full' - - ocifs ; extra == 'full' - - panel ; extra == 'full' - - paramiko ; extra == 'full' - - pyarrow>=1 ; extra == 'full' - - pygit2 ; extra == 'full' - - requests ; extra == 'full' - - s3fs ; extra == 'full' - - smbprotocol ; extra == 'full' - - tqdm ; extra == 'full' - - fusepy ; extra == 'fuse' - - gcsfs ; extra == 'gcs' - - pygit2 ; extra == 'git' - - requests ; extra == 'github' - - gcsfs ; extra == 'gs' - - panel ; extra == 'gui' - - pyarrow>=1 ; extra == 'hdfs' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' - - libarchive-c ; extra == 'libarchive' - - ocifs ; extra == 'oci' - - s3fs ; extra == 's3' - - paramiko ; extra == 'sftp' - - smbprotocol ; extra == 'smb' - - paramiko ; extra == 'ssh' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' - - numpy ; extra == 'test' - - pytest ; extra == 'test' - - pytest-asyncio!=0.22.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-recording ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - requests ; extra == 'test' - - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' - - dask-expr ; extra == 'test-downstream' - - dask[dataframe,test] ; extra == 'test-downstream' - - moto[server]>4,<5 ; extra == 'test-downstream' - - pytest-timeout ; extra == 'test-downstream' - - xarray ; extra == 'test-downstream' - - adlfs ; extra == 'test-full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' - - cloudpickle ; extra == 'test-full' - - dask ; extra == 'test-full' - - distributed ; extra == 'test-full' - - dropbox ; extra == 'test-full' - - dropboxdrivefs ; extra == 'test-full' - - fastparquet ; extra == 'test-full' - - fusepy ; extra == 'test-full' - - gcsfs ; extra == 'test-full' - - jinja2 ; extra == 'test-full' - - kerchunk ; extra == 'test-full' - - libarchive-c ; extra == 'test-full' - - lz4 ; extra == 'test-full' - - notebook ; extra == 'test-full' - - numpy ; extra == 'test-full' - - ocifs ; extra == 'test-full' - - pandas ; extra == 'test-full' - - panel ; extra == 'test-full' - - paramiko ; extra == 'test-full' - - pyarrow ; extra == 'test-full' - - pyarrow>=1 ; extra == 'test-full' - - pyftpdlib ; extra == 'test-full' - - pygit2 ; extra == 'test-full' - - pytest ; extra == 'test-full' - - pytest-asyncio!=0.22.0 ; extra == 'test-full' - - pytest-benchmark ; extra == 'test-full' - - pytest-cov ; extra == 'test-full' - - pytest-mock ; extra == 'test-full' - - pytest-recording ; extra == 'test-full' - - pytest-rerunfailures ; extra == 'test-full' - - python-snappy ; extra == 'test-full' - - requests ; extra == 'test-full' - - smbprotocol ; extra == 'test-full' - - tqdm ; extra == 'test-full' - - urllib3 ; extra == 'test-full' - - zarr ; extra == 'test-full' - - zstandard ; extra == 'test-full' - - tqdm ; extra == 'tqdm' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl name: fsspec - version: 2026.2.0 - sha256: 98de475b5cb3bd66bedd5c4679e87b4fdfe1a3bf4d707b151b3c07e58c9a2437 + version: 2026.4.0 + sha256: 11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 requires_dist: - adlfs ; extra == 'abfs' - adlfs ; extra == 'adl' @@ -2636,35 +2716,35 @@ packages: - zstandard ; python_full_version < '3.14' and extra == 'test-full' - tqdm ; extra == 'tqdm' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/45/27/09c33d67f7e0dcf06d7ac17d196594e66989299374bfb0d4331d1038e76b/google_api_core-2.30.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl name: google-api-core - version: 2.30.0 - sha256: 80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 + version: 2.31.0 + sha256: ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab requires_dist: - - googleapis-common-protos>=1.56.3,<2.0.0 - - protobuf>=4.25.8,<7.0.0 - - proto-plus>=1.22.3,<2.0.0 + - googleapis-common-protos>=1.63.2,<2.0.0 + - protobuf>=5.29.6,<8.0.0 + - proto-plus>=1.24.0,<2.0.0 - proto-plus>=1.25.0,<2.0.0 ; python_full_version >= '3.13' - google-auth>=2.14.1,<3.0.0 - - requests>=2.20.0,<3.0.0 - - google-auth[aiohttp]>=2.35.0,<3.0.0 ; extra == 'async-rest' - - grpcio>=1.33.2,<2.0.0 ; extra == 'grpc' + - requests>=2.33.0,<3.0.0 + - google-auth[aiohttp]>=2.14.1,<3.0.0 ; extra == 'async-rest' + - aiohttp>=3.13.4 ; extra == 'async-rest' + - grpcio>=1.41.0,<2.0.0 ; extra == 'grpc' - grpcio>=1.49.1,<2.0.0 ; python_full_version >= '3.11' and extra == 'grpc' - grpcio>=1.75.1,<2.0.0 ; python_full_version >= '3.14' and extra == 'grpc' - - grpcio-status>=1.33.2,<2.0.0 ; extra == 'grpc' + - grpcio-status>=1.41.0,<2.0.0 ; extra == 'grpc' - grpcio-status>=1.49.1,<2.0.0 ; python_full_version >= '3.11' and extra == 'grpc' - grpcio-status>=1.75.1,<2.0.0 ; python_full_version >= '3.14' and extra == 'grpc' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/83/1d/d6466de3a5249d35e832a52834115ca9d1d0de6abc22065f049707516d47/google_auth-2.48.0-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/4a/c9/db44165ba7c581268c6d46017ef63339110378305062830104fc7fa144cb/google_auth-2.53.0-py3-none-any.whl name: google-auth - version: 2.48.0 - sha256: 2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f + version: 2.53.0 + sha256: 6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 requires_dist: - pyasn1-modules>=0.2.1 - cryptography>=38.0.3 - - rsa>=3.1.4,<5 - cryptography>=38.0.3 ; extra == 'cryptography' - - aiohttp>=3.6.2,<4.0.0 ; extra == 'aiohttp' + - aiohttp>=3.8.0,<4.0.0 ; extra == 'aiohttp' - requests>=2.20.0,<3.0.0 ; extra == 'aiohttp' - pyopenssl ; extra == 'enterprise-cert' - pyopenssl>=20.0.0 ; extra == 'pyopenssl' @@ -2674,7 +2754,6 @@ packages: - grpcio ; extra == 'testing' - flask ; extra == 'testing' - freezegun ; extra == 'testing' - - oauth2client ; extra == 'testing' - pyjwt>=2.0 ; extra == 'testing' - pytest ; extra == 'testing' - pytest-cov ; extra == 'testing' @@ -2684,7 +2763,7 @@ packages: - responses ; extra == 'testing' - urllib3 ; extra == 'testing' - packaging ; extra == 'testing' - - aiohttp>=3.6.2,<4.0.0 ; extra == 'testing' + - aiohttp>=3.8.0,<4.0.0 ; extra == 'testing' - requests>=2.20.0,<3.0.0 ; extra == 'testing' - aioresponses ; extra == 'testing' - pytest-asyncio ; extra == 'testing' @@ -2692,20 +2771,21 @@ packages: - aiohttp<3.10.0 ; extra == 'testing' - urllib3 ; extra == 'urllib3' - packaging ; extra == 'urllib3' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/2f/56/909fd5632226d3fba31d7aeffd4754410735d49362f5809956fe3e9af344/google_auth_oauthlib-1.3.0-py3-none-any.whl + - rsa>=3.1.4,<5 ; extra == 'rsa' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/37/d3/d7dff0d58a9e9244b48044bfb6a898bfcc8ecc42e0031d1bebc695344725/google_auth_oauthlib-1.4.0-py3-none-any.whl name: google-auth-oauthlib - version: 1.3.0 - sha256: 386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 + version: 1.4.0 + sha256: 251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 requires_dist: - google-auth>=2.15.0,!=2.43.0,!=2.44.0,!=2.45.0,<3.0.0 - requests-oauthlib>=0.7.0 - click>=6.0.0 ; extra == 'tool' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/7c/f5/081cf5b90adfe524ae0d671781b0d497a75a0f2601d075af518828e22d8f/google_cloud_bigquery-3.40.1-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/40/33/1d3902efadef9194566d499d61507e1f038454e0b55499d2d7f8ab2a4fee/google_cloud_bigquery-3.41.0-py3-none-any.whl name: google-cloud-bigquery - version: 3.40.1 - sha256: 9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 + version: 3.41.0 + sha256: 2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa requires_dist: - google-api-core[grpc]>=2.11.1,<3.0.0 - google-auth>=2.14.1,<3.0.0 @@ -2741,67 +2821,65 @@ packages: - proto-plus>=1.22.3,<2.0.0 ; extra == 'bigquery-v2' - protobuf>=3.20.2,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 ; extra == 'bigquery-v2' - google-cloud-bigquery[bigquery-v2,bqstorage,geopandas,ipython,ipywidgets,matplotlib,opentelemetry,pandas,tqdm] ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1f/07/62dbe78ef773569be0a1d2c1b845e9214889b404e506126519b4d33ee999/google_cloud_bigquery_storage-2.36.2-py3-none-any.whl + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/eb/f6/4157466c10181907d07786fb41df5d0a9ff339c1770b9e2a15cfe483e845/google_cloud_bigquery_storage-2.39.0-py3-none-any.whl name: google-cloud-bigquery-storage - version: 2.36.2 - sha256: 823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf + version: 2.39.0 + sha256: 8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 requires_dist: - - google-api-core[grpc]>=1.34.1,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,<3.0.0 + - google-api-core[grpc]>=2.17.1,<3.0.0 - google-auth>=2.14.1,!=2.24.0,!=2.25.0,<3.0.0 - - grpcio>=1.33.2,<2.0.0 + - grpcio>=1.59.0,<2.0.0 - grpcio>=1.75.1,<2.0.0 ; python_full_version >= '3.14' - proto-plus>=1.22.3,<2.0.0 - proto-plus>=1.25.0,<2.0.0 ; python_full_version >= '3.13' - - protobuf>=3.20.2,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 - - pandas>=0.21.1 ; extra == 'pandas' - - importlib-metadata>=1.0.0 ; python_full_version < '3.8' and extra == 'pandas' - - fastavro>=0.21.2 ; extra == 'fastavro' - - pyarrow>=0.15.0 ; extra == 'pyarrow' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/62/69/03eed134d71f6117ffd9efac2d1033bb2fa2522e9e82545a0828061d32f4/google_cloud_bigtable-2.35.0-py3-none-any.whl + - protobuf>=4.25.8,<8.0.0 + - pandas>=1.1.3 ; extra == 'pandas' + - fastavro>=1.1.0 ; extra == 'fastavro' + - pyarrow>=3.0.0 ; extra == 'pyarrow' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/46/9d/9c0a81aa9cf6c058b02d3be194d70bcd7e4bd82f631c8110560c3908dbc4/google_cloud_bigtable-2.38.0-py3-none-any.whl name: google-cloud-bigtable - version: 2.35.0 - sha256: f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 + version: 2.38.0 + sha256: 9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 requires_dist: - - google-api-core[grpc]>=2.17.0,<3.0.0 - - google-cloud-core>=1.4.4,<3.0.0 - - google-auth>=2.23.0,!=2.24.0,!=2.25.0,<3.0.0 - - grpc-google-iam-v1>=0.12.4,<1.0.0 + - google-api-core[grpc]>=2.11.0,<3.0.0 + - google-auth>=2.14.1,!=2.24.0,!=2.25.0,<3.0.0 + - grpcio>=1.33.2,<2.0.0 + - grpcio>=1.75.1,<2.0.0 ; python_full_version >= '3.14' - proto-plus>=1.22.3,<2.0.0 - proto-plus>=1.25.0,<2.0.0 ; python_full_version >= '3.13' - - protobuf>=3.20.2,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 + - protobuf>=4.25.8,<8.0.0 + - google-cloud-core>=1.4.4,<3.0.0 + - grpc-google-iam-v1>=0.12.4,<1.0.0 - google-crc32c>=1.5.0,<2.0.0.dev0 - libcst>=0.2.5 ; extra == 'libcst' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/89/20/bfa472e327c8edee00f04beecc80baeddd2ab33ee0e86fd7654da49d45e9/google_cloud_core-2.5.0-py3-none-any.whl + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl name: google-cloud-core - version: 2.5.0 - sha256: 67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc + version: 2.6.0 + sha256: 6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e requires_dist: - - google-api-core>=1.31.6,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0 - - google-auth>=1.25.0,<3.0.0 - - importlib-metadata>1.0.0 ; python_full_version < '3.8' - - grpcio>=1.38.0,<2.0.0 ; python_full_version < '3.14' and extra == 'grpc' + - google-api-core>=2.11.0,<3.0.0 + - google-auth>=2.14.1,!=2.24.0,!=2.25.0,<3.0.0 + - grpcio>=1.47.0,<2.0.0 ; python_full_version < '3.14' and extra == 'grpc' - grpcio>=1.75.1,<2.0.0 ; python_full_version >= '3.14' and extra == 'grpc' - - grpcio-status>=1.38.0,<2.0.0 ; extra == 'grpc' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/b7/88/348c09570a03886356c02337f06d69532fa17a66ad2a9dff584f7b60eb04/google_cloud_datastore-2.23.0-py3-none-any.whl + - grpcio-status>=1.47.0,<2.0.0 ; extra == 'grpc' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/95/b2/fd5a3e55a5f698fd527f783ce27368e8e9c3d872bd1e1c39dd377b2b9f14/google_cloud_datastore-2.25.0-py3-none-any.whl name: google-cloud-datastore - version: 2.23.0 - sha256: 24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f + version: 2.25.0 + sha256: e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb requires_dist: - - google-api-core[grpc]>=1.34.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,<3.0.0 + - google-api-core[grpc]>=2.17.1,<3.0.0 - google-auth>=2.14.1,!=2.24.0,!=2.25.0,<3.0.0 - - google-cloud-core>=1.4.0,<3.0.0 - - proto-plus>=1.22.0,<2.0.0 - - proto-plus>=1.22.2,<2.0.0 ; python_full_version >= '3.11' - - proto-plus>=1.25.0,<2.0.0 ; python_full_version >= '3.13' - - protobuf!=3.20.0,!=3.20.1,>=3.20.2,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 - - grpcio>=1.38.0,<2.0.0 + - google-cloud-core>=2.0.0,<3.0.0 + - grpcio>=1.59.0,<2.0.0 - grpcio>=1.75.1,<2.0.0 ; python_full_version >= '3.14' - - libcst>=0.2.5 ; extra == 'libcst' - requires_python: '>=3.7' + - proto-plus>=1.22.3,<2.0.0 + - proto-plus>=1.25.0,<2.0.0 ; python_full_version >= '3.13' + - protobuf>=4.25.8,<8.0.0 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl name: google-cloud-storage version: 2.19.0 @@ -2831,28 +2909,28 @@ packages: version: 1.8.0 sha256: 119fcd90c57c89f30040b47c211acee231b25a45d225e3225294386f5d258288 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1f/0b/93afde9cfe012260e9fe1522f35c9b72d6ee222f316586b1f23ecf44d518/google_resumable_media-2.8.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl name: google-resumable-media - version: 2.8.0 - sha256: dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 + version: 2.10.0 + sha256: 88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c requires_dist: - google-crc32c>=1.0.0,<2.0.0 - requests>=2.18.0,<3.0.0 ; extra == 'requests' - aiohttp>=3.6.2,<4.0.0 ; extra == 'aiohttp' - google-auth>=1.22.0,<2.0.0 ; extra == 'aiohttp' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl name: googleapis-common-protos - version: 1.72.0 - sha256: 4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038 + version: 1.75.0 + sha256: 961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed requires_dist: - - protobuf>=3.20.2,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 + - protobuf>=4.25.8,<8.0.0 - grpcio>=1.44.0,<2.0.0 ; extra == 'grpc' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1d/21/117c8710abb7f146d804a124c07eb5964a60b90d02b72452885aecc18efa/greenlet-3.5.1-cp310-cp310-macosx_11_0_universal2.whl name: greenlet - version: 3.3.2 - sha256: 9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d + version: 3.5.1 + sha256: 7eacb17a9d41538a2bc4912eba5ef13823c83cb69e4d141d0813debe7163187f requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -2860,10 +2938,10 @@ packages: - psutil ; extra == 'test' - setuptools ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/3f/ae/8bffcbd373b57a5992cd077cbe8858fff39110480a9d50697091faea6f39/greenlet-3.3.2-cp314-cp314-macosx_11_0_universal2.whl +- pypi: https://files.pythonhosted.org/packages/77/96/4efd6fa5c62c85426a0c19077a586258ebc3a2a146ff2493e4312a697a22/greenlet-3.5.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl name: greenlet - version: 3.3.2 - sha256: 8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab + version: 3.5.1 + sha256: 2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -2871,10 +2949,10 @@ packages: - psutil ; extra == 'test' - setuptools ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/89/b8/8b83d18ae07c46c019617f35afd7b47aab7f9b4fbb12fc637d681e10bdd8/greenlet-3.5.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl name: greenlet - version: 3.3.2 - sha256: ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f + version: 3.5.1 + sha256: 540dae7b956209af4d70a3be35927b4055f617763771e5e84a5255bea934d2f5 requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -2882,10 +2960,10 @@ packages: - psutil ; extra == 'test' - setuptools ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/d2/d8/09bfa816572a4d83bccd6750df1926f79158b1c36c5f73786e26dbe4ee38/greenlet-3.3.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/8a/cb/c62454606daf5640369c94d8a9dd540599b1bfc090e2d2180cb77f4038d2/greenlet-3.5.1-cp314-cp314-macosx_11_0_universal2.whl name: greenlet - version: 3.3.2 - sha256: 63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506 + version: 3.5.1 + sha256: d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07 requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -2893,74 +2971,76 @@ packages: - psutil ; extra == 'test' - setuptools ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/4a/bd/330a1bbdb1afe0b96311249e699b6dc9cfc17916394fd4503ac5aca2514b/grpc_google_iam_v1-0.14.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl name: grpc-google-iam-v1 - version: 0.14.3 - sha256: 7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 + version: 0.14.4 + sha256: 412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 requires_dist: - grpcio>=1.44.0,<2.0.0 - - googleapis-common-protos[grpc]>=1.56.0,<2.0.0 - - protobuf>=3.20.2,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/58/2f/f3fc773270cf17e7ca076c1f6435278f58641d475a25cdeea5b2d8d4845b/grpcio-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - googleapis-common-protos[grpc]>=1.63.2,<2.0.0 + - protobuf>=4.25.8,<8.0.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9a/df/ec0a4e04472df2618f8741151fa026bc877648e952ebb0e421169e0b992b/grpcio-1.81.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: grpcio - version: 1.62.3 - sha256: 807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 + version: 1.81.0 + sha256: f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 requires_dist: - - grpcio-tools>=1.62.3 ; extra == 'protobuf' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/c5/63/ee244c4b64f0e71cef5314f9fa1d120c072e33c2e4c545dc75bd1af2a5c5/grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl + - typing-extensions~=4.12 + - grpcio-tools>=1.81.0 ; extra == 'protobuf' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/da/8a/439070efa430b3c51c8e319b67521957688905f27b294302c6077e9d4ef5/grpcio-1.81.0-cp310-cp310-macosx_11_0_universal2.whl name: grpcio - version: 1.62.3 - sha256: f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a + version: 1.81.0 + sha256: b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 requires_dist: - - grpcio-tools>=1.62.3 ; extra == 'protobuf' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/40/4c/ee3173906196b741ac6ba55a9788ba9ebf2cd05f91715a49b6c3bfbb9d73/grpcio_health_checking-1.62.3-py3-none-any.whl + - typing-extensions~=4.12 + - grpcio-tools>=1.81.0 ; extra == 'protobuf' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/90/ea/ba9cd33a1bed529b7bd5986dd07ef604556220ea6e1289c7fed862db2393/grpcio_health_checking-1.81.0-py3-none-any.whl name: grpcio-health-checking - version: 1.62.3 - sha256: f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d + version: 1.81.0 + sha256: 1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f requires_dist: - - protobuf>=4.21.6 - - grpcio>=1.62.3 - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/82/54/acc6a6e684827b0f6bb4e2c27f3d7e25b71322c4078ef5b455c07c43260e/grpcio_reflection-1.62.3-py3-none-any.whl + - protobuf>=6.33.5,<7.0.0 + - grpcio>=1.81.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d5/61/e472357ff5484f67c802568e70b3182df3d8eb1d0c2de38199d9a9a28bb2/grpcio_reflection-1.81.0-py3-none-any.whl name: grpcio-reflection - version: 1.62.3 - sha256: a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c + version: 1.81.0 + sha256: 85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 requires_dist: - - protobuf>=4.21.6 - - grpcio>=1.62.3 - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl + - protobuf>=6.33.5,<7.0.0 + - grpcio>=1.81.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f3/b7/5aa346bf1cdecd4ed64b86c10a4d5a089ce3da89145f8328caf0b22b240d/grpcio_status-1.81.0-py3-none-any.whl name: grpcio-status - version: 1.62.3 - sha256: f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 + version: 1.81.0 + sha256: 10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab requires_dist: - - protobuf>=4.21.6 - - grpcio>=1.62.3 + - protobuf>=6.33.5,<8.0.0 + - grpcio>=1.81.0 - googleapis-common-protos>=1.5.5 - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/10/69/cc76b0ef3248cb5f8389fabb9d69e23c597664e5f7f40861e3ebb04bd46b/grpcio_testing-1.81.0-py3-none-any.whl name: grpcio-testing - version: 1.62.3 - sha256: 06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb + version: 1.81.0 + sha256: f754ea3efd110127920513f0177f31b5c9bcbdc7e4af9ac568d8b3a5684df3c6 requires_dist: - - protobuf>=4.21.6 - - grpcio>=1.62.3 -- pypi: https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl + - protobuf>=6.33.5,<7.0.0 + - grpcio>=1.81.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e6/40/9c2384fc2be4ad25dd4a49decd5ad9ea5a3639814c11bd40ab77cb9f0a14/gunicorn-26.0.0-py3-none-any.whl name: gunicorn - version: 25.1.0 - sha256: d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b + version: 26.0.0 + sha256: 40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc requires_dist: - packaging - gevent>=24.10.1 ; extra == 'gevent' - - eventlet>=0.40.3 ; extra == 'eventlet' - tornado>=6.5.0 ; extra == 'tornado' - setproctitle ; extra == 'setproctitle' - h2>=4.1.0 ; extra == 'http2' + - gunicorn-h1c>=0.6.5 ; extra == 'fast' - gevent>=24.10.1 ; extra == 'testing' - - eventlet>=0.40.3 ; extra == 'testing' - h2>=4.1.0 ; extra == 'testing' - coverage ; extra == 'testing' - pytest ; extra == 'testing' @@ -2974,20 +3054,41 @@ packages: version: 0.16.0 sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/42/6e/8adaefff7e3e216b0f7bd6cafce6d5d06798f31c3e2852dc3db6a7d758c9/hiredis-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/3d/fb/69ff198a82cae7eb1a69fb84d93b3a3e4816564d76817fe541ddc96874eb/hf_xet-1.5.0-cp37-abi3-macosx_10_12_x86_64.whl + name: hf-xet + version: 1.5.0 + sha256: dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56 + requires_dist: + - pytest ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/49/4d/103f76b04310e5e57656696cc184690d20c466af0bca3ca88f8c8ea5d4f3/hf_xet-1.5.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: hf-xet + version: 1.5.0 + sha256: 3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949 + requires_dist: + - pytest ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/9b/ff/edcc2b40162bef3ff78e14ab637e5f3b89243d6aee72f5949d3bb6a5af83/hf_xet-1.5.0-cp37-abi3-macosx_11_0_arm64.whl + name: hf-xet + version: 1.5.0 + sha256: fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a + requires_dist: + - pytest ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/26/c9/4e9cd249afc101ac283943295fe3359bdd711a0bb8c667752eb0da80609d/hiredis-3.4.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: hiredis - version: 2.4.0 - sha256: 87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 + version: 3.4.0 + sha256: 4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d8/70/3f39ebfb3824578c34400df3b037b268abb5af0abaa789b430ffd17dd74e/hiredis-2.4.0-cp310-cp310-macosx_10_15_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/6f/75/2a08a6062228720747570a07ab42e6f5826725f09c9a95d75b7b5b938022/hiredis-3.4.0-cp310-cp310-macosx_10_15_x86_64.whl name: hiredis - version: 2.4.0 - sha256: 76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 + version: 3.4.0 + sha256: 4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ed/b7/26a56a3b991abe7fcf7bcfa8e0a08de3c3766c6caecb1ba46239342792ff/hiredis-2.4.0-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/e0/3d/28c61f9c628dfaf1f96bb8b8592cb006eaad3747248c95f9ae7f694abb47/hiredis-3.4.0-cp310-cp310-macosx_11_0_arm64.whl name: hiredis - version: 2.4.0 - sha256: b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 + version: 3.4.0 + sha256: 98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl name: httpcore @@ -3001,35 +3102,35 @@ packages: - socksio==1.* ; extra == 'socks' - trio>=0.22.0,<1.0 ; extra == 'trio' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/1a/12/fa3fbf5f9517b273edea2dc982aa82a8c634091e67c590792b729017bc6f/httptools-0.8.0-cp314-cp314-macosx_10_13_universal2.whl name: httptools - version: 0.7.1 - sha256: 7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 + version: 0.8.0 + sha256: de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl +- pypi: https://files.pythonhosted.org/packages/30/fc/5e7c4cb443370f2090a3aba0453a07384d29ff66b7435bb90e77e1037599/httptools-0.8.0-cp314-cp314-macosx_11_0_arm64.whl name: httptools - version: 0.7.1 - sha256: c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 + version: 0.8.0 + sha256: 159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7e/4f/35e3a63f863a659f92ffd92bef131f3e81cf849af26e6435b49bd9f6f751/httptools-0.7.1-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl name: httptools - version: 0.7.1 - sha256: 84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 + version: 0.8.0 + sha256: bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl name: httptools - version: 0.7.1 - sha256: 0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 + version: 0.8.0 + sha256: da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c7/e5/c07e0bcf4ec8db8164e9f6738c048b2e66aabf30e7506f440c4cc6953f60/httptools-0.7.1-cp310-cp310-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/ba/53/771bd891eb0f236f32145d6a1775777ec85745f3cc983a1f23d1a3b8ddfe/httptools-0.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: httptools - version: 0.7.1 - sha256: 11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 + version: 0.8.0 + sha256: c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f5/71/b0a9193641d9e2471ac541d3b1b869538a5fb6419d52fd2669fa9c79e4b8/httptools-0.7.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: httptools - version: 0.7.1 - sha256: c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 + version: 0.8.0 + sha256: a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl name: httpx @@ -3049,6 +3150,125 @@ packages: - socksio==1.* ; extra == 'socks' - zstandard>=0.18.0 ; extra == 'zstd' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/0b/03/40a05316cb6616e5b7efd7773656441ab04b4b022c2199e79bb4622a92a3/huggingface_hub-1.18.0-py3-none-any.whl + name: huggingface-hub + version: 1.18.0 + sha256: 729be4a976fb706dcc02d176bcda8a3f32bdf21a294e8f4b3dda6fbcbc9c1ab1 + requires_dist: + - click>=8.4.0 + - filelock>=3.10.0 + - fsspec>=2023.5.0 + - hf-xet>=1.4.3,<2.0.0 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64' + - httpx>=0.23.0,<1 + - packaging>=20.9 + - pyyaml>=5.1 + - tqdm>=4.42.1 + - typer>=0.20.0,<0.26.0 + - typing-extensions>=4.1.0 + - authlib>=1.3.2 ; extra == 'oauth' + - fastapi ; extra == 'oauth' + - httpx ; extra == 'oauth' + - itsdangerous ; extra == 'oauth' + - torch ; extra == 'torch' + - safetensors[torch] ; extra == 'torch' + - toml ; extra == 'fastai' + - fastai>=2.4 ; extra == 'fastai' + - fastcore>=1.3.27 ; extra == 'fastai' + - hf-xet>=1.4.3,<2.0.0 ; extra == 'hf-xet' + - mcp>=1.8.0 ; extra == 'mcp' + - authlib>=1.3.2 ; extra == 'testing' + - fastapi ; extra == 'testing' + - httpx ; extra == 'testing' + - itsdangerous ; extra == 'testing' + - jedi ; extra == 'testing' + - jinja2 ; extra == 'testing' + - pytest>=8.4.2 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-env ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - pytest-vcr ; extra == 'testing' + - pytest-asyncio ; extra == 'testing' + - pytest-rerunfailures<16.0 ; extra == 'testing' + - pytest-mock ; extra == 'testing' + - urllib3<2.0 ; extra == 'testing' + - soundfile ; extra == 'testing' + - pillow ; extra == 'testing' + - numpy ; extra == 'testing' + - duckdb ; extra == 'testing' + - fastapi ; extra == 'testing' + - gradio>=5.0.0 ; extra == 'gradio' + - requests ; extra == 'gradio' + - typing-extensions>=4.8.0 ; extra == 'typing' + - types-pyyaml ; extra == 'typing' + - types-simplejson ; extra == 'typing' + - types-toml ; extra == 'typing' + - types-tqdm ; extra == 'typing' + - types-urllib3 ; extra == 'typing' + - ruff>=0.9.0 ; extra == 'quality' + - mypy==1.15.0 ; extra == 'quality' + - libcst>=1.4.0 ; extra == 'quality' + - ty ; extra == 'quality' + - authlib>=1.3.2 ; extra == 'all' + - fastapi ; extra == 'all' + - httpx ; extra == 'all' + - itsdangerous ; extra == 'all' + - jedi ; extra == 'all' + - jinja2 ; extra == 'all' + - pytest>=8.4.2 ; extra == 'all' + - pytest-cov ; extra == 'all' + - pytest-env ; extra == 'all' + - pytest-xdist ; extra == 'all' + - pytest-vcr ; extra == 'all' + - pytest-asyncio ; extra == 'all' + - pytest-rerunfailures<16.0 ; extra == 'all' + - pytest-mock ; extra == 'all' + - urllib3<2.0 ; extra == 'all' + - soundfile ; extra == 'all' + - pillow ; extra == 'all' + - numpy ; extra == 'all' + - duckdb ; extra == 'all' + - fastapi ; extra == 'all' + - ruff>=0.9.0 ; extra == 'all' + - mypy==1.15.0 ; extra == 'all' + - libcst>=1.4.0 ; extra == 'all' + - ty ; extra == 'all' + - typing-extensions>=4.8.0 ; extra == 'all' + - types-pyyaml ; extra == 'all' + - types-simplejson ; extra == 'all' + - types-toml ; extra == 'all' + - types-tqdm ; extra == 'all' + - types-urllib3 ; extra == 'all' + - authlib>=1.3.2 ; extra == 'dev' + - fastapi ; extra == 'dev' + - httpx ; extra == 'dev' + - itsdangerous ; extra == 'dev' + - jedi ; extra == 'dev' + - jinja2 ; extra == 'dev' + - pytest>=8.4.2 ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-env ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pytest-vcr ; extra == 'dev' + - pytest-asyncio ; extra == 'dev' + - pytest-rerunfailures<16.0 ; extra == 'dev' + - pytest-mock ; extra == 'dev' + - urllib3<2.0 ; extra == 'dev' + - soundfile ; extra == 'dev' + - pillow ; extra == 'dev' + - numpy ; extra == 'dev' + - duckdb ; extra == 'dev' + - fastapi ; extra == 'dev' + - ruff>=0.9.0 ; extra == 'dev' + - mypy==1.15.0 ; extra == 'dev' + - libcst>=1.4.0 ; extra == 'dev' + - ty ; extra == 'dev' + - typing-extensions>=4.8.0 ; extra == 'dev' + - types-pyyaml ; extra == 'dev' + - types-simplejson ; extra == 'dev' + - types-toml ; extra == 'dev' + - types-tqdm ; extra == 'dev' + - types-urllib3 ; extra == 'dev' + requires_python: '>=3.10.0' - pypi: https://files.pythonhosted.org/packages/9d/b3/11d406849715b47c9d69bb22f50874f80caee96bd1cbe7b61abbebbf5a05/ibis_framework-12.0.0-py3-none-any.whl name: ibis-framework version: 12.0.0 @@ -3211,50 +3431,45 @@ packages: - trino>=0.321 ; extra == 'trino' - graphviz>=0.16 ; extra == 'visualization' requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 - md5: 186a18e3ba246eccfc7cff00cd19a870 +- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + sha256: 1294117122d55246bb83ad5b589e2a031aacdf2d0b1f99fd338aa4394f881735 + md5: 627eca44e62e2b665eeec57a984a7f00 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 + - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 12728445 - timestamp: 1767969922681 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - sha256: 24bc62335106c30fecbcc1dba62c5eba06d18b90ea1061abd111af7b9c89c2d7 - md5: 114e6bfe7c5ad2525eb3597acdbf2300 + size: 12273764 + timestamp: 1773822733780 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5 + md5: f1182c91c0de31a7abd40cedf6a5ebef depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 12389400 - timestamp: 1772209104304 -- pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + size: 12361647 + timestamp: 1773822915649 +- pypi: https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl name: idna - version: '3.11' - sha256: 771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea + version: '3.18' + sha256: 7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 requires_dist: - ruff>=0.6.2 ; extra == 'all' - mypy>=1.11.2 ; extra == 'all' - pytest>=8.3.2 ; extra == 'all' - - flake8>=7.1.1 ; extra == 'all' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl name: importlib-metadata - version: 8.7.1 - sha256: 5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 + version: 9.0.0 + sha256: 2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 requires_dist: - zipp>=3.20 - pytest>=6,!=8.1.* ; extra == 'test' - packaging ; extra == 'test' - pyfakefs ; extra == 'test' - - flufl-flake8 ; extra == 'test' - pytest-perf>=0.9.2 ; extra == 'test' - - jaraco-test>=5.4 ; extra == 'test' - sphinx>=3.5 ; extra == 'doc' - jaraco-packaging>=9.3 ; extra == 'doc' - rst-linker>=1.9 ; extra == 'doc' @@ -3262,13 +3477,12 @@ packages: - sphinx-lint ; extra == 'doc' - jaraco-tidelift>=1.4 ; extra == 'doc' - ipython ; extra == 'perf' - - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-checkdocs>=2.14 ; extra == 'check' - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - pytest-cov ; extra == 'cover' - pytest-enabler>=3.4 ; extra == 'enabler' - - pytest-mypy>=1.0.1 ; extra == 'type' - - mypy<1.19 ; platform_python_implementation == 'PyPy' and extra == 'type' - requires_python: '>=3.9' + - pytest-mypy>=1.0.1 ; platform_python_implementation != 'PyPy' and extra == 'type' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl name: iniconfig version: 2.3.0 @@ -3321,17 +3535,17 @@ packages: requires_dist: - referencing>=0.31.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cd/58/4a1880ea64032185e9ae9f63940c9327c6952d5584ea544a8f66972f2fda/jwcrypto-1.5.6-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/72/24/fb7da4d6613de7001feaf540d4b5969c6b5a1c42839043b0196cb13aa057/jwcrypto-1.5.7-py3-none-any.whl name: jwcrypto - version: 1.5.6 - sha256: 150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 + version: 1.5.7 + sha256: 729463fefe28b6de5cf1ebfda3e94f1a1b41d2799148ef98a01cb9678ebe2bb0 requires_dist: - cryptography>=3.4 - typing-extensions>=4.5.0 requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 - md5: 12bd9a3f089ee6c9266a37dab82afabd +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c + md5: 18335a698559cdbcd86150a48bf54ba6 depends: - __glibc >=2.17,<3.0.a0 - zstd >=1.5.7,<1.6.0a0 @@ -3340,45 +3554,45 @@ packages: license: GPL-3.0-only license_family: GPL purls: [] - size: 725507 - timestamp: 1770267139900 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda - sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 - md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 + size: 728002 + timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda + sha256: 363018b25fdb5534c79783d912bd4b685a3547f4fc5996357ad548899b0ee8e7 + md5: 93764a5ca80616e9c10106cdaec92f74 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 constrains: - - expat 2.7.4.* + - expat 2.8.1.* license: MIT license_family: MIT purls: [] - size: 76798 - timestamp: 1771259418166 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda - sha256: 8d9d79b2de7d6f335692391f5281607221bf5d040e6724dad4c4d77cd603ce43 - md5: a684eb8a19b2aa68fde0267df172a1e3 + size: 77294 + timestamp: 1779278686680 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda + sha256: 460afe7ba0882e6d2fcc0ad1568dce27025110ec09c2b9ce9e3b49d61e52ce6b + md5: f95dc08366f2a452005062b5bcceac51 depends: - - __osx >=10.13 + - __osx >=11.0 constrains: - - expat 2.7.4.* + - expat 2.8.1.* license: MIT license_family: MIT purls: [] - size: 74578 - timestamp: 1771260142624 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda - sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf - md5: a92e310ae8dfc206ff449f362fc4217f + size: 75654 + timestamp: 1779279058576 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda + sha256: 3133fb6bfa871288b92c8b8752696686a841bf4ffe035aa3038033c9e15b738e + md5: ef22e9ab1dc7c2f334252f565f90b3b8 depends: - __osx >=11.0 constrains: - - expat 2.7.4.* + - expat 2.8.1.* license: MIT license_family: MIT purls: [] - size: 68199 - timestamp: 1771260020767 + size: 69110 + timestamp: 1779278728511 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 md5: a360c33a5abe61c07959e449fa1453eb @@ -3410,74 +3624,74 @@ packages: purls: [] size: 40979 timestamp: 1769456747661 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 - md5: 0aa00f03f9e39fb9876085dee11a85d4 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + sha256: 8e0a3b5e41272e5678499b5dfc4cddb673f9e935de01eb0767ce857001229f46 + md5: 57736f29cc2b0ec0b6c2952d3f101b6a depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.2.0=*_18 - - libgomp 15.2.0 he0feb66_18 + - libgcc-ng ==15.2.0=*_19 + - libgomp 15.2.0 he0feb66_19 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 1041788 - timestamp: 1771378212382 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 - md5: d5e96b1ed75ca01906b3d2469b4ce493 + size: 1041084 + timestamp: 1778269013026 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + sha256: 9dcf54adfaa5e861123c2da4f2f0451a685464ea7e5a41ad91cf67b31d658d98 + md5: 331ee9b72b9dff570d56b1302c5ab37d depends: - - libgcc 15.2.0 he0feb66_18 + - libgcc 15.2.0 he0feb66_19 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 27526 - timestamp: 1771378224552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 - md5: 239c5e9546c38a1e884d69effcf4c882 + size: 27694 + timestamp: 1778269016987 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + sha256: 5abe4ab9d93f6c9757d654f1969ae2267d4505315c1f2f8fe705fd60af084f1b + md5: faac990cb7aedc7f3a2224f2c9b0c26c depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 603262 - timestamp: 1771378117851 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda - sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb - md5: c7c83eecbb72d88b940c249af56c8b17 + size: 603817 + timestamp: 1778268942614 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d + md5: b88d90cad08e6bc8ad540cb310a761fb depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 constrains: - - xz 5.8.2.* + - xz 5.8.3.* license: 0BSD purls: [] - size: 113207 - timestamp: 1768752626120 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 - md5: 688a0c3d57fa118b9c97bf7e471ab46c + size: 113478 + timestamp: 1775825492909 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + sha256: d9e2006051529aec5578c6efeb13bb6a7200a014b2d5a77a579e83a8049d5f3c + md5: becdfbfe7049fa248e52aa37a9df09e2 depends: - - __osx >=10.13 + - __osx >=11.0 constrains: - - xz 5.8.2.* + - xz 5.8.3.* license: 0BSD purls: [] - size: 105482 - timestamp: 1768753411348 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e - md5: 009f0d956d7bfb00de86901d16e486c7 + size: 105724 + timestamp: 1775826029494 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + sha256: 34878d87275c298f1a732c6806349125cebbf340d24c6c23727268184bba051e + md5: b1fd823b5ae54fbec272cea0811bd8a9 depends: - __osx >=11.0 constrains: - - xz 5.8.2.* + - xz 5.8.3.* license: 0BSD purls: [] - size: 92242 - timestamp: 1768752982486 + size: 92472 + timestamp: 1775825802659 - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 md5: 2c21e66f50753a083cbe6b80f38268fa @@ -3520,93 +3734,80 @@ packages: purls: [] size: 33731 timestamp: 1750274110928 -- pypi: https://files.pythonhosted.org/packages/01/99/f85130582f05dcf0c8902f3d629270231d2f4afdfc567f8305a952ac7f14/librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/0a/7e/f5d92af8486b8272c23b3e686b46ff72d89c8169585eb61eef01a2ac7147/librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: librt - version: 0.8.1 - sha256: 97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b + version: 0.11.0 + sha256: 05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1b/18/25e991cd5640c9fb0f8d91b18797b29066b792f17bf8493da183bf5caabe/librt-0.8.1-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/29/eb/dbce197da4e227779e56b5735f2decc3eb36e55a1cdbf1bd65d6639d76c1/librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl name: librt - version: 0.8.1 - sha256: 228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c + version: 0.11.0 + sha256: 4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7c/5f/63f5fa395c7a8a93558c0904ba8f1c8d1b997ca6a3de61bc7659970d66bf/librt-0.8.1-cp310-cp310-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/6f/50/5ec949d7f9ce1a07af903aa3e13abb98b717923bdead6e719b2f824ccc07/librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: librt - version: 0.8.1 - sha256: 81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc + version: 0.11.0 + sha256: 88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c9/6a/907ef6800f7bca71b525a05f1839b21f708c09043b1c6aa77b6b827b3996/librt-0.8.1-cp314-cp314-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/76/a3/254bebd0c11c8ba684018efb8006ff22e466abce445215cca6c778e7d9de/librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl name: librt - version: 0.8.1 - sha256: 6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f + version: 0.11.0 + sha256: b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d1/96/ef04902aad1424fd7299b62d1890e803e6ab4018c3044dca5922319c4b97/librt-0.8.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/83/10/37fd9e9ba96cb0bd742dfb20fc3d082e54bdbec759d7300df927f360ef07/librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl name: librt - version: 0.8.1 - sha256: 6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 + version: 0.11.0 + sha256: 6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ff/e0/0472cf37267b5920eff2f292ccfaede1886288ce35b7f3203d8de00abfe6/librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/cf/72/1b1466f358e4a0b728051f69bc27e67b432c6eaa2e05b88db49d3785ae0d/librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl name: librt - version: 0.8.1 - sha256: 5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 + version: 0.11.0 + sha256: ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - sha256: 04596fcee262a870e4b7c9807224680ff48d4d0cc0dac076a602503d3dc6d217 - md5: da5be73701eecd0e8454423fd6ffcf30 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + sha256: 1ab603b6ec93933e76027e1f23b21b22b858ba1b56f1e1695ef6fe5e80cb7358 + md5: 062b0ac602fb0adf250e3dfa86f221c4 depends: - __glibc >=2.17,<3.0.a0 - - icu >=78.2,<79.0a0 - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 license: blessing purls: [] - size: 942808 - timestamp: 1768147973361 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - sha256: 710a7ea27744199023c92e66ad005de7f8db9cf83f10d5a943d786f0dac53b7c - md5: d910105ce2b14dfb2b32e92ec7653420 + size: 957849 + timestamp: 1780574429573 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.2-h8f8c405_0.conda + sha256: 4d4f3135d390d192ab9cdf3711d87e3be6bb7f3959c52a96e2f333b30960d6fb + md5: 4c019bd25570899d0f9755de01b89021 depends: - - __osx >=10.13 - - libzlib >=1.3.1,<2.0a0 + - __osx >=11.0 + - icu >=78.3,<79.0a0 + - libzlib >=1.3.2,<2.0a0 license: blessing purls: [] - size: 987506 - timestamp: 1768148247615 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - sha256: 6e9b9f269732cbc4698c7984aa5b9682c168e2a8d1e0406e1ff10091ca046167 - md5: 4b0bf313c53c3e89692f020fb55d5f2c + size: 1010419 + timestamp: 1780575011758 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda + sha256: 862463917e8ef5ac3ebdaf8f19914634b457609cc27ba678b7197124cefeb1f7 + md5: 1ebde5c677f00765233a17e278571177 depends: - __osx >=11.0 - - icu >=78.2,<79.0a0 - - libzlib >=1.3.1,<2.0a0 + - icu >=78.3,<79.0a0 + - libzlib >=1.3.2,<2.0a0 license: blessing purls: [] - size: 909777 - timestamp: 1768148320535 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e - md5: 1b08cd684f34175e4514474793d44bcb - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 he0feb66_18 - constrains: - - libstdcxx-ng ==15.2.0=*_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 5852330 - timestamp: 1771378262446 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee - md5: db409b7c1720428638e7c0d509d3e1b5 + size: 927724 + timestamp: 1780575223548 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + sha256: 3f0edf1280e2f6684a986f821eaa3e123d2694a00b31b96ca0d4a4c12c129231 + md5: 7d0a66598195ef00b6efc55aefc7453b depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: BSD-3-Clause license_family: BSD purls: [] - size: 40311 - timestamp: 1766271528534 + size: 40163 + timestamp: 1779118517630 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c md5: 5aa797f8787fe7a17d1b0821485b5adc @@ -3616,52 +3817,51 @@ packages: purls: [] size: 100393 timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 - md5: edb0dca6bc32e4f4789199455a1dbeb8 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 + md5: d87ff7921124eccd67248aa483c23fec depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 constrains: - - zlib 1.3.1 *_2 + - zlib 1.3.2 *_2 license: Zlib license_family: Other purls: [] - size: 60963 - timestamp: 1727963148474 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - sha256: 8412f96504fc5993a63edf1e211d042a1fd5b1d51dedec755d2058948fcced09 - md5: 003a54a4e32b02f7355b50a837e699da + size: 63629 + timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + sha256: 4c6da089952b2d70150c74234679d6f7ac04f4a98f9432dec724968f912691e7 + md5: 30439ff30578e504ee5e0b390afc8c65 depends: - - __osx >=10.13 + - __osx >=11.0 constrains: - - zlib 1.3.1 *_2 + - zlib 1.3.2 *_2 license: Zlib license_family: Other purls: [] - size: 57133 - timestamp: 1727963183990 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b - md5: 369964e85dc26bfe78f41399b366c435 + size: 59000 + timestamp: 1774073052242 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 + md5: bc5a5721b6439f2f62a84f2548136082 depends: - __osx >=11.0 constrains: - - zlib 1.3.1 *_2 + - zlib 1.3.2 *_2 license: Zlib license_family: Other purls: [] - size: 46438 - timestamp: 1727963202283 + size: 47759 + timestamp: 1774072956767 - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl name: locket version: 1.0.0 sha256: b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl name: markdown-it-py - version: 4.0.0 - sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 + version: 4.2.0 + sha256: 9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a requires_dist: - mdurl~=0.1 - psutil ; extra == 'benchmarking' @@ -3689,6 +3889,7 @@ packages: - pytest ; extra == 'testing' - pytest-cov ; extra == 'testing' - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' - requests ; extra == 'testing' requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl @@ -3737,138 +3938,144 @@ packages: - pycryptodome - typing-extensions requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/39/8e/29306d5eca6dfda4b899d22c95b5420db4e0ffb7e0b6389b17379654ece5/mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/6f/75/2c24517d4b2ce9e4917362d24f274d3d541346af764430249ddcc4cb3a08/mmh3-5.2.1-cp314-cp314-macosx_10_15_x86_64.whl name: mmh3 - version: 5.2.0 - sha256: dfbead5575f6470c17e955b94f92d62a03dfc3d07f2e6f817d9b93dc211a1515 - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: 72d1cc63bcc91e14933f77d51b3df899d6a07d184ec515ea7f56bff659e124d7 + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3b/88/eb9a55b3f3cf43a74d6bfa8db0e2e209f966007777a1dc897c52c008314c/mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b6/71/c1a60c1652b8813ef9de6d289784847355417ee0f2980bca002fe87f4ae5/mmh3-5.2.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: mmh3 - version: 5.2.0 - sha256: 0b898cecff57442724a0f52bf42c2de42de63083a91008fb452887e372f9c328 - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: 8ff038d52ef6aa0f309feeba00c5095c9118d0abf787e8e8454d6048db2037fc + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/70/1f/f87e3d34d83032b4f3f0f528c6d95a98290fcacf019da61343a49dccfd51/mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/b9/e4a360164365ac9f07a25f0f7928e3a66eb9ecc989384060747aa170e6aa/mmh3-5.2.1-cp314-cp314-macosx_11_0_arm64.whl name: mmh3 - version: 5.2.0 - sha256: ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110 - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: e8b4b5580280b9265af3e0409974fb79c64cf7523632d03fbf11df18f8b0181e + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a6/e2/db849eaed07117086f3452feca8c839d30d38b830ac59fe1ce65af8be5ad/mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c6/b1/e20d5f0d19c4c0f3df213fa7dcfa0942c4fb127d38e11f398ae8ddf6cccc/mmh3-5.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: mmh3 - version: 5.2.0 - sha256: 37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647 - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: fb9d44c25244e11c8be3f12c938ca8ba8404620ef8092245d2093c6ab3df260f + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ca/e0/78adf4104c425606a9ce33fb351f790c76a6c2314969c4a517d1ffc92196/mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cc/bf/5404c2fd6ac84819e8ff1b7e34437b37cf55a2b11318894909e7bb88de3f/mmh3-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl name: mmh3 - version: 5.2.0 - sha256: 1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12 - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: 30e4d2084df019880d55f6f7bea35328d9b464ebee090baa372c096dc77556fb + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d1/4c/8e4b3878bf8435c697d7ce99940a3784eb864521768069feaccaff884a17/mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/de/0b/52bffad0b52ae4ea53e222b594bd38c08ecac1fc410323220a7202e43da5/mmh3-5.2.1-cp310-cp310-macosx_11_0_arm64.whl name: mmh3 - version: 5.2.0 - sha256: be1374df449465c9f2500e62eee73a39db62152a8bdfbe12ec5b5c1cd451344d - requires_dist: - - pytest==8.4.1 ; extra == 'test' - - pytest-sugar==1.0.0 ; extra == 'test' - - black==25.1.0 ; extra == 'lint' - - clang-format==20.1.8 ; extra == 'lint' - - isort==6.0.1 ; extra == 'lint' - - pylint==3.3.7 ; extra == 'lint' - - mypy==1.17.0 ; extra == 'type' - - myst-parser==4.0.1 ; extra == 'docs' - - shibuya==2025.7.24 ; extra == 'docs' + version: 5.2.1 + sha256: 0bbc17250b10d3466875a40a52520a6bac3c02334ca709207648abd3c223ed5c + requires_dist: + - pytest==9.0.2 ; extra == 'test' + - pytest-sugar==1.1.1 ; extra == 'test' + - actionlint-py==1.7.11.24 ; extra == 'lint' + - clang-format==22.1.0 ; extra == 'lint' + - codespell==2.4.1 ; extra == 'lint' + - pylint==4.0.5 ; extra == 'lint' + - ruff==0.15.4 ; extra == 'lint' + - mypy==1.19.1 ; extra == 'type' + - myst-parser==5.0.0 ; extra == 'docs' + - shibuya==2026.1.9 ; extra == 'docs' - sphinx==8.2.3 ; extra == 'docs' - sphinx-copybutton==0.5.2 ; extra == 'docs' - pymmh3==0.0.5 ; extra == 'benchmark' - - pyperf==2.9.0 ; extra == 'benchmark' - - xxhash==3.5.0 ; extra == 'benchmark' - - matplotlib==3.10.3 ; extra == 'plot' - - pandas==2.3.1 ; extra == 'plot' - requires_python: '>=3.9' + - pyperf==2.10.0 ; extra == 'benchmark' + - xxhash==3.6.0 ; extra == 'benchmark' + - matplotlib==3.10.8 ; extra == 'plot' + - pandas==3.0.1 ; extra == 'plot' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/5b/e1/2b720cc341325c00be44e1ed59e7cfeae2678329fbf5aa68f5bda57fe728/msgpack-1.1.2-cp310-cp310-macosx_11_0_arm64.whl name: msgpack version: 1.1.2 @@ -3905,135 +4112,154 @@ packages: requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl + name: multiprocess + version: 0.70.17 + sha256: 38357ca266b51a2e22841b755d9a91e4bb7b937979a54d411677111716c32744 + requires_dist: + - dill>=0.3.9 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl name: mypy - version: 1.19.1 - sha256: de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 + version: 2.1.0 + sha256: 49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2f/45/7d51594b644c17c0bcf74ed8cd5fc33b324276d708e8506f220b70dab9d9/mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl name: mypy - version: 1.19.1 - sha256: 5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec + version: 2.1.0 + sha256: 8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/41/5a/93093f0b29a9e982deafde698f740a2eb2e05886e79ccf0594c7fd5413a3/mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: mypy - version: 1.19.1 - sha256: 28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 + version: 2.1.0 + sha256: 47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: mypy - version: 1.19.1 - sha256: 022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b + version: 2.1.0 + sha256: c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a4/71/d351dca3e9b30da2328ee9d445c88b8388072808ebfbc49eb69d30b67749/mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl name: mypy - version: 1.19.1 - sha256: 804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 + version: 2.1.0 + sha256: 11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl name: mypy - version: 1.19.1 - sha256: 06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 + version: 2.1.0 + sha256: 7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 requires_dist: - - typing-extensions>=4.6.0 + - typing-extensions>=4.6.0 ; python_full_version < '3.15' + - typing-extensions>=4.14.0 ; python_full_version >= '3.15' - mypy-extensions>=1.0.0 - - pathspec>=0.9.0 + - pathspec>=1.0.0 - tomli>=1.1.0 ; python_full_version < '3.11' - - librt>=0.6.2 ; platform_python_implementation != 'PyPy' + - librt>=0.11.0 ; platform_python_implementation != 'PyPy' + - ast-serialize>=0.3.0,<1.0.0 - psutil>=4.0 ; extra == 'dmypy' - setuptools>=50 ; extra == 'mypyc' - lxml ; extra == 'reports' - pip ; extra == 'install-types' - orjson ; extra == 'faster-cache' - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl name: mypy-extensions version: 1.1.0 sha256: 1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 - md5: 47e340acb35de30501a76c7c799c41d7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 + md5: fc21868a1a5aacc937e7a18747acb8a5 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: X11 AND BSD-3-Clause purls: [] - size: 891641 - timestamp: 1738195959188 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - sha256: ea4a5d27ded18443749aefa49dc79f6356da8506d508b5296f60b8d51e0c4bd9 - md5: ced34dd9929f491ca6dab6a2927aff25 + size: 918956 + timestamp: 1777422145199 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + sha256: f5f7e006ff4271305ab4cc08eedd855c67a571793c3d18aff73f645f088a8cae + md5: 31b8740cf1b2588d4e61c81191004061 depends: - - __osx >=10.13 + - __osx >=11.0 license: X11 AND BSD-3-Clause purls: [] - size: 822259 - timestamp: 1738196181298 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 - md5: 068d497125e4bf8a66bf707254fff5ae + size: 831711 + timestamp: 1777423052277 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d + md5: 343d10ed5b44030a2f67193905aea159 depends: - __osx >=11.0 license: X11 AND BSD-3-Clause purls: [] - size: 797030 - timestamp: 1738196177597 + size: 805509 + timestamp: 1777423252320 - pypi: https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl name: numpy version: 2.2.6 @@ -4049,20 +4275,20 @@ packages: version: 2.2.6 sha256: fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl name: numpy - version: 2.4.2 - sha256: 444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b + version: 2.4.6 + sha256: 38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: numpy - version: 2.4.2 - sha256: d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000 + version: 2.4.6 + sha256: a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl name: numpy - version: 2.4.2 - sha256: bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325 + version: 2.4.6 + sha256: 06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl name: oauthlib @@ -4074,9 +4300,9 @@ packages: - pyjwt>=2.0.0,<3 ; extra == 'signedtoken' - blinker>=1.4.0 ; extra == 'signals' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c - md5: f61eb8cd60ff9057122a3d338b99c00f +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb + md5: da1b85b6a87e141f5140bb9924cecab0 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates @@ -4084,54 +4310,34 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - size: 3164551 - timestamp: 1769555830639 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90 - md5: 30bb8d08b99b9a7600d39efb3559fff0 + size: 3167099 + timestamp: 1775587756857 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + sha256: 334fd49ea31b99114f5afb1ec44555dc8c90640648302a4f8f838ee345d1ec50 + md5: 5cf0ece4375c73d7a5765e83565a69c7 depends: - - __osx >=10.13 + - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2777136 - timestamp: 1769557662405 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 - md5: f4f6ad63f98f64191c3e77c5f5f29d76 + size: 2776564 + timestamp: 1775589970694 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + sha256: c91bf510c130a1ea1b6ff023e28bac0ccaef869446acd805e2016f69ebdc49ea + md5: 25dcccd4f80f1638428613e0d7c9b4e1 depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 3104268 - timestamp: 1769556384749 -- pypi: https://files.pythonhosted.org/packages/8f/ed/f2b5d66aa9b6b5c02ff5f120efc7b38c7c4962b21e6be0f00fd99a5c348e/orjson-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: orjson - version: 3.11.7 - sha256: cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c2/8b/ecdad52d0b38d4b8f514be603e69ccd5eacf4e7241f972e37e79792212ec/orjson-3.11.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: orjson - version: 3.11.7 - sha256: a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/de/1a/a373746fa6d0e116dd9e54371a7b54622c44d12296d5d0f3ad5e3ff33490/orjson-3.11.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - name: orjson - version: 3.11.7 - sha256: a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e9/1e/745565dca749813db9a093c5ebc4bac1a9475c64d54b95654336ac3ed961/orjson-3.11.7-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - name: orjson - version: 3.11.7 - sha256: de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + size: 3106008 + timestamp: 1775587972483 +- pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl name: packaging - version: '26.0' - sha256: b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 + version: '26.2' + sha256: 5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl name: pandas @@ -4679,16 +4885,16 @@ packages: - xlsxwriter>=3.0.5 ; extra == 'all' - zstandard>=0.19.0 ; extra == 'all' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/26/b7/e805de93e3aa78813912b19edc9c8b037d6cd1c302ab339b895f305cf9a5/pandas_gbq-0.33.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/06/3d/2f0e9c5cbc456d34f48215645d876f7885a15e09a72a07d1de3ddb181c38/pandas_gbq-0.35.0-py3-none-any.whl name: pandas-gbq - version: 0.33.0 - sha256: 499ad18a7b1917e2cc04bbd763ec37c11ecc49030348c45cebb9cbbdb7f909af + version: 0.35.0 + sha256: 258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 requires_dist: - setuptools - - db-dtypes>=1.0.4,<2.0.0 - - numpy>=1.18.1 - - pandas>=1.1.4,<3.0.0 - - pyarrow>=4.0.0 + - db-dtypes>=1.1.1,<2.0.0 + - numpy>=1.26.4 + - pandas>=1.5.3 + - pyarrow>=12.0.0 - pyarrow>=22.0.0 ; python_full_version >= '3.14' - pydata-google-auth>=1.5.0 - psutil>=5.9.8 @@ -4699,9 +4905,9 @@ packages: - packaging>=22.0.0 - google-cloud-bigquery-storage>=2.16.2,<3.0.0 ; extra == 'bqstorage' - tqdm>=4.23.0 ; extra == 'tqdm' - - geopandas>=0.9.0 ; extra == 'geopandas' - - shapely>=1.8.4 ; extra == 'geopandas' - requires_python: '>=3.9' + - geopandas>=0.14.4 ; extra == 'geopandas' + - shapely>=1.8.5 ; extra == 'geopandas' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/77/fc/8cb9073bb1bee54eb49a1ae501a36402d01763812962ac811cdc1c81a9d7/parsy-2.2-py3-none-any.whl name: parsy version: '2.2' @@ -4719,21 +4925,19 @@ packages: - pyzmq ; extra == 'complete' - blosc ; extra == 'complete' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl name: pathspec - version: 1.0.4 - sha256: fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 + version: 1.1.1 + sha256: a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 requires_dist: - hyperscan>=0.7 ; extra == 'hyperscan' - typing-extensions>=4 ; extra == 'optional' - google-re2>=1.1 ; extra == 're2' - - pytest>=9 ; extra == 'tests' - - typing-extensions>=4.15 ; extra == 'tests' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl name: platformdirs - version: 4.9.2 - sha256: 9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd + version: 4.10.0 + sha256: fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl name: pluggy @@ -4755,48 +4959,48 @@ packages: - aiohttp ; extra == 'aiohttp' - django ; extra == 'django' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/1a/55/1140a8e067b8ec093a18a4ae7bb0045d9db65da38a08618ddc5e2f1994aa/propcache-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl name: propcache - version: 0.4.1 - sha256: 2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl + version: 0.5.2 + sha256: 29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/20/42/0e7443c90310498561addf346e7d57fe3c6ba1914e1ba938b5464c7bbfd2/propcache-0.5.2-cp310-cp310-macosx_11_0_arm64.whl name: propcache - version: 0.4.1 - sha256: 1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl + version: 0.5.2 + sha256: 6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/39/6e/899fed76dc1942b8a64193a4f059d7f1a2c7ef65085e8a9366ed8ec0d199/propcache-0.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: propcache - version: 0.4.1 - sha256: 66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5d/79/ac273cbbf744691821a9cca88957257f41afe271637794975ca090b9588b/proto_plus-1.27.1-py3-none-any.whl + version: 0.5.2 + sha256: b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl name: proto-plus - version: 1.27.1 - sha256: e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc + version: 1.28.0 + sha256: a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 requires_dist: - - protobuf>=3.19.0,<7.0.0 + - protobuf>=4.25.8,<8.0.0 - google-api-core>=1.31.5 ; extra == 'testing' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/9b/53/a9443aa3ca9ba8724fdfa02dd1887c1bcd8e89556b715cfbacca6b63dbec/protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl name: protobuf - version: 6.33.5 - sha256: cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 + version: 6.33.6 + sha256: e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl name: protobuf - version: 6.33.5 - sha256: a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 + version: 6.33.6 + sha256: 9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/13/c4/6322ab5c8f279c4c358bc14eb8aefc0550b97222a39f04eb3c1af7a830fa/protobuf-7.34.0-cp310-abi3-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/70/5b/6baf9008817964454055ff3fe65f1de0b5f1e26c80c82f7fb108b7cd4ea3/protobuf-7.35.0-cp310-abi3-manylinux2014_x86_64.whl name: protobuf - version: 7.34.0 - sha256: 8e329966799f2c271d5e05e236459fe1cbfdb8755aaa3b0914fa60947ddea408 + version: 7.35.0 + sha256: 6c0f98f10c8a05ea30f8993dfef2de093d27b490fdae78bb60c8343795d55011 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b5/57/89727baef7578897af5ed166735ceb315819f1c184da8c3441271dbcfde7/protobuf-7.34.0-cp310-abi3-manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/83/ee/93d06e358a4aa32280b00e722d3ea0a1f25fc3cc5778d80581c9cca2c10e/protobuf-7.35.0-cp310-abi3-macosx_10_9_universal2.whl name: protobuf - version: 7.34.0 - sha256: 964cf977e07f479c0697964e83deda72bcbc75c3badab506fb061b352d991b01 + version: 7.35.0 + sha256: 66be6c513931c794fa92c080ffee41671390da3d79da219cf9c0c0907f035dda requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl name: psutil @@ -4930,58 +5134,59 @@ packages: - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/18/f3/14a1370b1449ca875d5e353ef02cb9db6b70bd46ec361c236176837c0be1/psycopg-3.2.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl name: psycopg - version: 3.2.5 - sha256: b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 + version: 3.3.4 + sha256: b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a requires_dist: - - backports-zoneinfo>=0.2.0 ; python_full_version < '3.9' - typing-extensions>=4.6 ; python_full_version < '3.13' - tzdata ; sys_platform == 'win32' - - psycopg-c==3.2.5 ; implementation_name != 'pypy' and extra == 'c' - - psycopg-binary==3.2.5 ; implementation_name != 'pypy' and extra == 'binary' + - psycopg-c==3.3.4 ; implementation_name != 'pypy' and extra == 'c' + - psycopg-binary==3.3.4 ; implementation_name != 'pypy' and extra == 'binary' - psycopg-pool ; extra == 'pool' - anyio>=4.0 ; extra == 'test' - - mypy>=1.14 ; extra == 'test' + - mypy>=1.19.0 ; implementation_name != 'pypy' and extra == 'test' - pproxy>=2.7 ; extra == 'test' - pytest>=6.2.5 ; extra == 'test' - pytest-cov>=3.0 ; extra == 'test' - pytest-randomly>=3.5 ; extra == 'test' - ast-comments>=1.1.2 ; extra == 'dev' - - black>=24.1.0 ; extra == 'dev' + - black>=26.1.0 ; extra == 'dev' - codespell>=2.2 ; extra == 'dev' + - cython-lint>=0.16 ; extra == 'dev' - dnspython>=2.1 ; extra == 'dev' - flake8>=4.0 ; extra == 'dev' - isort[colors]>=6.0 ; extra == 'dev' - isort-psycopg ; extra == 'dev' - - mypy>=1.14 ; extra == 'dev' + - mypy>=1.19.0 ; extra == 'dev' - pre-commit>=4.0.1 ; extra == 'dev' - types-setuptools>=57.4 ; extra == 'dev' + - types-shapely>=2.0 ; extra == 'dev' - wheel>=0.37 ; extra == 'dev' - - sphinx>=5.0 ; extra == 'docs' - - furo==2022.6.21 ; extra == 'docs' - - sphinx-autobuild>=2021.3.14 ; extra == 'docs' - - sphinx-autodoc-typehints>=1.12 ; extra == 'docs' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/31/77/31968655db2efe83c519e6296ff3a85a0c9e50432e0c11c8ffae1b404870/psycopg_binary-3.2.5-cp310-cp310-macosx_11_0_arm64.whl + - sphinx>=9.1 ; extra == 'docs' + - furo==2025.12.19 ; extra == 'docs' + - sphinx-autobuild>=2025.8.25 ; extra == 'docs' + - sphinx-autodoc-typehints>=3.10.2 ; extra == 'docs' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/87/9a/f088207b4cd6772f9e0d8a91807e79fa2458d4eb9eb1ae406c68415f2bec/psycopg_binary-3.3.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: psycopg-binary - version: 3.2.5 - sha256: e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a5/90/9f2c41b3b42d8cd8b9866f0bbd27a5796a1ca8042a1a019b39a6645df523/psycopg_binary-3.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + version: 3.3.4 + sha256: fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b7/bf/70d8a60488f9955cbbcd538beae44d56bb2f1d19e673b72788f2d343ff55/psycopg_binary-3.3.4-cp310-cp310-macosx_10_9_x86_64.whl name: psycopg-binary - version: 3.2.5 - sha256: c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d6/30/af3806081adc75b5a8addde839d4c6b171a8c5d0d07dd92de20ca4dd6717/psycopg_binary-3.2.5-cp310-cp310-macosx_10_9_x86_64.whl + version: 3.3.4 + sha256: b7bfff1ca23732b488cbca3076fc11bc98d520ee122514fdb17a8e20d3338f5a + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/db/b0/29e98ba210c9dbc75a6dc91e3f99b9e06ea901a62ca95804e02a1ae13e6b/psycopg_binary-3.3.4-cp310-cp310-macosx_11_0_arm64.whl name: psycopg-binary - version: 3.2.5 - sha256: a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e7/c3/26b8a0908a9db249de3b4169692e1c7c19048a9bc41a4d3209cee7dbb758/psycopg_pool-3.3.0-py3-none-any.whl + version: 3.3.4 + sha256: 32a6fbf8481e3a370d0d72b860d35948a693cb01281da217f7b2f307636e591a + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/37/ed/89c2c620af0e1660354cd8aabf9f5b21f911597ce22acb37c805d6c86bc8/psycopg_pool-3.3.1-py3-none-any.whl name: psycopg-pool - version: 3.3.0 - sha256: 2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 + version: 3.3.1 + sha256: 2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 requires_dist: - typing-extensions>=4.6 - anyio>=4.0 ; extra == 'test' @@ -5004,45 +5209,45 @@ packages: name: py4j version: 0.10.9.9 sha256: c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 -- pypi: https://files.pythonhosted.org/packages/36/2e/c0f017c405fcdc252dbccafbe05e36b0d0eb1ea9a958f081e01c6972927f/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/1a/ff/f01485fda6f4e5d441afb8dd5e7681e4db18826c1e271852f5d3957d6a80/pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl name: pyarrow - version: 23.0.1 - sha256: 4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 + version: 24.0.0 + sha256: e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/8d/1b/6da9a89583ce7b23ac611f183ae4843cd3a6cf54f079549b0e8c14031e73/pyarrow-23.0.1-cp314-cp314-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/1d/41/64180033d7027afce12dc96d0fe1f504c6fa112190582b458acea2399530/pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl name: pyarrow - version: 23.0.1 - sha256: 5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca + version: 24.0.0 + sha256: 644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ae/b5/d58a241fbe324dbaeb8df07be6af8752c846192d78d2272e551098f74e88/pyarrow-23.0.1-cp314-cp314-macosx_12_0_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/67/33/f75e91b9a64c3f33c787e263c93b871ad91b8a4a68c1d5cebddd9840e835/pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl name: pyarrow - version: 23.0.1 - sha256: fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 + version: 24.0.0 + sha256: e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bc/8e/4be5617b4aaae0287f621ad31c6036e5f63118cfca0dc57d42121ff49b51/pyarrow-23.0.1-cp310-cp310-macosx_12_0_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/8e/3a/28ba9c1c1ebdbb5f1b94dfebb46f207e52e6a554b7fe4132540fde29a3a0/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl name: pyarrow - version: 23.0.1 - sha256: 3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c + version: 24.0.0 + sha256: ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bc/a8/24e5dc6855f50a62936ceb004e6e9645e4219a8065f304145d7fb8a79d5d/pyarrow-23.0.1-cp310-cp310-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/a5/bf/a34fee1d624152124fa8355c42f34195ad5fe5233ce5bb87946432047d52/pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl name: pyarrow - version: 23.0.1 - sha256: 3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 + version: 24.0.0 + sha256: 7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f8/82/c40b68001dbec8a3faa4c08cd8c200798ac732d2854537c5449dc859f55a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/ad/80/d022a34ff05d2cbedd8ccf841fc1f532ecfa9eb5ed1711b56d0e0ea71fc9/pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl name: pyarrow - version: 23.0.1 - sha256: c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 + version: 24.0.0 + sha256: 1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/2e/c3/94ade4906a2f88bc935772f59c934013b4205e773bcb4239db114a6da136/pyarrow_hotfix-0.7-py3-none-any.whl name: pyarrow-hotfix version: '0.7' sha256: 3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl name: pyasn1 - version: 0.6.2 - sha256: 1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf + version: 0.6.3 + sha256: a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl name: pyasn1-modules @@ -5071,57 +5276,57 @@ packages: version: 3.23.0 sha256: 187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' -- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl name: pydantic - version: 2.12.5 - sha256: e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d + version: 2.13.4 + sha256: 45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba requires_dist: - annotated-types>=0.6.0 - - pydantic-core==2.41.5 + - pydantic-core==2.46.4 - typing-extensions>=4.14.1 - typing-inspection>=0.4.2 - email-validator>=2.0.0 ; extra == 'email' - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl name: pydantic-core - version: 2.41.5 - sha256: 22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 + version: 2.46.4 + sha256: da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: pydantic-core - version: 2.41.5 - sha256: 1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 + version: 2.46.4 + sha256: 7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl name: pydantic-core - version: 2.41.5 - sha256: 100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a + version: 2.46.4 + sha256: 428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl name: pydantic-core - version: 2.41.5 - sha256: 77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 + version: 2.46.4 + sha256: 23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: pydantic-core - version: 2.41.5 - sha256: 3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a + version: 2.46.4 + sha256: 395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl name: pydantic-core - version: 2.41.5 - sha256: dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 + version: 2.46.4 + sha256: a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 requires_dist: - typing-extensions>=4.14.1 requires_python: '>=3.9' @@ -5134,57 +5339,46 @@ packages: - google-auth>=1.25.0,<3.0.dev0 - google-auth-oauthlib>=0.4.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl name: pygments - version: 2.19.2 - sha256: 86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b + version: 2.20.0 + sha256: 81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 requires_dist: - colorama>=0.4.6 ; extra == 'windows-terminal' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl name: pyjwt - version: 2.11.0 - sha256: 94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 + version: 2.13.0 + sha256: 66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 requires_dist: + - typing-extensions>=4.0 ; python_full_version < '3.11' - cryptography>=3.4.0 ; extra == 'crypto' - - coverage[toml]==7.10.7 ; extra == 'dev' - - cryptography>=3.4.0 ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest>=8.4.2,<9.0.0 ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-rtd-theme ; extra == 'dev' - - zope-interface ; extra == 'dev' - - sphinx ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - zope-interface ; extra == 'docs' - - coverage[toml]==7.10.7 ; extra == 'tests' - - pytest>=8.4.2,<9.0.0 ; extra == 'tests' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c4/bd/2534e130295c8cfd4f0a2e31623baab7502278f1e97bcfe61db75656a77f/pymysql-1.2.0-py3-none-any.whl name: pymysql - version: 1.1.2 - sha256: e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 + version: 1.2.0 + sha256: 62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 requires_dist: - - cryptography ; extra == 'rsa' - - pynacl>=1.4.0 ; extra == 'ed25519' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/80/28/2659c02301b9500751f8d42f9a6632e1508aa5120de5e43042b8b30f8d5d/pyopenssl-25.1.0-py3-none-any.whl + - cryptography>=46.0.7 ; extra == 'rsa' + - pynacl>=1.6.2 ; extra == 'ed25519' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl name: pyopenssl - version: 25.1.0 - sha256: 2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab + version: 26.2.0 + sha256: 4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 requires_dist: - - cryptography>=41.0.5,<46 + - cryptography>=46.0.0,<49 - typing-extensions>=4.9 ; python_full_version >= '3.8' and python_full_version < '3.13' - pytest-rerunfailures ; extra == 'test' - pretend ; extra == 'test' - pytest>=3.0.1 ; extra == 'test' - sphinx!=5.2.0,!=5.2.0.post0,!=7.2.5 ; extra == 'docs' - sphinx-rtd-theme ; extra == 'docs' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/19/bf/58ee13add151469c25825b7125bbf62c3bdcec05eec4d458fcb5c5516066/pyspark-4.1.1.tar.gz + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5e/71/4dd20c69332a2a4bf7ece8a655c9da98e4bd9b6bcea235349c1a00399d57/pyspark-4.1.2.tar.gz name: pyspark - version: 4.1.1 - sha256: 77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec + version: 4.1.2 + sha256: fa5d6159f700d0990a07f4f62df1b7449401dccee9cd7d5d6df8957530841602 requires_dist: - py4j>=0.10.9.7,<0.10.9.10 - numpy>=1.21 ; extra == 'ml' @@ -5308,15 +5502,14 @@ packages: - psutil>=3.0 ; extra == 'psutil' - setproctitle ; extra == 'setproctitle' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda - build_number: 3 - sha256: 2d8b5566d82c3872f057661e056d696f2f77a17ee5a36d9ae6ec43052c4d1c51 - md5: be48679ccfbc8710dea1d5970600fa04 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda + sha256: 8ff2ce308faf2588b69c65b120293f59a8f2577b772b34df4e817d220b09e081 + md5: 5d4e2b00d99feacd026859b7fa239dc0 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.4,<3.0a0 - libffi >=3.4,<4.0a0 - libgcc >=14 - liblzma >=5.8.2,<6.0a0 @@ -5326,7 +5519,7 @@ packages: - libxcrypt >=4.4.36 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 + - openssl >=3.5.5,<4.0a0 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -5334,26 +5527,26 @@ packages: - python_abi 3.10.* *_cp310 license: Python-2.0 purls: [] - size: 25358312 - timestamp: 1769471983988 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda - build_number: 101 - sha256: cb0628c5f1732f889f53a877484da98f5a0e0f47326622671396fb4f2b0cd6bd - md5: c014ad06e60441661737121d3eae8a60 + size: 25455342 + timestamp: 1772729810280 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda + build_number: 100 + sha256: 55eed9bf2a3f6e90311276f0834737fe7c2d9ec3e5e2e557507858df4c7521e6 + md5: da92e59ff92f2d5ede4f612af20f583f depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.8.0,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libuuid >=2.41.3,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - libsqlite >=3.53.1,<4.0a0 + - libuuid >=2.42.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - openssl >=3.5.6,<4.0a0 - python_abi 3.14.* *_cp314 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 @@ -5361,23 +5554,22 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 36702440 - timestamp: 1770675584356 + size: 36745188 + timestamp: 1779236923603 python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.19-h988dfef_3_cpython.conda - build_number: 3 - sha256: e05e6e5d076f76e609e8665969391dabdbbb298ecf1cbd58a206bf39a10dbc67 - md5: 2717612cf85c1138d5a0645b1db537fb +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.20-hea035f4_0_cpython.conda + sha256: b6b9d6a85003b21ac17cc1485e196906bd704759caaab1315f6f8eeb85f26202 + md5: bc2a1cfdea76213972b98c65be1e2023 depends: - - __osx >=10.13 + - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.4,<3.0a0 - libffi >=3.4,<4.0a0 - liblzma >=5.8.2,<6.0a0 - libsqlite >=3.51.2,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 + - openssl >=3.5.5,<4.0a0 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -5385,23 +5577,23 @@ packages: - python_abi 3.10.* *_cp310 license: Python-2.0 purls: [] - size: 13150073 - timestamp: 1769472282154 -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda - build_number: 101 - sha256: f64e357aa0168a201c9b3eedf500d89a8550d6631d26a95590b12de61f8fd660 - md5: 030ec23658b941438ac42303aff0db2b + size: 13083662 + timestamp: 1772730522090 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.5-h7c6738f_100_cp314.conda + build_number: 100 + sha256: f99fd77c51d52319f02b7732971b35921a987ac49ca9b60f9c2e280b0dcdd409 + md5: 915728f929ae3610f084aecdf62f5272 depends: - - __osx >=10.13 + - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.8.0,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - libsqlite >=3.53.1,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - openssl >=3.5.6,<4.0a0 - python_abi 3.14.* *_cp314 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 @@ -5409,23 +5601,22 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 14387288 - timestamp: 1770676578632 + size: 14450441 + timestamp: 1779239702259 python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda - build_number: 3 - sha256: 7ce2adb0cc4d45178dc018b55148fa2d6ccae0c98291cef1b21dafcda2de2687 - md5: ac461265b59028847699c0606e17804b +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.20-h1b19095_0_cpython.conda + sha256: f0f6fcbb6cfdee5a6b9c03b5b94d2bbe737f3b17a618006c7685cc48992ae667 + md5: 55ec25b0d09379eb11c32dbe09ee28c4 depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.4,<3.0a0 - libffi >=3.4,<4.0a0 - liblzma >=5.8.2,<6.0a0 - libsqlite >=3.51.2,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 + - openssl >=3.5.5,<4.0a0 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -5433,23 +5624,23 @@ packages: - python_abi 3.10.* *_cp310 license: Python-2.0 purls: [] - size: 12507955 - timestamp: 1769472053757 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda - build_number: 101 - sha256: fccce2af62d11328d232df9f6bbf63464fd45f81f718c661757f9c628c4378ce - md5: 753c8d0447677acb7ddbcc6e03e82661 + size: 12468674 + timestamp: 1772730636766 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.5-h4c637c5_100_cp314.conda + build_number: 100 + sha256: 06dec0e2f50e2f7e6a8808fcb4aff23729a3f23bcb1fca4fcbc3a341d9e38a83 + md5: f7331c9deaf21c79e5675e72b21d570b depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.8.0,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - libsqlite >=3.53.1,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - openssl >=3.5.6,<4.0a0 - python_abi 3.14.* *_cp314 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 @@ -5457,8 +5648,8 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 13522698 - timestamp: 1770675365241 + size: 13560854 + timestamp: 1779238292621 python_site_packages_path: lib/python3.14/site-packages - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl name: python-dateutil @@ -5497,10 +5688,10 @@ packages: purls: [] size: 6989 timestamp: 1752805904792 -- pypi: https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl name: pytz - version: 2026.1.post1 - sha256: f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a + version: '2026.2' + sha256: 04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 - pypi: https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl name: pyyaml version: 6.0.3 @@ -5789,10 +5980,10 @@ packages: - pandas>=1.3 ; extra == 'llm' - opentelemetry-proto ; extra == 'llm' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/64/13/b86d791b41f33220335eba18fc4841f1ebddae41e562c6a216846404c88d/ray-2.54.0-cp310-cp310-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/7e/d0/a85097dd53aaca1a44acc4dd0b3d2c0e9233179433e2ee326e4018ab3cf7/ray-2.55.1-cp310-cp310-macosx_12_0_arm64.whl name: ray - version: 2.54.0 - sha256: a22937f09ee74a43171df338d84b45ef882c1c05748947ca9d5343a44d4b9379 + version: 2.55.1 + sha256: 2d5786661e192148719accc959def6cdcabd7a24cd9008005bf3d0e3c8cfd529 requires_dist: - click>=7.0 - filelock @@ -5825,25 +6016,25 @@ packages: - smart-open ; extra == 'default' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'default' - memray ; sys_platform != 'win32' and extra == 'observability' - - fastapi ; extra == 'serve' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve' - - opencensus ; extra == 'serve' - - opentelemetry-proto ; extra == 'serve' - watchfiles ; extra == 'serve' - - starlette ; extra == 'serve' - - opentelemetry-sdk>=1.30.0 ; extra == 'serve' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve' - - aiohttp-cors ; extra == 'serve' + - opentelemetry-proto ; extra == 'serve' + - opencensus ; extra == 'serve' + - grpcio>=1.42.0 ; extra == 'serve' + - requests ; extra == 'serve' - aiohttp>=3.13.3 ; extra == 'serve' - colorful ; extra == 'serve' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve' + - opentelemetry-exporter-prometheus ; extra == 'serve' - prometheus-client>=0.7.1 ; extra == 'serve' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve' - - opentelemetry-exporter-prometheus ; extra == 'serve' - - uvicorn[standard] ; extra == 'serve' + - aiohttp-cors ; extra == 'serve' - smart-open ; extra == 'serve' - - requests ; extra == 'serve' - - grpcio>=1.42.0 ; extra == 'serve' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve' + - fastapi ; extra == 'serve' + - opentelemetry-sdk>=1.30.0 ; extra == 'serve' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve' + - starlette ; extra == 'serve' + - uvicorn[standard] ; extra == 'serve' - pandas ; extra == 'tune' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'tune' - tensorboardx>=1.9 ; extra == 'tune' @@ -5851,47 +6042,48 @@ packages: - pyarrow>=9.0.0 ; extra == 'tune' - fsspec ; extra == 'tune' - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'adag' - - fastapi ; extra == 'serve-grpc' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-grpc' - - opencensus ; extra == 'serve-grpc' - - opentelemetry-proto ; extra == 'serve-grpc' - watchfiles ; extra == 'serve-grpc' - - starlette ; extra == 'serve-grpc' - - opentelemetry-sdk>=1.30.0 ; extra == 'serve-grpc' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-grpc' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-grpc' - - aiohttp-cors ; extra == 'serve-grpc' + - opentelemetry-proto ; extra == 'serve-grpc' + - opencensus ; extra == 'serve-grpc' + - grpcio>=1.42.0 ; extra == 'serve-grpc' + - pyopenssl ; extra == 'serve-grpc' + - requests ; extra == 'serve-grpc' - aiohttp>=3.13.3 ; extra == 'serve-grpc' - colorful ; extra == 'serve-grpc' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-grpc' + - opentelemetry-exporter-prometheus ; extra == 'serve-grpc' - prometheus-client>=0.7.1 ; extra == 'serve-grpc' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-grpc' - - opentelemetry-exporter-prometheus ; extra == 'serve-grpc' - - uvicorn[standard] ; extra == 'serve-grpc' + - aiohttp-cors ; extra == 'serve-grpc' - smart-open ; extra == 'serve-grpc' - - requests ; extra == 'serve-grpc' - - grpcio>=1.42.0 ; extra == 'serve-grpc' - - pyopenssl ; extra == 'serve-grpc' - - fastapi ; extra == 'serve-async-inference' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-async-inference' - - opencensus ; extra == 'serve-async-inference' - - opentelemetry-proto ; extra == 'serve-async-inference' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-grpc' + - fastapi ; extra == 'serve-grpc' + - opentelemetry-sdk>=1.30.0 ; extra == 'serve-grpc' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-grpc' + - starlette ; extra == 'serve-grpc' + - uvicorn[standard] ; extra == 'serve-grpc' - watchfiles ; extra == 'serve-async-inference' - - starlette ; extra == 'serve-async-inference' - - opentelemetry-sdk>=1.30.0 ; extra == 'serve-async-inference' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-async-inference' - - celery ; extra == 'serve-async-inference' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-async-inference' - - aiohttp-cors ; extra == 'serve-async-inference' + - opentelemetry-proto ; extra == 'serve-async-inference' + - taskiq ; extra == 'serve-async-inference' + - opencensus ; extra == 'serve-async-inference' + - grpcio>=1.42.0 ; extra == 'serve-async-inference' + - requests ; extra == 'serve-async-inference' - aiohttp>=3.13.3 ; extra == 'serve-async-inference' - colorful ; extra == 'serve-async-inference' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-async-inference' + - opentelemetry-exporter-prometheus ; extra == 'serve-async-inference' - prometheus-client>=0.7.1 ; extra == 'serve-async-inference' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-async-inference' - - opentelemetry-exporter-prometheus ; extra == 'serve-async-inference' - - uvicorn[standard] ; extra == 'serve-async-inference' + - aiohttp-cors ; extra == 'serve-async-inference' - smart-open ; extra == 'serve-async-inference' - - requests ; extra == 'serve-async-inference' - - grpcio>=1.42.0 ; extra == 'serve-async-inference' - - ray-cpp==2.54.0 ; extra == 'cpp' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-async-inference' + - fastapi ; extra == 'serve-async-inference' + - opentelemetry-sdk>=1.30.0 ; extra == 'serve-async-inference' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-async-inference' + - starlette ; extra == 'serve-async-inference' + - uvicorn[standard] ; extra == 'serve-async-inference' + - celery ; extra == 'serve-async-inference' + - ray-cpp==2.55.1 ; extra == 'cpp' - pandas ; extra == 'rllib' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'rllib' - tensorboardx>=1.9 ; extra == 'rllib' @@ -5911,145 +6103,146 @@ packages: - pyarrow>=9.0.0 ; extra == 'train' - fsspec ; extra == 'train' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'train' - - fastapi ; extra == 'air' - - tensorboardx>=1.9 ; extra == 'air' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'air' - - numpy>=1.20 ; extra == 'air' - - pyarrow>=9.0.0 ; extra == 'air' - - opencensus ; extra == 'air' - - opentelemetry-proto ; extra == 'air' - watchfiles ; extra == 'air' - - starlette ; extra == 'air' - - opentelemetry-sdk>=1.30.0 ; extra == 'air' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'air' - - pandas ; extra == 'air' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'air' - fsspec ; extra == 'air' - - aiohttp-cors ; extra == 'air' + - tensorboardx>=1.9 ; extra == 'air' + - opentelemetry-proto ; extra == 'air' + - pandas>=1.3 ; extra == 'air' + - opencensus ; extra == 'air' + - grpcio>=1.42.0 ; extra == 'air' + - requests ; extra == 'air' - aiohttp>=3.13.3 ; extra == 'air' - colorful ; extra == 'air' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'air' + - opentelemetry-exporter-prometheus ; extra == 'air' - prometheus-client>=0.7.1 ; extra == 'air' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'air' - - opentelemetry-exporter-prometheus ; extra == 'air' - - uvicorn[standard] ; extra == 'air' + - aiohttp-cors ; extra == 'air' + - pyarrow>=9.0.0 ; extra == 'air' - smart-open ; extra == 'air' - - requests ; extra == 'air' - - grpcio>=1.42.0 ; extra == 'air' - - pandas>=1.3 ; extra == 'air' - - fastapi ; extra == 'all' - - scipy ; extra == 'all' - - dm-tree ; extra == 'all' - - tensorboardx>=1.9 ; extra == 'all' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all' - - numpy>=1.20 ; extra == 'all' - - pyarrow>=9.0.0 ; extra == 'all' - - pyyaml ; extra == 'all' - - ormsgpack>=1.7.0 ; extra == 'all' - - opencensus ; extra == 'all' - - opentelemetry-proto ; extra == 'all' + - pandas ; extra == 'air' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'air' + - numpy>=1.20 ; extra == 'air' + - fastapi ; extra == 'air' + - opentelemetry-sdk>=1.30.0 ; extra == 'air' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'air' + - starlette ; extra == 'air' + - uvicorn[standard] ; extra == 'air' - watchfiles ; extra == 'all' - - starlette ; extra == 'all' - - opentelemetry-sdk>=1.30.0 ; extra == 'all' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all' - - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all' - - celery ; extra == 'all' - grpcio ; extra == 'all' - - pandas ; extra == 'all' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all' + - gymnasium==1.2.2 ; extra == 'all' - fsspec ; extra == 'all' + - tensorboardx>=1.9 ; extra == 'all' + - opentelemetry-proto ; extra == 'all' + - pandas>=1.3 ; extra == 'all' + - taskiq ; extra == 'all' + - opencensus ; extra == 'all' + - grpcio>=1.42.0 ; extra == 'all' + - ormsgpack>=1.7.0 ; extra == 'all' + - pyopenssl ; extra == 'all' + - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all' + - requests ; extra == 'all' - aiohttp>=3.13.3 ; extra == 'all' - - aiohttp-cors ; extra == 'all' - colorful ; extra == 'all' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all' + - opentelemetry-exporter-prometheus ; extra == 'all' + - scipy ; extra == 'all' - prometheus-client>=0.7.1 ; extra == 'all' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'all' - - gymnasium==1.2.2 ; extra == 'all' - - lz4 ; extra == 'all' - - opentelemetry-exporter-prometheus ; extra == 'all' - - uvicorn[standard] ; extra == 'all' + - aiohttp-cors ; extra == 'all' + - pyarrow>=9.0.0 ; extra == 'all' - smart-open ; extra == 'all' - - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all' - - requests ; extra == 'all' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all' - memray ; sys_platform != 'win32' and extra == 'all' - - grpcio>=1.42.0 ; extra == 'all' - - pandas>=1.3 ; extra == 'all' - - pyopenssl ; extra == 'all' - - fastapi ; extra == 'all-cpp' - - scipy ; extra == 'all-cpp' - - dm-tree ; extra == 'all-cpp' - - tensorboardx>=1.9 ; extra == 'all-cpp' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all-cpp' - - numpy>=1.20 ; extra == 'all-cpp' - - pyarrow>=9.0.0 ; extra == 'all-cpp' - - pyyaml ; extra == 'all-cpp' - - ormsgpack>=1.7.0 ; extra == 'all-cpp' - - opencensus ; extra == 'all-cpp' - - opentelemetry-proto ; extra == 'all-cpp' + - pandas ; extra == 'all' + - pyyaml ; extra == 'all' + - numpy>=1.20 ; extra == 'all' + - fastapi ; extra == 'all' + - opentelemetry-sdk>=1.30.0 ; extra == 'all' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all' + - starlette ; extra == 'all' + - uvicorn[standard] ; extra == 'all' + - celery ; extra == 'all' + - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all' + - lz4 ; extra == 'all' + - dm-tree ; extra == 'all' - watchfiles ; extra == 'all-cpp' - - starlette ; extra == 'all-cpp' - - opentelemetry-sdk>=1.30.0 ; extra == 'all-cpp' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all-cpp' - - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all-cpp' - - celery ; extra == 'all-cpp' - grpcio ; extra == 'all-cpp' - - pandas ; extra == 'all-cpp' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all-cpp' + - gymnasium==1.2.2 ; extra == 'all-cpp' - fsspec ; extra == 'all-cpp' + - tensorboardx>=1.9 ; extra == 'all-cpp' + - opentelemetry-proto ; extra == 'all-cpp' + - pandas>=1.3 ; extra == 'all-cpp' + - taskiq ; extra == 'all-cpp' + - opencensus ; extra == 'all-cpp' + - grpcio>=1.42.0 ; extra == 'all-cpp' + - ormsgpack>=1.7.0 ; extra == 'all-cpp' + - pyopenssl ; extra == 'all-cpp' + - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all-cpp' + - requests ; extra == 'all-cpp' - aiohttp>=3.13.3 ; extra == 'all-cpp' - - aiohttp-cors ; extra == 'all-cpp' - colorful ; extra == 'all-cpp' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all-cpp' + - opentelemetry-exporter-prometheus ; extra == 'all-cpp' + - scipy ; extra == 'all-cpp' - prometheus-client>=0.7.1 ; extra == 'all-cpp' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'all-cpp' - - gymnasium==1.2.2 ; extra == 'all-cpp' - - lz4 ; extra == 'all-cpp' - - ray-cpp==2.54.0 ; extra == 'all-cpp' - - opentelemetry-exporter-prometheus ; extra == 'all-cpp' - - uvicorn[standard] ; extra == 'all-cpp' + - aiohttp-cors ; extra == 'all-cpp' + - pyarrow>=9.0.0 ; extra == 'all-cpp' - smart-open ; extra == 'all-cpp' - - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all-cpp' - - requests ; extra == 'all-cpp' + - ray-cpp==2.55.1 ; extra == 'all-cpp' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all-cpp' - memray ; sys_platform != 'win32' and extra == 'all-cpp' - - grpcio>=1.42.0 ; extra == 'all-cpp' - - pandas>=1.3 ; extra == 'all-cpp' - - pyopenssl ; extra == 'all-cpp' - - fastapi ; extra == 'llm' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'llm' - - numpy>=1.20 ; extra == 'llm' - - pyarrow>=9.0.0 ; extra == 'llm' - - typer ; extra == 'llm' - - opencensus ; extra == 'llm' - - opentelemetry-proto ; extra == 'llm' - - jsonschema ; extra == 'llm' + - pandas ; extra == 'all-cpp' + - pyyaml ; extra == 'all-cpp' + - numpy>=1.20 ; extra == 'all-cpp' + - fastapi ; extra == 'all-cpp' + - opentelemetry-sdk>=1.30.0 ; extra == 'all-cpp' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all-cpp' + - starlette ; extra == 'all-cpp' + - uvicorn[standard] ; extra == 'all-cpp' + - celery ; extra == 'all-cpp' + - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all-cpp' + - lz4 ; extra == 'all-cpp' + - dm-tree ; extra == 'all-cpp' - watchfiles ; extra == 'llm' - - meson ; extra == 'llm' - - vllm[audio]>=0.15.0 ; extra == 'llm' - - transformers>=4.57.3 ; extra == 'llm' - - starlette ; extra == 'llm' - - opentelemetry-sdk>=1.30.0 ; extra == 'llm' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'llm' - - hf-transfer ; extra == 'llm' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'llm' - fsspec ; extra == 'llm' - - aiohttp-cors ; extra == 'llm' - - aiohttp>=3.13.3 ; extra == 'llm' - - colorful ; extra == 'llm' + - opentelemetry-proto ; extra == 'llm' + - pandas>=1.3 ; extra == 'llm' - jsonref>=1.1.0 ; extra == 'llm' - - prometheus-client>=0.7.1 ; extra == 'llm' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'llm' - - nixl>=0.6.1 ; extra == 'llm' + - ninja ; extra == 'llm' + - nixl>=1.0.0 ; extra == 'llm' + - meson ; extra == 'llm' + - opencensus ; extra == 'llm' - async-timeout ; python_full_version < '3.11' and extra == 'llm' - pybind11 ; extra == 'llm' + - grpcio>=1.42.0 ; extra == 'llm' + - vllm[audio]>=0.18.0 ; extra == 'llm' + - requests ; extra == 'llm' + - typer ; extra == 'llm' + - aiohttp>=3.13.3 ; extra == 'llm' + - colorful ; extra == 'llm' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'llm' - opentelemetry-exporter-prometheus ; extra == 'llm' - - uvicorn[standard] ; extra == 'llm' + - prometheus-client>=0.7.1 ; extra == 'llm' + - jsonschema ; extra == 'llm' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'llm' + - aiohttp-cors ; extra == 'llm' + - hf-transfer ; extra == 'llm' + - pyarrow>=9.0.0 ; extra == 'llm' - smart-open ; extra == 'llm' - - requests ; extra == 'llm' - - ninja ; extra == 'llm' - - grpcio>=1.42.0 ; extra == 'llm' - - pandas>=1.3 ; extra == 'llm' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'llm' + - numpy>=1.20 ; extra == 'llm' + - fastapi ; extra == 'llm' + - opentelemetry-sdk>=1.30.0 ; extra == 'llm' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'llm' + - starlette ; extra == 'llm' + - uvicorn[standard] ; extra == 'llm' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b0/b1/8cc4e45a3ce87aabcb70696b448b20840bcbaa5c98bdb4807a2749541fda/ray-2.54.0-cp310-cp310-manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/b4/64/640f5525bac171282c6f76f3ecc9c4cfef60149ac0d00231afb22018ebe5/ray-2.55.1-cp310-cp310-manylinux2014_x86_64.whl name: ray - version: 2.54.0 - sha256: 2d140409e4ca06d8d6a06f71d441b53f6edcd930ebe67a6988f652915db81070 + version: 2.55.1 + sha256: bb49fbbe53a1d931e1f92d17f9271338f0b738885f8f70b7f531aa33f019d8af requires_dist: - click>=7.0 - filelock @@ -6082,25 +6275,25 @@ packages: - smart-open ; extra == 'default' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'default' - memray ; sys_platform != 'win32' and extra == 'observability' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve' + - colorful ; extra == 'serve' + - starlette ; extra == 'serve' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve' + - grpcio>=1.42.0 ; extra == 'serve' + - aiohttp-cors ; extra == 'serve' + - opentelemetry-exporter-prometheus ; extra == 'serve' + - prometheus-client>=0.7.1 ; extra == 'serve' - fastapi ; extra == 'serve' - - uvicorn[standard] ; extra == 'serve' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve' - opentelemetry-sdk>=1.30.0 ; extra == 'serve' + - requests ; extra == 'serve' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve' + - watchfiles ; extra == 'serve' + - uvicorn[standard] ; extra == 'serve' + - smart-open ; extra == 'serve' - opentelemetry-proto ; extra == 'serve' - aiohttp>=3.13.3 ; extra == 'serve' - - starlette ; extra == 'serve' - - smart-open ; extra == 'serve' - - aiohttp-cors ; extra == 'serve' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve' - opencensus ; extra == 'serve' - - requests ; extra == 'serve' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve' - - colorful ; extra == 'serve' - - prometheus-client>=0.7.1 ; extra == 'serve' - - watchfiles ; extra == 'serve' - - opentelemetry-exporter-prometheus ; extra == 'serve' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve' - - grpcio>=1.42.0 ; extra == 'serve' - pandas ; extra == 'tune' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'tune' - tensorboardx>=1.9 ; extra == 'tune' @@ -6108,47 +6301,48 @@ packages: - pyarrow>=9.0.0 ; extra == 'tune' - fsspec ; extra == 'tune' - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'adag' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-grpc' + - colorful ; extra == 'serve-grpc' + - starlette ; extra == 'serve-grpc' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-grpc' + - grpcio>=1.42.0 ; extra == 'serve-grpc' + - aiohttp-cors ; extra == 'serve-grpc' + - opentelemetry-exporter-prometheus ; extra == 'serve-grpc' + - prometheus-client>=0.7.1 ; extra == 'serve-grpc' + - pyopenssl ; extra == 'serve-grpc' - fastapi ; extra == 'serve-grpc' - - uvicorn[standard] ; extra == 'serve-grpc' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-grpc' - opentelemetry-sdk>=1.30.0 ; extra == 'serve-grpc' - - pyopenssl ; extra == 'serve-grpc' + - requests ; extra == 'serve-grpc' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-grpc' + - watchfiles ; extra == 'serve-grpc' + - uvicorn[standard] ; extra == 'serve-grpc' + - smart-open ; extra == 'serve-grpc' - opentelemetry-proto ; extra == 'serve-grpc' - aiohttp>=3.13.3 ; extra == 'serve-grpc' - - starlette ; extra == 'serve-grpc' - - smart-open ; extra == 'serve-grpc' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-grpc' - - requests ; extra == 'serve-grpc' - opencensus ; extra == 'serve-grpc' - - aiohttp-cors ; extra == 'serve-grpc' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-grpc' - - colorful ; extra == 'serve-grpc' - - prometheus-client>=0.7.1 ; extra == 'serve-grpc' - - watchfiles ; extra == 'serve-grpc' - - opentelemetry-exporter-prometheus ; extra == 'serve-grpc' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-grpc' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-grpc' - - grpcio>=1.42.0 ; extra == 'serve-grpc' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-async-inference' + - colorful ; extra == 'serve-async-inference' + - starlette ; extra == 'serve-async-inference' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-async-inference' + - grpcio>=1.42.0 ; extra == 'serve-async-inference' + - aiohttp-cors ; extra == 'serve-async-inference' + - opentelemetry-exporter-prometheus ; extra == 'serve-async-inference' + - celery ; extra == 'serve-async-inference' + - prometheus-client>=0.7.1 ; extra == 'serve-async-inference' - fastapi ; extra == 'serve-async-inference' - - uvicorn[standard] ; extra == 'serve-async-inference' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-async-inference' + - taskiq ; extra == 'serve-async-inference' - opentelemetry-sdk>=1.30.0 ; extra == 'serve-async-inference' + - requests ; extra == 'serve-async-inference' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-async-inference' + - watchfiles ; extra == 'serve-async-inference' + - uvicorn[standard] ; extra == 'serve-async-inference' + - smart-open ; extra == 'serve-async-inference' - opentelemetry-proto ; extra == 'serve-async-inference' - aiohttp>=3.13.3 ; extra == 'serve-async-inference' - - starlette ; extra == 'serve-async-inference' - - celery ; extra == 'serve-async-inference' - - smart-open ; extra == 'serve-async-inference' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'serve-async-inference' - - requests ; extra == 'serve-async-inference' - opencensus ; extra == 'serve-async-inference' - - aiohttp-cors ; extra == 'serve-async-inference' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'serve-async-inference' - - colorful ; extra == 'serve-async-inference' - - prometheus-client>=0.7.1 ; extra == 'serve-async-inference' - - watchfiles ; extra == 'serve-async-inference' - - opentelemetry-exporter-prometheus ; extra == 'serve-async-inference' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'serve-async-inference' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'serve-async-inference' - - grpcio>=1.42.0 ; extra == 'serve-async-inference' - - ray-cpp==2.54.0 ; extra == 'cpp' + - ray-cpp==2.55.1 ; extra == 'cpp' - pandas ; extra == 'rllib' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'rllib' - tensorboardx>=1.9 ; extra == 'rllib' @@ -6168,140 +6362,141 @@ packages: - pyarrow>=9.0.0 ; extra == 'train' - fsspec ; extra == 'train' - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'train' - - fastapi ; extra == 'air' - - uvicorn[standard] ; extra == 'air' - - opentelemetry-sdk>=1.30.0 ; extra == 'air' - - numpy>=1.20 ; extra == 'air' - - opentelemetry-proto ; extra == 'air' - - aiohttp>=3.13.3 ; extra == 'air' - - starlette ; extra == 'air' - pyarrow>=9.0.0 ; extra == 'air' + - fsspec ; extra == 'air' - tensorboardx>=1.9 ; extra == 'air' - - pandas>=1.3 ; extra == 'air' - - smart-open ; extra == 'air' - - aiohttp-cors ; extra == 'air' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'air' - - opencensus ; extra == 'air' - - requests ; extra == 'air' - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'air' - - pandas ; extra == 'air' - colorful ; extra == 'air' - - prometheus-client>=0.7.1 ; extra == 'air' - - watchfiles ; extra == 'air' - - opentelemetry-exporter-prometheus ; extra == 'air' - - fsspec ; extra == 'air' + - starlette ; extra == 'air' - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'air' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'air' - grpcio>=1.42.0 ; extra == 'air' - - fastapi ; extra == 'all' - - grpcio ; extra == 'all' - - uvicorn[standard] ; extra == 'all' - - opentelemetry-sdk>=1.30.0 ; extra == 'all' - - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all' - - ormsgpack>=1.7.0 ; extra == 'all' - - dm-tree ; extra == 'all' - - pyopenssl ; extra == 'all' - - numpy>=1.20 ; extra == 'all' - - opentelemetry-proto ; extra == 'all' - - aiohttp>=3.13.3 ; extra == 'all' - - pyyaml ; extra == 'all' - - starlette ; extra == 'all' + - numpy>=1.20 ; extra == 'air' + - aiohttp-cors ; extra == 'air' + - opentelemetry-exporter-prometheus ; extra == 'air' + - pandas>=1.3 ; extra == 'air' + - prometheus-client>=0.7.1 ; extra == 'air' + - pandas ; extra == 'air' + - fastapi ; extra == 'air' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'air' + - opentelemetry-sdk>=1.30.0 ; extra == 'air' + - requests ; extra == 'air' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'air' + - watchfiles ; extra == 'air' + - uvicorn[standard] ; extra == 'air' + - smart-open ; extra == 'air' + - opentelemetry-proto ; extra == 'air' + - aiohttp>=3.13.3 ; extra == 'air' + - opencensus ; extra == 'air' - pyarrow>=9.0.0 ; extra == 'all' + - fsspec ; extra == 'all' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all' - tensorboardx>=1.9 ; extra == 'all' + - ormsgpack>=1.7.0 ; extra == 'all' + - colorful ; extra == 'all' + - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all' + - pyyaml ; extra == 'all' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all' + - starlette ; extra == 'all' + - grpcio>=1.42.0 ; extra == 'all' + - numpy>=1.20 ; extra == 'all' + - aiohttp-cors ; extra == 'all' - memray ; sys_platform != 'win32' and extra == 'all' - - scipy ; extra == 'all' + - opentelemetry-exporter-prometheus ; extra == 'all' - pandas>=1.3 ; extra == 'all' + - scipy ; extra == 'all' - celery ; extra == 'all' - - smart-open ; extra == 'all' - - requests ; extra == 'all' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all' - - opencensus ; extra == 'all' - - aiohttp-cors ; extra == 'all' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all' - lz4 ; extra == 'all' - - pandas ; extra == 'all' - - colorful ; extra == 'all' - prometheus-client>=0.7.1 ; extra == 'all' + - pyopenssl ; extra == 'all' + - grpcio ; extra == 'all' + - pandas ; extra == 'all' + - fastapi ; extra == 'all' - gymnasium==1.2.2 ; extra == 'all' - - watchfiles ; extra == 'all' - - opentelemetry-exporter-prometheus ; extra == 'all' - - fsspec ; extra == 'all' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'all' + - taskiq ; extra == 'all' + - opentelemetry-sdk>=1.30.0 ; extra == 'all' + - requests ; extra == 'all' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all' + - dm-tree ; extra == 'all' + - watchfiles ; extra == 'all' + - smart-open ; extra == 'all' + - uvicorn[standard] ; extra == 'all' + - opentelemetry-proto ; extra == 'all' + - aiohttp>=3.13.3 ; extra == 'all' - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all' - - grpcio>=1.42.0 ; extra == 'all' - - fastapi ; extra == 'all-cpp' - - grpcio ; extra == 'all-cpp' - - uvicorn[standard] ; extra == 'all-cpp' - - opentelemetry-sdk>=1.30.0 ; extra == 'all-cpp' - - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all-cpp' + - opencensus ; extra == 'all' + - pyarrow>=9.0.0 ; extra == 'all-cpp' + - ray-cpp==2.55.1 ; extra == 'all-cpp' + - fsspec ; extra == 'all-cpp' + - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all-cpp' + - tensorboardx>=1.9 ; extra == 'all-cpp' - ormsgpack>=1.7.0 ; extra == 'all-cpp' - - dm-tree ; extra == 'all-cpp' - - pyopenssl ; extra == 'all-cpp' + - colorful ; extra == 'all-cpp' + - cupy-cuda12x ; sys_platform != 'darwin' and extra == 'all-cpp' - pyyaml ; extra == 'all-cpp' - - numpy>=1.20 ; extra == 'all-cpp' - - opentelemetry-proto ; extra == 'all-cpp' - - aiohttp>=3.13.3 ; extra == 'all-cpp' + - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all-cpp' - starlette ; extra == 'all-cpp' - - pyarrow>=9.0.0 ; extra == 'all-cpp' - - tensorboardx>=1.9 ; extra == 'all-cpp' + - grpcio>=1.42.0 ; extra == 'all-cpp' + - numpy>=1.20 ; extra == 'all-cpp' + - aiohttp-cors ; extra == 'all-cpp' - memray ; sys_platform != 'win32' and extra == 'all-cpp' - - scipy ; extra == 'all-cpp' + - opentelemetry-exporter-prometheus ; extra == 'all-cpp' - pandas>=1.3 ; extra == 'all-cpp' + - scipy ; extra == 'all-cpp' - celery ; extra == 'all-cpp' - - smart-open ; extra == 'all-cpp' - - requests ; extra == 'all-cpp' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all-cpp' - - opencensus ; extra == 'all-cpp' - - aiohttp-cors ; extra == 'all-cpp' - - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'all-cpp' - - ray-cpp==2.54.0 ; extra == 'all-cpp' - lz4 ; extra == 'all-cpp' - - pandas ; extra == 'all-cpp' - - colorful ; extra == 'all-cpp' - prometheus-client>=0.7.1 ; extra == 'all-cpp' + - pyopenssl ; extra == 'all-cpp' + - grpcio ; extra == 'all-cpp' + - pandas ; extra == 'all-cpp' + - fastapi ; extra == 'all-cpp' - gymnasium==1.2.2 ; extra == 'all-cpp' - - watchfiles ; extra == 'all-cpp' - - opentelemetry-exporter-prometheus ; extra == 'all-cpp' - - fsspec ; extra == 'all-cpp' - - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'all-cpp' - virtualenv>=20.0.24,!=20.21.1 ; extra == 'all-cpp' + - taskiq ; extra == 'all-cpp' + - opentelemetry-sdk>=1.30.0 ; extra == 'all-cpp' + - requests ; extra == 'all-cpp' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'all-cpp' + - dm-tree ; extra == 'all-cpp' + - watchfiles ; extra == 'all-cpp' + - smart-open ; extra == 'all-cpp' + - uvicorn[standard] ; extra == 'all-cpp' + - opentelemetry-proto ; extra == 'all-cpp' + - aiohttp>=3.13.3 ; extra == 'all-cpp' - grpcio!=1.56.0 ; sys_platform == 'darwin' and extra == 'all-cpp' - - grpcio>=1.42.0 ; extra == 'all-cpp' - - fastapi ; extra == 'llm' - - meson ; extra == 'llm' - - hf-transfer ; extra == 'llm' - - uvicorn[standard] ; extra == 'llm' - - opentelemetry-sdk>=1.30.0 ; extra == 'llm' - - numpy>=1.20 ; extra == 'llm' - - opentelemetry-proto ; extra == 'llm' - - aiohttp>=3.13.3 ; extra == 'llm' - - starlette ; extra == 'llm' + - opencensus ; extra == 'all-cpp' - pyarrow>=9.0.0 ; extra == 'llm' - - typer ; extra == 'llm' - - pandas>=1.3 ; extra == 'llm' - - smart-open ; extra == 'llm' - - aiohttp-cors ; extra == 'llm' - - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'llm' - - opencensus ; extra == 'llm' - - requests ; extra == 'llm' + - fsspec ; extra == 'llm' - py-spy>=0.2.0 ; python_full_version < '3.12' and extra == 'llm' - jsonref>=1.1.0 ; extra == 'llm' - - vllm[audio]>=0.15.0 ; extra == 'llm' - - ninja ; extra == 'llm' - - pybind11 ; extra == 'llm' - - transformers>=4.57.3 ; extra == 'llm' - - nixl>=0.6.1 ; extra == 'llm' - colorful ; extra == 'llm' - - prometheus-client>=0.7.1 ; extra == 'llm' - - async-timeout ; python_full_version < '3.11' and extra == 'llm' - - watchfiles ; extra == 'llm' - - opentelemetry-exporter-prometheus ; extra == 'llm' - - fsspec ; extra == 'llm' - - jsonschema ; extra == 'llm' + - starlette ; extra == 'llm' - py-spy>=0.4.0 ; python_full_version >= '3.12' and extra == 'llm' - - virtualenv>=20.0.24,!=20.21.1 ; extra == 'llm' - grpcio>=1.42.0 ; extra == 'llm' + - vllm[audio]>=0.18.0 ; extra == 'llm' + - numpy>=1.20 ; extra == 'llm' + - aiohttp-cors ; extra == 'llm' + - opentelemetry-exporter-prometheus ; extra == 'llm' + - pandas>=1.3 ; extra == 'llm' + - typer ; extra == 'llm' + - async-timeout ; python_full_version < '3.11' and extra == 'llm' + - prometheus-client>=0.7.1 ; extra == 'llm' + - hf-transfer ; extra == 'llm' + - fastapi ; extra == 'llm' + - nixl>=1.0.0 ; extra == 'llm' + - virtualenv>=20.0.24,!=20.21.1 ; extra == 'llm' + - jsonschema ; extra == 'llm' + - meson ; extra == 'llm' + - opentelemetry-sdk>=1.30.0 ; extra == 'llm' + - requests ; extra == 'llm' + - pydantic!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*,!=2.11.*,<3 ; extra == 'llm' + - watchfiles ; extra == 'llm' + - uvicorn[standard] ; extra == 'llm' + - smart-open ; extra == 'llm' + - ninja ; extra == 'llm' + - opentelemetry-proto ; extra == 'llm' + - pybind11 ; extra == 'llm' + - aiohttp>=3.13.3 ; extra == 'llm' + - opencensus ; extra == 'llm' requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 @@ -6337,19 +6532,23 @@ packages: purls: [] size: 313930 timestamp: 1765813902568 -- pypi: https://files.pythonhosted.org/packages/20/2e/409703d645363352a20c944f5d119bdae3eb3034051a53724a7c5fee12b8/redis-4.6.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/4a/2e/2677f3f93dae0497e7e33b6637302e7f3744efc553f34231183e32584885/redis-7.4.1-py3-none-any.whl name: redis - version: 4.6.0 - sha256: e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c + version: 7.4.1 + sha256: 1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 requires_dist: - - async-timeout>=4.0.2 ; python_full_version <= '3.11.2' - - importlib-metadata>=1.0 ; python_full_version < '3.8' - - typing-extensions ; python_full_version < '3.8' - - hiredis>=1.0.0 ; extra == 'hiredis' + - async-timeout>=4.0.3 ; python_full_version < '3.11.3' + - pybreaker>=1.4.0 ; extra == 'circuit-breaker' + - hiredis>=3.2.0 ; extra == 'hiredis' + - pyjwt>=2.13.0 ; extra == 'jwt' - cryptography>=36.0.1 ; extra == 'ocsp' - - pyopenssl==20.0.1 ; extra == 'ocsp' - - requests>=2.26.0 ; extra == 'ocsp' - requires_python: '>=3.7' + - pyopenssl>=20.0.1 ; extra == 'ocsp' + - requests>=2.31.0 ; extra == 'ocsp' + - opentelemetry-api>=1.39.1 ; extra == 'otel' + - opentelemetry-exporter-otlp-proto-http>=1.39.1 ; extra == 'otel' + - opentelemetry-sdk>=1.39.1 ; extra == 'otel' + - xxhash~=3.6.0 ; extra == 'xxhash' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl name: referencing version: 0.37.0 @@ -6359,18 +6558,18 @@ packages: - rpds-py>=0.7.0 - typing-extensions>=4.4.0 ; python_full_version < '3.13' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl name: requests - version: 2.32.5 - sha256: 2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 + version: 2.34.2 + sha256: 2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 requires_dist: - charset-normalizer>=2,<4 - idna>=2.5,<4 - - urllib3>=1.21.1,<3 - - certifi>=2017.4.17 + - urllib3>=1.26,<3 + - certifi>=2023.5.7 - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' - - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' - requires_python: '>=3.9' + - chardet>=3.0.2,<8 ; extra == 'use-chardet-on-py3' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl name: requests-oauthlib version: 2.0.0 @@ -6387,15 +6586,15 @@ packages: requires_dist: - requests>=2.0.1,<3.0.0 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl name: rich - version: 14.3.3 - sha256: 793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d + version: 15.0.0 + sha256: 33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb requires_dist: - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' - markdown-it-py>=2.2.0 - pygments>=2.13.0,<3.0.0 - requires_python: '>=3.8.0' + requires_python: '>=3.9.0' - pypi: https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl name: rpds-py version: 0.30.0 @@ -6406,45 +6605,38 @@ packages: version: 0.30.0 sha256: 4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl - name: rpds-py - version: 0.30.0 - sha256: ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: rpds-py version: 0.30.0 sha256: 0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/19/c8/d63bb75b68afe77b229e3021c6031bcaf01da5db5b0e69d0d10f9ba679a7/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: rpds-py - version: 0.30.0 - sha256: 68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + version: 2026.5.1 + sha256: 21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d4/6f/19c1918a4b590d8de87e712e4abe4b3875771eff60216fb6153cf6665c68/rpds_py-2026.5.1-cp314-cp314-macosx_10_12_x86_64.whl name: rpds-py - version: 0.30.0 - sha256: 47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl - name: rsa - version: 4.9.1 - sha256: 68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 - requires_dist: - - pyasn1>=0.1.3 - requires_python: '>=3.6,<4' -- pypi: https://files.pythonhosted.org/packages/6d/4f/d073e09df851cfa251ef7840007d04db3293a0482ce607d2b993926089be/s3transfer-0.13.1-py3-none-any.whl + version: 2026.5.1 + sha256: 1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e5/60/a06fe7da34eca79dacbf958a2ba0c6eea85bc2b29de20080bf40f72f66fa/rpds_py-2026.5.1-cp314-cp314-macosx_11_0_arm64.whl + name: rpds-py + version: 2026.5.1 + sha256: 413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/85/dd/904873250a6554fbae40cddbf9198e3cc37a2f1319d5e1a5ce82fe269c17/s3transfer-0.17.1-py3-none-any.whl name: s3transfer - version: 0.13.1 - sha256: a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 + version: 0.17.1 + sha256: 5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c requires_dist: - botocore>=1.37.4,<2.0a0 - botocore[crt]>=1.37.4,<2.0a0 ; extra == 'crt' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl name: setuptools - version: 82.0.0 - sha256: 70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0 + version: 82.0.1 + sha256: a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb requires_dist: - pytest>=6,!=8.1.* ; extra == 'test' - virtualenv>=13.0.0 ; extra == 'test' @@ -6485,7 +6677,6 @@ packages: - importlib-metadata>=6 ; python_full_version < '3.10' and extra == 'core' - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'core' - wheel>=0.43.0 ; extra == 'core' - - platformdirs>=4.2.2 ; extra == 'core' - jaraco-functools>=4 ; extra == 'core' - more-itertools ; extra == 'core' - pytest-checkdocs>=2.4 ; extra == 'check' @@ -6498,69 +6689,31 @@ packages: - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + name: shellingham + version: 1.5.4 + sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl name: six version: 1.17.0 sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/60/e6/30c4015e2712bf8bf83b54ddadeee0494b68ae6d0f6d49d9373f463305d4/snowflake_connector_python-4.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: snowflake-connector-python - version: 4.0.0 - sha256: 4106a66e770e564b3037457b7b01b15ca28aee61afb88560b664aa8af439b533 - requires_dist: - - asn1crypto>0.24.0,<2.0.0 - - cryptography>=3.1.0 - - pyopenssl>=22.0.0,<26.0.0 - - pyjwt<3.0.0 - - pytz - - requests<3.0.0 - - packaging - - charset-normalizer>=2,<4 - - idna>=2.5,<4 - - urllib3>=1.21.1,<2.0.0 ; python_full_version < '3.10' - - certifi>=2017.4.17 - - typing-extensions>=4.3,<5 - - filelock>=3.5,<4 - - sortedcontainers>=2.4.0 - - platformdirs>=2.6.0,<5.0.0 - - tomlkit - - boto3>=1.24 - - botocore>=1.24 - - boto3>=1.24 ; extra == 'boto' - - botocore>=1.24 ; extra == 'boto' - - cython ; extra == 'development' - - coverage ; extra == 'development' - - more-itertools ; extra == 'development' - - numpy<=2.2.4 ; extra == 'development' - - pendulum!=2.1.1 ; extra == 'development' - - pexpect ; extra == 'development' - - pytest<7.5.0 ; extra == 'development' - - pytest-cov ; extra == 'development' - - pytest-rerunfailures<16.0 ; extra == 'development' - - pytest-timeout ; extra == 'development' - - pytest-xdist ; extra == 'development' - - pytzdata ; extra == 'development' - - responses ; extra == 'development' - - pandas>=2.1.2,<3.0.0 ; extra == 'pandas' - - pyarrow ; extra == 'pandas' - - keyring>=23.1.0,<26.0.0 ; extra == 'secure-local-storage' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e4/75/f845ca5079a6b911023fa945dbf1bac0ed1c2f5967108b14440c740cb410/snowflake_connector_python-4.0.0-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/49/4d/7e6a9088381386b4cfae4c5d1d23ea0c3618ca694bc2290118737af59f36/snowflake_connector_python-4.6.0.tar.gz name: snowflake-connector-python - version: 4.0.0 - sha256: 2c3e0f6d103fe67c975550ed424f579d3e7ae503d56467e5549f3a1a1e0e8f24 + version: 4.6.0 + sha256: 06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 requires_dist: - asn1crypto>0.24.0,<2.0.0 - - cryptography>=3.1.0 - - pyopenssl>=22.0.0,<26.0.0 - - pyjwt<3.0.0 + - cryptography>=46.0.5 + - pyopenssl>=24.0.0 + - pyjwt>=2.10.1,<3.0.0 - pytz - - requests<3.0.0 + - requests>=2.32.4,<3.0.0 - packaging - charset-normalizer>=2,<4 - - idna>=2.5,<4 - - urllib3>=1.21.1,<2.0.0 ; python_full_version < '3.10' - - certifi>=2017.4.17 + - idna>=3.7,<4 + - certifi>=2024.7.4 - typing-extensions>=4.3,<5 - filelock>=3.5,<4 - sortedcontainers>=2.4.0 @@ -6572,37 +6725,39 @@ packages: - botocore>=1.24 ; extra == 'boto' - cython ; extra == 'development' - coverage ; extra == 'development' + - mitmproxy>=12.0.0 ; python_full_version >= '3.12' and extra == 'development' - more-itertools ; extra == 'development' - - numpy<=2.2.4 ; extra == 'development' + - numpy<=2.4.3 ; extra == 'development' - pendulum!=2.1.1 ; extra == 'development' - pexpect ; extra == 'development' - pytest<7.5.0 ; extra == 'development' + - pytest-asyncio ; extra == 'development' - pytest-cov ; extra == 'development' - pytest-rerunfailures<16.0 ; extra == 'development' - pytest-timeout ; extra == 'development' - pytest-xdist ; extra == 'development' - pytzdata ; extra == 'development' - responses ; extra == 'development' - - pandas>=2.1.2,<3.0.0 ; extra == 'pandas' - - pyarrow ; extra == 'pandas' + - pandas>=1.0.0,<3.0.0 ; python_full_version < '3.13' and extra == 'pandas' + - pandas>=2.1.2,<3.0.0 ; python_full_version >= '3.13' and extra == 'pandas' + - pyarrow>=14.0.1 ; extra == 'pandas' - keyring>=23.1.0,<26.0.0 ; extra == 'secure-local-storage' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fd/80/3a7e36a9e53beeb27c0599d2703f33bb812be931b469b154b08df0eeeaf5/snowflake_connector_python-4.0.0-cp310-cp310-macosx_11_0_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/74/19/996b45846fcc5f2015bd70ed98420b11c847c1b79b57b82b250e0a409f49/snowflake_connector_python-4.6.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: snowflake-connector-python - version: 4.0.0 - sha256: e8d5b66f283967c700fff2303ac5e52d1a3cf41990a634f121ac8b1f1cd9af10 + version: 4.6.0 + sha256: fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b requires_dist: - asn1crypto>0.24.0,<2.0.0 - - cryptography>=3.1.0 - - pyopenssl>=22.0.0,<26.0.0 - - pyjwt<3.0.0 + - cryptography>=46.0.5 + - pyopenssl>=24.0.0 + - pyjwt>=2.10.1,<3.0.0 - pytz - - requests<3.0.0 + - requests>=2.32.4,<3.0.0 - packaging - charset-normalizer>=2,<4 - - idna>=2.5,<4 - - urllib3>=1.21.1,<2.0.0 ; python_full_version < '3.10' - - certifi>=2017.4.17 + - idna>=3.7,<4 + - certifi>=2024.7.4 - typing-extensions>=4.3,<5 - filelock>=3.5,<4 - sortedcontainers>=2.4.0 @@ -6614,29 +6769,32 @@ packages: - botocore>=1.24 ; extra == 'boto' - cython ; extra == 'development' - coverage ; extra == 'development' + - mitmproxy>=12.0.0 ; python_full_version >= '3.12' and extra == 'development' - more-itertools ; extra == 'development' - - numpy<=2.2.4 ; extra == 'development' + - numpy<=2.4.3 ; extra == 'development' - pendulum!=2.1.1 ; extra == 'development' - pexpect ; extra == 'development' - pytest<7.5.0 ; extra == 'development' + - pytest-asyncio ; extra == 'development' - pytest-cov ; extra == 'development' - pytest-rerunfailures<16.0 ; extra == 'development' - pytest-timeout ; extra == 'development' - pytest-xdist ; extra == 'development' - pytzdata ; extra == 'development' - responses ; extra == 'development' - - pandas>=2.1.2,<3.0.0 ; extra == 'pandas' - - pyarrow ; extra == 'pandas' + - pandas>=1.0.0,<3.0.0 ; python_full_version < '3.13' and extra == 'pandas' + - pandas>=2.1.2,<3.0.0 ; python_full_version >= '3.13' and extra == 'pandas' + - pyarrow>=14.0.1 ; extra == 'pandas' - keyring>=23.1.0,<26.0.0 ; extra == 'secure-local-storage' - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl name: sortedcontainers version: 2.4.0 sha256: a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 -- pypi: https://files.pythonhosted.org/packages/46/2c/9664130905f03db57961b8980b05cab624afd114bf2be2576628a9f22da4/sqlalchemy-2.0.48-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/31/26/ef168b184a25701f9995e8fb7e503fafd7a99c1c77cda1bc1a26ea2ed486/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: sqlalchemy - version: 2.0.48 - sha256: a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 + version: 2.0.50 + sha256: 6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e requires_dist: - importlib-metadata ; python_full_version < '3.8' - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' @@ -6671,10 +6829,10 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/5c/ad/6c4395649a212a6c603a72c5b9ab5dce3135a1546cfdffa3c427e71fd535/sqlalchemy-2.0.48-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/70/a9/812a775bd8c1af0966d660238d005baf25e9bced1f038c8e71f00aa637a7/sqlalchemy-2.0.50-cp310-cp310-macosx_11_0_arm64.whl name: sqlalchemy - version: 2.0.48 - sha256: 10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd + version: 2.0.50 + sha256: 7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 requires_dist: - importlib-metadata ; python_full_version < '3.8' - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' @@ -6709,10 +6867,10 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/9a/67/1235676e93dd3b742a4a8eddfae49eea46c85e3eed29f0da446a8dd57500/sqlalchemy-2.0.48-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/81/55/b260d8df2adc9bb0bf294f67b5f802ff0d84d99442b536b9efd0ea72d447/sqlalchemy-2.0.50-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: sqlalchemy - version: 2.0.48 - sha256: 7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 + version: 2.0.50 + sha256: e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 requires_dist: - importlib-metadata ; python_full_version < '3.8' - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' @@ -6747,10 +6905,10 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/f2/5e/327428a034407651a048f5e624361adf3f9fbac9d0fa98e981e9c6ff2f5e/sqlalchemy-2.0.48-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl name: sqlalchemy - version: 2.0.48 - sha256: 426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b + version: 2.0.50 + sha256: 92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 requires_dist: - importlib-metadata ; python_full_version < '3.8' - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' @@ -6785,10 +6943,10 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/f7/b3/f437eaa1cf028bb3c927172c7272366393e73ccd104dcf5b6963f4ab5318/sqlalchemy-2.0.48-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/df/32/10ac51b4be7cdecd7e93d069251c86dfbf70b7adbd7c67b48ccea6c49e1c/sqlalchemy-2.0.50-cp314-cp314-macosx_11_0_arm64.whl name: sqlalchemy - version: 2.0.48 - sha256: e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd + version: 2.0.50 + sha256: c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 requires_dist: - importlib-metadata ; python_full_version < '3.8' - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' @@ -6823,31 +6981,34 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/ad/c9/f58c3a17beb650700f9d2eccd410726b6d96df8953663700764ca48636c7/sqlglot-29.0.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/13/4c/41b222c130950a077e1a0ba311df84a29b818db7c136ecc1aafbfad42e26/sqlglot-30.9.0-py3-none-any.whl name: sqlglot - version: 29.0.1 - sha256: 06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 + version: 30.9.0 + sha256: 59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 requires_dist: - duckdb>=0.6 ; extra == 'dev' - - mypy ; extra == 'dev' + - sqlglot-mypy>=2.1.0.post2 ; python_full_version >= '3.10' and extra == 'dev' + - mypy ; python_full_version < '3.10' and extra == 'dev' + - setuptools-scm ; extra == 'dev' - pandas ; extra == 'dev' - pandas-stubs ; extra == 'dev' - python-dateutil ; extra == 'dev' - pytz ; extra == 'dev' - pdoc ; extra == 'dev' - pre-commit ; extra == 'dev' - - ruff==0.7.2 ; extra == 'dev' + - ruff==0.15.6 ; extra == 'dev' - types-python-dateutil ; extra == 'dev' - types-pytz ; extra == 'dev' - typing-extensions ; extra == 'dev' - pyperf ; extra == 'dev' - - sqlglotc ; extra == 'c' + - sqlglotc==30.9.0 ; python_full_version >= '3.10' and extra == 'c' - sqlglotrs==0.13.0 ; extra == 'rs' + - sqlglotc==30.9.0 ; python_full_version >= '3.10' and extra == 'rs' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl name: starlette - version: 0.52.1 - sha256: 0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 + version: 1.2.1 + sha256: 4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 requires_dist: - anyio>=3.6.2,<5 - typing-extensions>=4.10.0 ; python_full_version < '3.13' @@ -6857,13 +7018,13 @@ packages: - python-multipart>=0.0.18 ; extra == 'full' - pyyaml ; extra == 'full' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl name: tabulate - version: 0.9.0 - sha256: 024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f + version: 0.10.0 + sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 requires_dist: - wcwidth ; extra == 'widechars' - requires_python: '>=3.7' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl name: tenacity version: 8.5.0 @@ -6875,50 +7036,62 @@ packages: - tornado>=4.5 ; extra == 'test' - typeguard ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/3e/f8/6425ff800894784160290bcb9737878d910b6da6a08633bfe7f2ed8c9ae3/testcontainers-4.9.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/1f/f5/5983f2e45474660a0c90976d23d23cdfeedef28283f9ddd62f1d7ceb0d1d/testcontainers-4.15.0rc3-py3-none-any.whl name: testcontainers - version: 4.9.0 - sha256: c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 - requires_dist: - - azure-cosmos ; extra == 'cosmosdb' - - azure-storage-blob>=12.19,<13.0 ; extra == 'azurite' - - bcrypt ; extra == 'registry' - - boto3 ; extra == 'aws' or extra == 'localstack' - - cassandra-driver==3.29.1 ; extra == 'scylla' - - chromadb-client ; extra == 'chroma' - - clickhouse-driver ; extra == 'clickhouse' - - cryptography ; extra == 'mailpit' or extra == 'sftp' + version: 4.15.0rc3 + sha256: 2a9dad9a10ef1aff91c3df43b7387768ed16616d83bc591b92cefd54d3426faf + requires_dist: - docker - - google-cloud-datastore>=2 ; extra == 'google' - - google-cloud-pubsub>=2 ; extra == 'google' - - httpx ; extra == 'aws' or extra == 'generic' or extra == 'test-module-import' - - ibm-db-sa ; extra == 'db2' - - influxdb ; extra == 'influxdb' - - influxdb-client ; extra == 'influxdb' - - kubernetes ; extra == 'k3s' - - minio ; extra == 'minio' - - nats-py ; extra == 'nats' - - neo4j ; extra == 'neo4j' - - opensearch-py ; extra == 'opensearch' - - oracledb ; extra == 'oracle' or extra == 'oracle-free' - - pika ; extra == 'rabbitmq' - - pymongo ; extra == 'mongodb' - - pymssql ; extra == 'mssql' - - pymysql[rsa] ; extra == 'mysql' - - python-arango>=7.8,<8.0 ; extra == 'arangodb' - python-dotenv - - python-keycloak ; extra == 'keycloak' - - pyyaml ; extra == 'k3s' - - qdrant-client ; extra == 'qdrant' - - redis ; extra == 'generic' or extra == 'redis' - - selenium ; extra == 'selenium' - - sqlalchemy ; extra == 'db2' or extra == 'mssql' or extra == 'mysql' or extra == 'oracle' or extra == 'oracle-free' - - trino ; extra == 'trino' - typing-extensions - urllib3 - - weaviate-client>=4.5.4,<5.0.0 ; extra == 'weaviate' - wrapt - requires_python: '>=3.9,<4.0' + - python-arango>=8 ; extra == 'arangodb' + - boto3>=1 ; extra == 'aws' + - httpx ; extra == 'aws' + - azure-storage-blob>=12 ; extra == 'azurite' + - chromadb-client>=1 ; extra == 'chroma' + - clickhouse-driver ; extra == 'clickhouse' + - azure-cosmos>=4 ; extra == 'cosmosdb' + - ibm-db-sa ; platform_machine != 'aarch64' and platform_machine != 'arm64' and extra == 'db2' + - sqlalchemy>=2 ; extra == 'db2' + - httpx ; extra == 'generic' + - redis>=7 ; extra == 'generic' + - sqlalchemy ; extra == 'generic' + - google-cloud-datastore>=2 ; extra == 'google' + - google-cloud-pubsub>=2 ; extra == 'google' + - influxdb-client>=1 ; extra == 'influxdb' + - influxdb>=5 ; extra == 'influxdb' + - kubernetes ; extra == 'k3s' + - pyyaml>=6.0.3 ; extra == 'k3s' + - python-keycloak>=6 ; python_full_version < '4' and extra == 'keycloak' + - boto3>=1 ; extra == 'localstack' + - cryptography ; extra == 'mailpit' + - minio>=7 ; extra == 'minio' + - pymongo>=4 ; extra == 'mongodb' + - pymssql>=2 ; extra == 'mssql' + - sqlalchemy>=2 ; extra == 'mssql' + - pymysql[rsa]>=1 ; extra == 'mysql' + - sqlalchemy>=2 ; extra == 'mysql' + - nats-py>=2 ; extra == 'nats' + - neo4j>=6 ; extra == 'neo4j' + - openfga-sdk ; extra == 'openfga' + - opensearch-py>=3 ; python_full_version < '4' and extra == 'opensearch' + - oracledb>=3 ; extra == 'oracle' + - sqlalchemy>=2 ; extra == 'oracle' + - oracledb>=3 ; extra == 'oracle-free' + - sqlalchemy>=2 ; extra == 'oracle-free' + - qdrant-client>=1 ; extra == 'qdrant' + - pika>=1 ; extra == 'rabbitmq' + - redis>=7 ; extra == 'redis' + - bcrypt>=5 ; extra == 'registry' + - cassandra-driver>=3 ; python_full_version < '3.14' and extra == 'scylla' + - selenium>=4 ; extra == 'selenium' + - cryptography ; extra == 'sftp' + - httpx ; extra == 'test-module-import' + - trino ; extra == 'trino' + - weaviate-client>=4 ; extra == 'weaviate' + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac md5: cffd3bdd58090148f4cfcd831f4b26ab @@ -6960,25 +7133,25 @@ packages: version: 0.10.2 sha256: 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b requires_python: '>=2.6,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl name: tomli - version: 2.4.0 - sha256: 1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a + version: 2.4.1 + sha256: 0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl name: tomlkit - version: 0.14.0 - sha256: 592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 + version: 0.15.0 + sha256: 4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl name: toolz version: 1.1.0 sha256: 15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c2/51/ab57af723f38a041c5027040fc6fa93a9a066ca7294fc380c1c0810813b2/tqdm-4.68.0-py3-none-any.whl name: tqdm - version: 4.67.3 - sha256: ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf + version: 4.68.0 + sha256: b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 requires_dist: - colorama ; sys_platform == 'win32' - importlib-metadata ; python_full_version < '3.8' @@ -6988,23 +7161,36 @@ packages: - pytest-asyncio>=0.24 ; extra == 'dev' - nbval ; extra == 'dev' - requests ; extra == 'discord' + - envwrap ; extra == 'discord' - slack-sdk ; extra == 'slack' + - envwrap ; extra == 'slack' - requests ; extra == 'telegram' + - envwrap ; extra == 'telegram' - ipywidgets>=6 ; extra == 'notebook' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/5b/29/74eeb4d3f3ae61ca096b018ad486b3b3c74b17bec09ab4edab721cbefec3/typeguard-4.5.2-py3-none-any.whl name: typeguard - version: 4.5.1 - sha256: 44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 + version: 4.5.2 + sha256: fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf requires_dist: - importlib-metadata>=3.6 ; python_full_version < '3.10' - typing-extensions>=4.14.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/8b/fa/4f4d3bfca9ef6dd17d69ed18b96564c53b32d3ce774132308d0bee849f10/types_pymysql-1.1.0.20251220-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + name: typer + version: 0.25.1 + sha256: 75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 + requires_dist: + - click>=8.2.1 + - shellingham>=1.3.0 + - rich>=13.8.0 + - annotated-doc>=0.0.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b1/5a/db02b5e6633fbe49eaf4e3194bc64ec031e6436a0cfcc610cbda4f1b6a24/types_pymysql-1.1.0.20260518-py3-none-any.whl name: types-pymysql - version: 1.1.0.20251220 - sha256: fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 - requires_python: '>=3.9' + version: 1.1.0.20260518 + sha256: cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl name: typing-extensions version: 4.15.0 @@ -7017,10 +7203,10 @@ packages: requires_dist: - typing-extensions>=4.12.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl name: tzdata - version: '2025.3' - sha256: 06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 + version: '2026.2' + sha256: bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 requires_python: '>=2' - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c @@ -7029,17 +7215,17 @@ packages: purls: [] size: 119135 timestamp: 1767016325805 -- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl name: urllib3 - version: 2.6.3 - sha256: bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 + version: 2.7.0 + sha256: 9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 requires_dist: - brotli>=1.2.0 ; platform_python_implementation == 'CPython' and extra == 'brotli' - brotlicffi>=1.2.0.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' - h2>=4,<5 ; extra == 'h2' - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl name: uvicorn version: 0.34.0 @@ -7166,48 +7352,48 @@ packages: - sphinxcontrib-asyncio~=0.3.0 ; extra == 'docs' - sphinx-rtd-theme~=0.5.2 ; extra == 'docs' requires_python: '>=3.8.1' -- pypi: https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/02/c8/79eee650c62d2c186598489814468e389b5def0ebe755399ff645b35b1b2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: watchfiles - version: 1.1.1 - sha256: 39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd + version: 1.2.0 + sha256: b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a7/1a/206e8cf2dd86fddf939165a57b4df61607a1e0add2785f170a3f616b7d9f/watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/0d/5a/2bf22ecb24916983bf1cc0095e7dea2741d14d6553b0d6a2ac8bc96eca93/watchfiles-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl name: watchfiles - version: 1.1.1 - sha256: eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c + version: 1.2.0 + sha256: bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b3/0f/abaf5262b9c496b5dad4ed3c0e799cbecb1f8ea512ecb6ddd46646a9fca3/watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/55/70/dea1f6a0e76607841a60fb51af150e70124864673f61704abb62b90cdcc7/watchfiles-1.2.0-cp310-cp310-macosx_11_0_arm64.whl name: watchfiles - version: 1.1.1 - sha256: 03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 + version: 1.2.0 + sha256: c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7c/8a/3076c496ca8dafe0e8cd03fcebdfc47be4b1174b4e5b24ff6e396e6b3af2/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: watchfiles - version: 1.1.1 - sha256: 5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 + version: 1.2.0 + sha256: 054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/aa/5d/c9ab3534374a4a67450696905d6ef16a04405448b8dc52bd752ae50423d4/watchfiles-1.2.0-cp314-cp314-macosx_11_0_arm64.whl name: watchfiles - version: 1.1.1 - sha256: d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 + version: 1.2.0 + sha256: 9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d5/dc/1a680b7458ffa3b14bb64878112aefc8f2e4f73c5af763cbf0bd43100658/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e7/54/a9c7ea9a82a4ac65e7004c0a03920b5cdd2f9c3b678757d9cd425aa51d53/watchfiles-1.2.0-cp314-cp314-macosx_10_12_x86_64.whl name: watchfiles - version: 1.1.1 - sha256: 544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab + version: 1.2.0 + sha256: b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 requires_dist: - anyio>=3.0.0 - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl name: websockets version: '16.0' @@ -7238,76 +7424,76 @@ packages: version: '16.0' sha256: daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/94/c2/3d186944aae923631d1def58f4c4ff8f0b6309906afc0b6978de3e69b3e0/wrapt-2.2.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: wrapt - version: 1.17.3 - sha256: e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl - name: wrapt - version: 1.17.3 - sha256: fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: wrapt - version: 1.17.3 - sha256: f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/25/e9/96dd77728b54a899d4ce2798d7b1296989ce687ed3c0cb917d6b3154bf5d/wrapt-2.1.1-cp310-cp310-macosx_11_0_arm64.whl - name: wrapt - version: 2.1.1 - sha256: e1c99544b6a7d40ca22195563b6d8bc3986ee8bb82f272f31f0670fe9440c869 + version: 2.2.1 + sha256: 036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 requires_dist: - pytest ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/44/79/4c755b45df6ef30c0dd628ecfaa0c808854be147ca438429da70a162833c/wrapt-2.1.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/b4/8b/84bc1ea68b620fe0e2696a8cff07e82f4b962d952ab14efee8955997bb70/wrapt-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl name: wrapt - version: 2.1.1 - sha256: b2be3fa5f4efaf16ee7c77d0556abca35f5a18ad4ac06f0ef3904c3399010ce9 + version: 2.2.1 + sha256: 0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae requires_dist: - pytest ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ca/21/293b657a27accfbbbb6007ebd78af0efa2083dac83e8f523272ea09b4638/wrapt-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/f3/8f/64ec81194a0bc708d9720174c998c8a32116e82b5b32c04e20a7fe01176c/wrapt-2.2.1-cp310-cp310-macosx_11_0_arm64.whl name: wrapt - version: 2.1.1 - sha256: 7e927375e43fd5a985b27a8992327c22541b6dede1362fc79df337d26e23604f + version: 2.2.1 + sha256: e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a requires_dist: - pytest ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/07/61/40f0155b0b09988eb6cdbfc52652f2f371810b0c58163208cb05667757bd/xxhash-3.7.0-cp310-cp310-macosx_11_0_arm64.whl + name: xxhash + version: 3.7.0 + sha256: 85f5c0e26d945b5bb475e0a3d95193117498130baa7619357bdc7869c2391b5a + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/92/49/e4b575b4ed170a7f640c8bd69cfadfa81c7b700191fde5e72228762b9f73/xxhash-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl + name: xxhash + version: 3.7.0 + sha256: cd8ab85c916a58d5c8656ea15e3ce9df836fe2f120a74c296e01d69fab2614b4 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/a4/db/268012153eb7f6bf2c8a0491fdcde11e093f166990821a2ab754fe95537d/xxhash-3.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: xxhash + version: 3.7.0 + sha256: 12c249621af6d50a05d9f10af894b404157b15819878e18f75fcbb0213a77d07 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/02/ad/0b9cc9f38a7324a7eb1d80f834eaa5283d17e9271bbda3186e598dddaeac/yarl-1.24.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: yarl - version: 1.23.0 - sha256: 31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 + version: 1.24.2 + sha256: f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/48/41/7daafb32dd7562bf45b1ce56562e7e1a9146f6479b6456873eb8a3413c40/yarl-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl name: yarl - version: 1.23.0 - sha256: 2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 + version: 1.24.2 + sha256: 7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/a8/8f/7b3ec212f1ea0683f55f978e3246bc313c38818664edfc97a9f349a4901e/yarl-1.24.2-cp310-cp310-macosx_11_0_arm64.whl name: yarl - version: 1.23.0 - sha256: e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d + version: 1.24.2 + sha256: 15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl name: zipp - version: 3.23.0 - sha256: 071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e + version: 4.1.0 + sha256: 25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f requires_dist: - pytest>=6,!=8.1.* ; extra == 'test' - jaraco-itertools ; extra == 'test' @@ -7322,12 +7508,12 @@ packages: - furo ; extra == 'doc' - sphinx-lint ; extra == 'doc' - jaraco-tidelift>=1.4 ; extra == 'doc' - - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-checkdocs>=2.14 ; extra == 'check' - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' - requires_python: '>=3.9' + - pytest-enabler>=3.4 ; extra == 'enabler' + - pytest-mypy>=1.0.1 ; platform_python_implementation != 'PyPy' and extra == 'type' + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 diff --git a/protos/feast/core/DataSource.proto b/protos/feast/core/DataSource.proto index b91296dca31..2889fba042f 100644 --- a/protos/feast/core/DataSource.proto +++ b/protos/feast/core/DataSource.proto @@ -29,7 +29,7 @@ import "feast/types/Value.proto"; import "feast/core/Feature.proto"; // Defines a Data Source that can be used source Feature data -// Next available id: 28 +// Next available id: 29 message DataSource { // Field indexes should *not* be reused. Not sure if fields 6-10 were used previously or not, // but they are going to be reserved for backwards compatibility. @@ -81,6 +81,10 @@ message DataSource { // Must specify creation timestamp column name string created_timestamp_column = 5; + // (Optional) Type of the timestamp_field column ("TIMESTAMP" or "DATE"). + // When set to "DATE", SQL generation uses date-only comparisons. + string timestamp_field_type = 28; + // This is an internal field that is represents the python class for the data source object a proto object represents. // This should be set by feast, and not by users. // The field is used primarily by custom data sources and is mandatory for them to set. Feast may set it for diff --git a/protos/feast/core/FeatureService.proto b/protos/feast/core/FeatureService.proto index 380b2dc3718..557782fe552 100644 --- a/protos/feast/core/FeatureService.proto +++ b/protos/feast/core/FeatureService.proto @@ -38,6 +38,10 @@ message FeatureServiceSpec { // (optional) if provided logging will be enabled for this feature service. LoggingConfig logging_config = 7; + + // When true, a pre-computed feature vector is maintained per entity for this + // service, enabling single-read online retrieval instead of per-feature-view reads. + bool precompute_online = 8; } diff --git a/protos/feast/core/FeatureView.proto b/protos/feast/core/FeatureView.proto index 66dc4c3de6f..e9fab625bb4 100644 --- a/protos/feast/core/FeatureView.proto +++ b/protos/feast/core/FeatureView.proto @@ -28,6 +28,26 @@ import "feast/core/DataSource.proto"; import "feast/core/Feature.proto"; import "feast/core/Transformation.proto"; +// Lifecycle state of a feature view. +enum FeatureViewState { + // Default value for backward compatibility. Treated as AVAILABLE_ONLINE + // for existing feature views that predate the state machine. + STATE_UNSPECIFIED = 0; + + // Feature view has been registered via feast apply but no data is available. + CREATED = 1; + + // Feature engineering / offline data generation is complete. + // The feature view is ready to be materialized. + GENERATED = 2; + + // Materialization is currently in progress. + MATERIALIZING = 3; + + // Materialization completed. Features are available in the online store. + AVAILABLE_ONLINE = 4; +} + message FeatureView { // User-specified specifications of this feature view. FeatureViewSpec spec = 1; @@ -36,7 +56,7 @@ message FeatureView { FeatureViewMeta meta = 2; } -// Next available id: 18 +// Next available id: 20 // TODO(adchia): refactor common fields from this and ODFV into separate metadata proto message FeatureViewSpec { // Name of the feature view. Must be unique. Not updated. @@ -94,6 +114,17 @@ message FeatureViewSpec { // Whether schema validation is enabled during materialization bool enable_validation = 17; + + // User-specified version pin (e.g. "latest", "v2", "version2") + string version = 18; + + // Organizational unit that owns this feature view (e.g. "ads", "search"). + string org = 19; + + // Whether this feature view is disabled for serving and materialization. + // When true, the feature view will not serve online features or be materialized. + // Defaults to false (enabled) for backward compatibility. + bool disabled = 20; } message FeatureViewMeta { @@ -105,6 +136,15 @@ message FeatureViewMeta { // List of pairs (start_time, end_time) for which this feature view has been materialized. repeated MaterializationInterval materialization_intervals = 3; + + // The current version number of this feature view in the version history. + int32 current_version_number = 4; + + // Auto-generated UUID identifying this specific version. + string version_id = 5; + + // Lifecycle state of this feature view. + FeatureViewState state = 6; } message MaterializationInterval { diff --git a/protos/feast/core/FeatureViewProjection.proto b/protos/feast/core/FeatureViewProjection.proto index b0e697b656f..a130eb96ad2 100644 --- a/protos/feast/core/FeatureViewProjection.proto +++ b/protos/feast/core/FeatureViewProjection.proto @@ -32,4 +32,11 @@ message FeatureViewProjection { // Streaming DataSource from where this view can consume "online" feature data. DataSource stream_source = 9; + // Optional version tag for version-qualified feature references (e.g., @v2). + optional int32 version_tag = 10; + + // Distinguishes the source view type (e.g., "featureView", "labelView"). + // Empty string or unset means "featureView" for backward compatibility. + string view_type = 11; + } diff --git a/protos/feast/core/FeatureViewVersion.proto b/protos/feast/core/FeatureViewVersion.proto new file mode 100644 index 00000000000..c88a43eea80 --- /dev/null +++ b/protos/feast/core/FeatureViewVersion.proto @@ -0,0 +1,42 @@ +// +// Copyright 2024 The Feast Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; +package feast.core; + +option go_package = "github.com/feast-dev/feast/go/protos/feast/core"; +option java_outer_classname = "FeatureViewVersionProto"; +option java_package = "feast.proto.core"; + +import "google/protobuf/timestamp.proto"; + +message FeatureViewVersionRecord { + string feature_view_name = 1; + string project_id = 2; + int32 version_number = 3; + // "feature_view" | "stream_feature_view" | "on_demand_feature_view" + string feature_view_type = 4; + // serialized FV proto snapshot + bytes feature_view_proto = 5; + google.protobuf.Timestamp created_timestamp = 6; + string description = 7; + // auto-generated UUID for unique identification + string version_id = 8; +} + +message FeatureViewVersionHistory { + repeated FeatureViewVersionRecord records = 1; +} diff --git a/protos/feast/core/LabelView.proto b/protos/feast/core/LabelView.proto new file mode 100644 index 00000000000..8d2ff2abcf5 --- /dev/null +++ b/protos/feast/core/LabelView.proto @@ -0,0 +1,96 @@ +// +// Copyright 2026 The Feast Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; +package feast.core; + +option go_package = "github.com/feast-dev/feast/go/protos/feast/core"; +option java_outer_classname = "LabelViewProto"; +option java_package = "feast.proto.core"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "feast/core/DataSource.proto"; +import "feast/core/Feature.proto"; + +message LabelView { + LabelViewSpec spec = 1; + LabelViewMeta meta = 2; +} + +enum ConflictResolutionPolicy { + LAST_WRITE_WINS = 0; + LABELER_PRIORITY = 1; + MAJORITY_VOTE = 2; +} + +// Next available id: 16 +message LabelViewSpec { + // Name of the label view. Must be unique. Not updated. + string name = 1; + + // Name of Feast project that this label view belongs to. + string project = 2; + + // List of names of entities associated with this label view. + repeated string entities = 3; + + // List of specifications for each label field defined as part of this label view. + repeated FeatureSpecV2 features = 4; + + // User defined metadata. + map tags = 5; + + // Labels older than ttl will be excluded from online serving. + google.protobuf.Duration ttl = 6; + + // DataSource (typically a PushSource) that feeds label data into this view. + DataSource source = 7; + + // Whether labels should be served from the online store. + bool online = 8; + + // Description of the label view. + string description = 9; + + // Owner of the label view. + string owner = 10; + + // List of specifications for each entity column. + repeated FeatureSpecV2 entity_columns = 11; + + // The schema field that identifies the labeler (e.g. "labeler"). + string labeler_field = 12; + + // How conflicting labels from different labelers are resolved. + // Enforced for offline store reads; online store uses LAST_WRITE_WINS. + ConflictResolutionPolicy conflict_policy = 13; + + // DEPRECATED: retain_history is always true (offline store always appends). + // Field kept for backwards wire compatibility; ignored by the SDK. + bool retain_history = 14 [deprecated = true]; + + // Optional name of the FeatureView whose entities this label view annotates. + string reference_feature_view = 15; +} + +message LabelViewMeta { + // Time when this Label View was created. + google.protobuf.Timestamp created_timestamp = 1; + + // Time when this Label View was last updated. + google.protobuf.Timestamp last_updated_timestamp = 2; +} diff --git a/protos/feast/core/OnDemandFeatureView.proto b/protos/feast/core/OnDemandFeatureView.proto index 4b8dabb4f39..47372af15b2 100644 --- a/protos/feast/core/OnDemandFeatureView.proto +++ b/protos/feast/core/OnDemandFeatureView.proto @@ -36,7 +36,7 @@ message OnDemandFeatureView { OnDemandFeatureViewMeta meta = 2; } -// Next available id: 9 +// Next available id: 19 message OnDemandFeatureViewSpec { // Name of the feature view. Must be unique. Not updated. string name = 1; @@ -75,6 +75,16 @@ message OnDemandFeatureViewSpec { // Aggregation definitions repeated Aggregation aggregations = 16; + // User-specified version pin (e.g. "latest", "v2", "version2") + string version = 17; + + // Organizational unit that owns this feature view (e.g. "ads", "search"). + string org = 18; + + // Whether this feature view is disabled for serving. + // When true, the feature view will not serve features. + // Defaults to false (enabled) for backward compatibility. + bool disabled = 19; } message OnDemandFeatureViewMeta { @@ -83,6 +93,15 @@ message OnDemandFeatureViewMeta { // Time where this Feature View is last updated google.protobuf.Timestamp last_updated_timestamp = 2; + + // The current version number of this feature view in the version history. + int32 current_version_number = 3; + + // Auto-generated UUID identifying this specific version. + string version_id = 4; + + // Lifecycle state of this feature view. + FeatureViewState state = 5; } message OnDemandSource { diff --git a/protos/feast/core/Permission.proto b/protos/feast/core/Permission.proto index 8a876a0dc78..e0c1d4efb98 100644 --- a/protos/feast/core/Permission.proto +++ b/protos/feast/core/Permission.proto @@ -46,6 +46,7 @@ message PermissionSpec { SAVED_DATASET = 8; PERMISSION = 9; PROJECT = 10; + LABEL_VIEW = 11; } repeated Type types = 3; diff --git a/protos/feast/core/PrecomputedFeatureVector.proto b/protos/feast/core/PrecomputedFeatureVector.proto new file mode 100644 index 00000000000..798df0b8d1e --- /dev/null +++ b/protos/feast/core/PrecomputedFeatureVector.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package feast.core; + +option go_package = "github.com/feast-dev/feast/go/protos/feast/core"; +option java_outer_classname = "PrecomputedFeatureVectorProto"; +option java_package = "feast.proto.core"; + +import "google/protobuf/timestamp.proto"; +import "feast/types/Value.proto"; + +// A pre-computed feature vector stores all features for a FeatureService +// as a single serialized blob per entity, enabling O(1) online retrieval. +message PrecomputedFeatureVector { + // Fully-qualified feature names in deterministic order, e.g. "fv1__feat1". + repeated string feature_names = 1; + + // Feature values in the same order as feature_names. + repeated feast.types.Value values = 2; + + // Per-feature-view event timestamps for TTL enforcement at read time. + repeated FeatureViewTimestamp fv_timestamps = 3; + + // Wall-clock time when this vector was assembled. + google.protobuf.Timestamp precomputed_at = 4; +} + +// Event timestamp associated with a specific feature view within the vector. +message FeatureViewTimestamp { + string feature_view_name = 1; + google.protobuf.Timestamp event_timestamp = 2; +} diff --git a/protos/feast/core/Registry.proto b/protos/feast/core/Registry.proto index 45ecd2c173e..1224f6d26ff 100644 --- a/protos/feast/core/Registry.proto +++ b/protos/feast/core/Registry.proto @@ -1,63 +1,67 @@ -// -// * Copyright 2020 The Feast Authors -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * https://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// - -syntax = "proto3"; - -package feast.core; -option java_package = "feast.proto.core"; -option java_outer_classname = "RegistryProto"; -option go_package = "github.com/feast-dev/feast/go/protos/feast/core"; - -import "feast/core/Entity.proto"; -import "feast/core/FeatureService.proto"; -import "feast/core/FeatureTable.proto"; -import "feast/core/FeatureView.proto"; -import "feast/core/InfraObject.proto"; -import "feast/core/OnDemandFeatureView.proto"; -import "feast/core/StreamFeatureView.proto"; -import "feast/core/DataSource.proto"; -import "feast/core/SavedDataset.proto"; -import "feast/core/ValidationProfile.proto"; -import "google/protobuf/timestamp.proto"; -import "feast/core/Permission.proto"; -import "feast/core/Project.proto"; - -// Next id: 18 -message Registry { - repeated Entity entities = 1; - repeated FeatureTable feature_tables = 2; - repeated FeatureView feature_views = 6; - repeated DataSource data_sources = 12; - repeated OnDemandFeatureView on_demand_feature_views = 8; - repeated StreamFeatureView stream_feature_views = 14; - repeated FeatureService feature_services = 7; - repeated SavedDataset saved_datasets = 11; - repeated ValidationReference validation_references = 13; - Infra infra = 10; - // Tracking metadata of Feast by project - repeated ProjectMetadata project_metadata = 15 [deprecated = true]; - - string registry_schema_version = 3; // to support migrations; incremented when schema is changed - string version_id = 4; // version id, random string generated on each update of the data; now used only for debugging purposes - google.protobuf.Timestamp last_updated = 5; - repeated Permission permissions = 16; - repeated Project projects = 17; -} - -message ProjectMetadata { - string project = 1; - string project_uuid = 2; -} +// +// * Copyright 2020 The Feast Authors +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * https://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// + +syntax = "proto3"; + +package feast.core; +option java_package = "feast.proto.core"; +option java_outer_classname = "RegistryProto"; +option go_package = "github.com/feast-dev/feast/go/protos/feast/core"; + +import "feast/core/Entity.proto"; +import "feast/core/FeatureService.proto"; +import "feast/core/FeatureTable.proto"; +import "feast/core/FeatureView.proto"; +import "feast/core/InfraObject.proto"; +import "feast/core/OnDemandFeatureView.proto"; +import "feast/core/StreamFeatureView.proto"; +import "feast/core/DataSource.proto"; +import "feast/core/SavedDataset.proto"; +import "feast/core/ValidationProfile.proto"; +import "google/protobuf/timestamp.proto"; +import "feast/core/Permission.proto"; +import "feast/core/Project.proto"; +import "feast/core/FeatureViewVersion.proto"; +import "feast/core/LabelView.proto"; + +// Next id: 20 +message Registry { + repeated Entity entities = 1; + repeated FeatureTable feature_tables = 2; + repeated FeatureView feature_views = 6; + repeated DataSource data_sources = 12; + repeated OnDemandFeatureView on_demand_feature_views = 8; + repeated StreamFeatureView stream_feature_views = 14; + repeated FeatureService feature_services = 7; + repeated SavedDataset saved_datasets = 11; + repeated ValidationReference validation_references = 13; + Infra infra = 10; + // Tracking metadata of Feast by project + repeated ProjectMetadata project_metadata = 15 [deprecated = true]; + + string registry_schema_version = 3; // to support migrations; incremented when schema is changed + string version_id = 4; // version id, random string generated on each update of the data; now used only for debugging purposes + google.protobuf.Timestamp last_updated = 5; + repeated Permission permissions = 16; + repeated Project projects = 17; + FeatureViewVersionHistory feature_view_version_history = 18; + repeated LabelView label_views = 19; +} + +message ProjectMetadata { + string project = 1; + string project_uuid = 2; +} diff --git a/protos/feast/core/StreamFeatureView.proto b/protos/feast/core/StreamFeatureView.proto index 5f9ee6ce39d..8539e74bb6d 100644 --- a/protos/feast/core/StreamFeatureView.proto +++ b/protos/feast/core/StreamFeatureView.proto @@ -37,7 +37,7 @@ message StreamFeatureView { FeatureViewMeta meta = 2; } -// Next available id: 21 +// Next available id: 23 message StreamFeatureViewSpec { // Name of the feature view. Must be unique. Not updated. string name = 1; @@ -102,5 +102,16 @@ message StreamFeatureViewSpec { // Whether schema validation is enabled during materialization bool enable_validation = 20; + + // User-specified version pin (e.g. "latest", "v2", "version2") + string version = 21; + + // Organizational unit that owns this stream feature view (e.g. "ads", "search"). + string org = 22; + + // Whether this feature view is disabled for serving and materialization. + // When true, the feature view will not serve online features or be materialized. + // Defaults to false (enabled) for backward compatibility. + bool disabled = 23; } diff --git a/protos/feast/registry/RegistryServer.proto b/protos/feast/registry/RegistryServer.proto index 1e305abe728..1dfb766b8ea 100644 --- a/protos/feast/registry/RegistryServer.proto +++ b/protos/feast/registry/RegistryServer.proto @@ -14,6 +14,7 @@ import "feast/core/FeatureService.proto"; import "feast/core/SavedDataset.proto"; import "feast/core/ValidationProfile.proto"; import "feast/core/InfraObject.proto"; +import "feast/core/LabelView.proto"; import "feast/core/Permission.proto"; import "feast/core/Project.proto"; @@ -50,6 +51,10 @@ service RegistryServer{ rpc GetOnDemandFeatureView (GetOnDemandFeatureViewRequest) returns (feast.core.OnDemandFeatureView) {} rpc ListOnDemandFeatureViews (ListOnDemandFeatureViewsRequest) returns (ListOnDemandFeatureViewsResponse) {} + // LabelView RPCs + rpc GetLabelView (GetLabelViewRequest) returns (feast.core.LabelView) {} + rpc ListLabelViews (ListLabelViewsRequest) returns (ListLabelViewsResponse) {} + // FeatureService RPCs rpc ApplyFeatureService (ApplyFeatureServiceRequest) returns (google.protobuf.Empty) {} rpc GetFeatureService (GetFeatureServiceRequest) returns (feast.core.FeatureService) {} @@ -220,6 +225,7 @@ message ApplyFeatureViewRequest { feast.core.FeatureView feature_view = 1; feast.core.OnDemandFeatureView on_demand_feature_view = 2; feast.core.StreamFeatureView stream_feature_view = 3; + feast.core.LabelView label_view = 6; } string project = 4; bool commit = 5; @@ -255,6 +261,7 @@ message AnyFeatureView { feast.core.FeatureView feature_view = 1; feast.core.OnDemandFeatureView on_demand_feature_view = 2; feast.core.StreamFeatureView stream_feature_view = 3; + feast.core.LabelView label_view = 4; } } @@ -328,6 +335,27 @@ message ListOnDemandFeatureViewsResponse { PaginationMetadata pagination = 2; } +// LabelViews + +message GetLabelViewRequest { + string name = 1; + string project = 2; + bool allow_cache = 3; +} + +message ListLabelViewsRequest { + string project = 1; + bool allow_cache = 2; + map tags = 3; + PaginationParams pagination = 4; + SortingParams sorting = 5; +} + +message ListLabelViewsResponse { + repeated feast.core.LabelView label_views = 1; + PaginationMetadata pagination = 2; +} + // FeatureServices message ApplyFeatureServiceRequest { @@ -543,6 +571,8 @@ message Feature { google.protobuf.Timestamp created_timestamp = 6; google.protobuf.Timestamp last_updated_timestamp = 7; map tags = 8; + // Semantic kind: "feature" (input/predictor) or "label" (target/annotation). + string kind = 9; } message ListFeaturesRequest { @@ -552,6 +582,8 @@ message ListFeaturesRequest { bool allow_cache = 6; PaginationParams pagination = 4; SortingParams sorting = 5; + // Filter by kind: "feature" or "label". Empty means no filter. + string kind = 7; } message ListFeaturesResponse { diff --git a/protos/feast/serving/GrpcServer.proto b/protos/feast/serving/GrpcServer.proto index 19caf0b7119..44d7c393b7c 100644 --- a/protos/feast/serving/GrpcServer.proto +++ b/protos/feast/serving/GrpcServer.proto @@ -1,6 +1,7 @@ syntax = "proto3"; import "feast/serving/ServingService.proto"; +import "feast/types/Value.proto"; option java_package = "feast.proto.serving"; option java_outer_classname = "GrpcServerAPIProto"; @@ -11,6 +12,7 @@ message PushRequest { string stream_feature_view = 2; bool allow_registry_cache = 3; string to = 4; + map typed_features = 5; } message PushResponse { @@ -21,6 +23,7 @@ message WriteToOnlineStoreRequest { map features = 1; string feature_view_name = 2; bool allow_registry_cache = 3; + map typed_features = 4; } message WriteToOnlineStoreResponse { diff --git a/protos/feast/serving/ServingService.proto b/protos/feast/serving/ServingService.proto index 154d850099f..87e35ac4edf 100644 --- a/protos/feast/serving/ServingService.proto +++ b/protos/feast/serving/ServingService.proto @@ -91,6 +91,9 @@ message GetOnlineFeaturesRequest { // (was moved to dedicated parameter to avoid unnecessary separation logic on serving side) // A map of variable name -> list of values map request_context = 5; + + // Whether to include feature view version metadata in the response + bool include_feature_view_version_metadata = 6; } message GetOnlineFeaturesResponse { @@ -109,8 +112,14 @@ message GetOnlineFeaturesResponse { bool status = 3; } +message FeatureViewMetadata { + string name = 1; // Feature view name (e.g., "driver_stats") + int32 version = 2; // Version number (e.g., 2) +} + message GetOnlineFeaturesResponseMetadata { - FeatureList feature_names = 1; + FeatureList feature_names = 1; // Clean feature names without @v2 syntax + repeated FeatureViewMetadata feature_view_metadata = 2; // Only populated when requested } enum FieldStatus { diff --git a/protos/feast/types/Value.proto b/protos/feast/types/Value.proto index ada2ba42791..648045cb1e0 100644 --- a/protos/feast/types/Value.proto +++ b/protos/feast/types/Value.proto @@ -57,6 +57,19 @@ message ValueType { JSON_LIST = 33; STRUCT = 34; STRUCT_LIST = 35; + UUID = 36; + TIME_UUID = 37; + UUID_LIST = 38; + TIME_UUID_LIST = 39; + UUID_SET = 40; + TIME_UUID_SET = 41; + VALUE_LIST = 42; + VALUE_SET = 43; + DECIMAL = 44; + DECIMAL_LIST = 45; + DECIMAL_SET = 46; + SCALAR_MAP = 47; + ZONED_TIMESTAMP = 48; } } @@ -96,6 +109,19 @@ message Value { StringList json_list_val = 33; Map struct_val = 34; MapList struct_list_val = 35; + string uuid_val = 36; + string time_uuid_val = 37; + StringList uuid_list_val = 38; + StringList time_uuid_list_val = 39; + StringSet uuid_set_val = 40; + StringSet time_uuid_set_val = 41; + RepeatedValue list_val = 42; + RepeatedValue set_val = 43; + string decimal_val = 44; + StringList decimal_list_val = 45; + StringSet decimal_set_val = 46; + ScalarMap scalar_map_val = 47; + ZonedTimestamp zoned_timestamp_val = 48; } } @@ -103,6 +129,17 @@ enum Null { NULL = 0; } +// A timezone-aware datetime: the UTC instant plus its originating zone, so a +// zoned datetime round-trips losslessly (unlike UNIX_TIMESTAMP, which is decoded +// as UTC and discards the original zone). +message ZonedTimestamp { + // Epoch seconds (UTC instant), same convention as unix_timestamp_val. + int64 unix_timestamp = 1; + // IANA zone name (e.g. "America/Los_Angeles") or a fixed-offset string + // (e.g. "-07:00", "UTC"). Empty string is treated as UTC on read. + string zone = 2; +} + message BytesList { repeated bytes val = 1; } @@ -172,3 +209,30 @@ message MapList { message RepeatedValue { repeated Value val = 1; } + +// Map key for maps with non-string keys. +// Excludes string (handled by Map) and all collection types (not valid as keys). +message MapKey { + oneof key { + int32 int32_key = 1; + int64 int64_key = 2; + float float_key = 3; + double double_key = 4; + bool bool_key = 5; + int64 unix_timestamp_key = 6; + bytes bytes_key = 7; + string uuid_key = 8; + string time_uuid_key = 9; + string decimal_key = 10; + } +} + +message ScalarMapEntry { + MapKey key = 1; + Value value = 2; +} + +// Map with non-string keys. For string-keyed maps use Map. +message ScalarMap { + repeated ScalarMapEntry val = 1; +} diff --git a/pyproject.toml b/pyproject.toml index 3ba14b4ee47..25bef64ccfa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,8 @@ dependencies = [ "mmh3", "numpy>=2.0.0,<3", "pandas>=1.4.3,<3", - "pyarrow>=21.0.0", + "pyarrow>=21.0.0; extra != 'flink'", + "pyarrow>=16.1.0,<21.0.0; extra == 'flink'", "pydantic>=2.10.6", "pygments>=2.12.0,<3", "PyYAML>=5.4.0,<7", @@ -35,19 +36,19 @@ dependencies = [ "tqdm>=4,<5", "typeguard>=4.0.0", "fastapi>=0.68.0", + "starlette>=1.0.1", "uvicorn[standard]>=0.30.6,<=0.34.0", "uvicorn-worker", "gunicorn; platform_system != 'Windows'", "dask[dataframe]>=2024.2.1", - "prometheus_client", + "prometheus_client>=0.20.0,<0.25.0", "psutil", "bigtree>=0.19.2", "pyjwt", - "orjson>=3.9.0", ] [project.optional-dependencies] -aws = ["boto3==1.38.27", "fsspec<=2024.9.0", "aiobotocore>2,<3"] +aws = ["boto3>=1.38.27", "fsspec>=2024.1.0", "aiobotocore>=2"] azure = [ "azure-storage-blob>=0.37.0", "azure-identity>=1.6.1", @@ -63,6 +64,7 @@ docling = ["docling==2.27.0"] duckdb = ["ibis-framework[duckdb]>=10.0.0"] elasticsearch = ["elasticsearch>=8.13.0"] faiss = ["faiss-cpu>=1.7.0,<=1.10.0"] +flink = ["apache-flink>=2.2.1,<3"] gcp = [ "google-api-core>=1.23.0,<3", "googleapis-common-protos>=1.52.0,<2", @@ -71,14 +73,14 @@ gcp = [ "google-cloud-datastore>=2.16.0,<3", "google-cloud-storage>=1.34.0,<3", "google-cloud-bigtable>=2.11.0,<3", - "fsspec<=2024.9.0", + "fsspec>=2024.1.0", ] ge = ["great_expectations>=0.15.41,<1"] go = ["cffi>=1.15.0"] grpcio = [ - "grpcio>=1.56.2,<=1.62.3", - "grpcio-reflection>=1.56.2,<=1.62.3", - "grpcio-health-checking>=1.56.2,<=1.62.3", + "grpcio>=1.56.2", + "grpcio-reflection>=1.56.2", + "grpcio-health-checking>=1.56.2", ] hazelcast = ["hazelcast-python-client>=5.1"] hbase = ["happybase>=1.2.0,<3"] @@ -93,7 +95,7 @@ image = [ "scikit-learn>=1.0.0", ] milvus = [ - "pymilvus>2.5", + "pymilvus>=2.5,<3", "milvus-lite==2.4.12", "feast[setuptools]" ] @@ -108,23 +110,25 @@ openlineage = ["openlineage-python>=1.40.0"] opentelemetry = ["prometheus_client", "psutil"] spark = ["pyspark>=4.0.0"] trino = ["trino>=0.305.0,<0.400.0", "regex"] -postgres = ["psycopg[binary,pool]==3.2.5"] +postgres = ["psycopg[binary,pool]>=3.2.5"] # psycopg[c] install requires a system with a C compiler, python dev headers, & postgresql client dev headers # https://www.psycopg.org/psycopg3/docs/basic/install.html#local-installation -postgres-c = ["psycopg[c,pool]==3.2.5"] +postgres-c = ["psycopg[c,pool]>=3.2.5"] pytorch = ["torch>=2.7.0", "torchvision>=0.22.1"] qdrant = ["qdrant-client>=1.12.0"] rag = [ "transformers>=4.36.0", "datasets>=3.6.0", + "sentence-transformers>=3.0.0", ] ray = [ 'ray>=2.47.0; python_version == "3.10"', -'codeflare-sdk>=0.31.1; python_version > "3.10"' +'codeflare-sdk>=0.31.1; python_version > "3.10"', +"datasets>=3.6.0", ] redis = [ - "redis>=4.2.2,<5", - "hiredis>=2.0.0,<3", + "redis>=4.2.2,<8", + "hiredis>=2.0.0,<4", ] singlestore = ["singlestoredb<1.8.0"] snowflake = [ @@ -132,6 +136,7 @@ snowflake = [ ] sqlite_vec = ["sqlite-vec==v0.1.6"] mcp = ["fastapi_mcp"] +mlflow = ["mlflow>=2.10.0"] dbt = ["dbt-artifacts-parser"] @@ -146,21 +151,21 @@ test = [ "pytest-benchmark>=3.4.1,<4", "pytest-asyncio<=0.24.0", "py>=1.11.0", - "testcontainers==4.9.0", + "testcontainers>=4.15.0rc2", "minio==7.2.11", "python-keycloak==4.2.2", - "cryptography>=43.0,<44", + "cryptography>=43.0", ] ci = [ - "feast[test, aws, azure, cassandra, clickhouse, couchbase, delta, docling, duckdb, elasticsearch, faiss, gcp, ge, go, grpcio, hazelcast, hbase, ibis, image, k8s, mcp, milvus, mssql, mysql, openlineage, opentelemetry, oracle, spark, trino, postgres, pytorch, qdrant, rag, ray, redis, singlestore, snowflake, sqlite_vec]", + "feast[test, aws, azure, cassandra, clickhouse, couchbase, delta, docling, duckdb, elasticsearch, faiss, gcp, ge, go, grpcio, hazelcast, hbase, ibis, image, k8s, mcp, milvus, mlflow, mongodb, mssql, mysql, openlineage, opentelemetry, oracle, spark, trino, postgres, pytorch, qdrant, rag, ray, redis, singlestore, snowflake, sqlite_vec]", "build", "virtualenv==20.23.0", "dbt-artifacts-parser", "ruff>=0.8.0", "mypy-protobuf>=3.1", - "grpcio-tools>=1.56.2,<=1.62.3", - "grpcio-testing>=1.56.2,<=1.62.3", + "grpcio-tools>=1.56.2", + "grpcio-testing>=1.56.2", # FastAPI does not correctly pull starlette dependency on httpx see thread(https://github.com/tiangolo/fastapi/issues/5656). "httpx==0.27.2", "mock==2.0.0", @@ -275,6 +280,26 @@ dev = [ "pytest-xdist>=3.8.0", ] +[tool.uv] +conflicts = [ + [ + { extra = "flink" }, + { extra = "ge" }, + ], + [ + { extra = "flink" }, + { extra = "ci" }, + ], + [ + { extra = "flink" }, + { extra = "dev" }, + ], + [ + { extra = "flink" }, + { extra = "docs" }, + ], +] + # Pixi configuration [tool.pixi.workspace] channels = ["conda-forge"] @@ -295,11 +320,12 @@ feast = { path = ".", editable = true, extras = ["ray", "grpcio", "test"] } [tool.pixi.feature.ray-tests.tasks] test-offline = { cmd = "python -m pytest -v --integration --ignore=sdk/python/tests/integration/offline_store/test_dqm_validation.py sdk/python/tests/integration/offline_store", env = { PYTHONPATH = ".", FULL_REPO_CONFIGS_MODULE = "sdk.python.tests.universal.feature_repos.ray_repo_configuration", FEAST_IS_LOCAL_TEST = "True" } } test-compute = { cmd = "python -m pytest -v --integration sdk/python/tests/component/ray", env = { PYTHONPATH = ".", FEAST_IS_LOCAL_TEST = "True" } } -test = { depends-on = ["test-offline", "test-compute"] } +test-unit-compute-ray = { cmd = "python -m pytest -v sdk/python/tests/component/ray", env = { PYTHONPATH = ".", FEAST_IS_LOCAL_TEST = "True" } } +test = { depends-on = ["test-offline", "test-unit-compute-ray", "test-compute"] } [tool.pixi.feature.registration-tests.pypi-dependencies] feast = { path = ".", editable = true, extras = ["aws", "gcp", "grpcio", "postgres", "mysql", "redis", "snowflake", "spark", "test"] } -grpcio-testing = ">=1.56.2,<=1.62.3" +grpcio-testing = ">=1.56.2" [tool.pixi.feature.registration-tests.tasks] test = { cmd = "python -m pytest -n auto --dist loadgroup --integration sdk/python/tests/integration/registration", env = { PYTHONPATH = ".", FEAST_IS_LOCAL_TEST = "True" } } diff --git a/sdk/python/docs/index.rst b/sdk/python/docs/index.rst index 14af6a6d9ef..ad21025eb2e 100644 --- a/sdk/python/docs/index.rst +++ b/sdk/python/docs/index.rst @@ -128,6 +128,18 @@ Stream Feature View .. autoclass:: feast.stream_feature_view.StreamFeatureView :members: +Label View +---------------------- + +.. autoclass:: feast.labeling.label_view.LabelView + :members: + +Conflict Policy +---------------------- + +.. autoclass:: feast.labeling.conflict_policy.ConflictPolicy + :members: + Field ================== diff --git a/sdk/python/docs/source/feast.aggregation.rst b/sdk/python/docs/source/feast.aggregation.rst new file mode 100644 index 00000000000..757f0976bac --- /dev/null +++ b/sdk/python/docs/source/feast.aggregation.rst @@ -0,0 +1,17 @@ +feast.aggregation package +========================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + feast.aggregation.tiling + +Module contents +--------------- + +.. automodule:: feast.aggregation + :members: + :show-inheritance: diff --git a/sdk/python/docs/source/feast.aggregation.tiling.rst b/sdk/python/docs/source/feast.aggregation.tiling.rst new file mode 100644 index 00000000000..d51ef22ed05 --- /dev/null +++ b/sdk/python/docs/source/feast.aggregation.tiling.rst @@ -0,0 +1,9 @@ +feast.aggregation.tiling package +================================= + +Module contents +--------------- + +.. automodule:: feast.aggregation.tiling + :members: + :show-inheritance: diff --git a/sdk/python/docs/source/feast.dbt.rst b/sdk/python/docs/source/feast.dbt.rst new file mode 100644 index 00000000000..3a7c28d620b --- /dev/null +++ b/sdk/python/docs/source/feast.dbt.rst @@ -0,0 +1,37 @@ +feast.dbt package +================= + +Submodules +---------- + +feast.dbt.codegen module +------------------------ + +.. automodule:: feast.dbt.codegen + :members: + :undoc-members: + :show-inheritance: + +feast.dbt.mapper module +----------------------- + +.. automodule:: feast.dbt.mapper + :members: + :undoc-members: + :show-inheritance: + +feast.dbt.parser module +----------------------- + +.. automodule:: feast.dbt.parser + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: feast.dbt + :members: + :undoc-members: + :show-inheritance: diff --git a/sdk/python/docs/source/feast.diff.rst b/sdk/python/docs/source/feast.diff.rst index e4142171711..f03ab5d8409 100644 --- a/sdk/python/docs/source/feast.diff.rst +++ b/sdk/python/docs/source/feast.diff.rst @@ -4,6 +4,14 @@ feast.diff package Submodules ---------- +feast.diff.apply\_progress module +---------------------------------- + +.. automodule:: feast.diff.apply_progress + :members: + :undoc-members: + :show-inheritance: + feast.diff.infra\_diff module ----------------------------- diff --git a/sdk/python/docs/source/feast.loaders.rst b/sdk/python/docs/source/feast.loaders.rst deleted file mode 100644 index d4968a29999..00000000000 --- a/sdk/python/docs/source/feast.loaders.rst +++ /dev/null @@ -1,21 +0,0 @@ -feast.loaders package -===================== - -Submodules ----------- - -feast.loaders.yaml module -------------------------- - -.. automodule:: feast.loaders.yaml - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: feast.loaders - :members: - :undoc-members: - :show-inheritance: diff --git a/sdk/python/docs/source/feast.openlineage.rst b/sdk/python/docs/source/feast.openlineage.rst new file mode 100644 index 00000000000..a861bcccf56 --- /dev/null +++ b/sdk/python/docs/source/feast.openlineage.rst @@ -0,0 +1,9 @@ +feast.openlineage package +========================= + +Module contents +--------------- + +.. automodule:: feast.openlineage + :members: + :show-inheritance: diff --git a/sdk/python/docs/source/feast.protos.feast.core.rst b/sdk/python/docs/source/feast.protos.feast.core.rst index b2fa998509c..e5bdced9f22 100644 --- a/sdk/python/docs/source/feast.protos.feast.core.rst +++ b/sdk/python/docs/source/feast.protos.feast.core.rst @@ -180,6 +180,14 @@ feast.protos.feast.core.InfraObject\_pb2\_grpc module :undoc-members: :show-inheritance: +feast.protos.feast.core.LabelView\_pb2 module +---------------------------------------------- + +.. automodule:: feast.protos.feast.core.LabelView_pb2 + :members: + :undoc-members: + :show-inheritance: + feast.protos.feast.core.OnDemandFeatureView\_pb2 module ------------------------------------------------------- diff --git a/sdk/python/docs/source/feast.rst b/sdk/python/docs/source/feast.rst index ffb8a2eb580..304083138d2 100644 --- a/sdk/python/docs/source/feast.rst +++ b/sdk/python/docs/source/feast.rst @@ -7,14 +7,16 @@ Subpackages .. toctree:: :maxdepth: 4 + feast.aggregation feast.api feast.cli + feast.dbt feast.diff feast.dqm feast.embedded_go feast.infra feast.lineage - feast.loaders + feast.openlineage feast.permissions feast.protos feast.transformation @@ -23,14 +25,6 @@ Subpackages Submodules ---------- -feast.aggregation module ------------------------- - -.. automodule:: feast.aggregation - :members: - :undoc-members: - :show-inheritance: - feast.arrow\_error\_handler module ---------------------------------- @@ -71,6 +65,14 @@ feast.data\_format module :undoc-members: :show-inheritance: +feast.demos module +------------------ + +.. automodule:: feast.demos + :members: + :undoc-members: + :show-inheritance: + feast.data\_source module ------------------------- diff --git a/sdk/python/feast/__init__.py b/sdk/python/feast/__init__.py index 1a03327740e..30925e9fc4a 100644 --- a/sdk/python/feast/__init__.py +++ b/sdk/python/feast/__init__.py @@ -1,6 +1,7 @@ from importlib.metadata import PackageNotFoundError from importlib.metadata import version as _version +from feast.demos import copy_demo_notebooks from feast.infra.offline_stores.bigquery_source import BigQuerySource from feast.infra.offline_stores.contrib.athena_offline_store.athena_source import ( AthenaSource, @@ -14,14 +15,18 @@ from .aggregation import Aggregation from .batch_feature_view import BatchFeatureView +from .chunker import BaseChunker, ChunkingConfig, TextChunker from .data_source import KafkaSource, KinesisSource, PushSource, RequestSource from .dataframe import DataFrameEngine, FeastDataFrame +from .doc_embedder import DocEmbedder, SchemaTransformFn +from .embedder import BaseEmbedder, EmbeddingConfig, MultiModalEmbedder from .entity import Entity from .feature import Feature from .feature_service import FeatureService from .feature_store import FeatureStore -from .feature_view import FeatureView +from .feature_view import FeatureView, FeatureViewState from .field import Field +from .labeling import ConflictPolicy, LabelView from .on_demand_feature_view import OnDemandFeatureView from .project import Project from .repo_config import RepoConfig @@ -38,6 +43,7 @@ __all__ = [ "Aggregation", "BatchFeatureView", + "copy_demo_notebooks", "DataFrameEngine", "Entity", "KafkaSource", @@ -48,6 +54,9 @@ "FeatureService", "FeatureStore", "FeatureView", + "FeatureViewState", + "LabelView", + "ConflictPolicy", "OnDemandFeatureView", "RepoConfig", "StreamFeatureView", @@ -62,4 +71,12 @@ "OracleSource", "Project", "FeastVectorStore", + "DocEmbedder", + "SchemaTransformFn", + "BaseChunker", + "TextChunker", + "ChunkingConfig", + "BaseEmbedder", + "MultiModalEmbedder", + "EmbeddingConfig", ] diff --git a/sdk/python/feast/aggregation/__init__.py b/sdk/python/feast/aggregation/__init__.py index 8edb51bb76b..464e49edd9b 100644 --- a/sdk/python/feast/aggregation/__init__.py +++ b/sdk/python/feast/aggregation/__init__.py @@ -18,7 +18,7 @@ class Aggregation: Attributes: column: str # Column name of the feature we are aggregating. - function: str # Provided built in aggregations sum, max, min, count mean + function: str # Provided built in aggregations sum, max, min, count, mean, count_distinct time_window: timedelta # The time window for this aggregation. slide_interval: timedelta # The sliding window for these aggregations name: str # Optional override for the output feature name (defaults to {function}_{column}) @@ -118,6 +118,11 @@ def resolved_name(self, time_window: Optional[timedelta] = None) -> str: return base +_FUNCTION_ALIASES: Dict[str, str] = { + "count_distinct": "nunique", +} + + def aggregation_specs_to_agg_ops( agg_specs: Iterable[Any], *, @@ -128,7 +133,8 @@ def aggregation_specs_to_agg_ops( if getattr(agg, "time_window", None) is not None: raise ValueError(time_window_unsupported_error_message) alias = getattr(agg, "name", None) or f"{agg.function}_{agg.column}" - agg_ops[alias] = (agg.function, agg.column) + func_name = _FUNCTION_ALIASES.get(agg.function, agg.function) + agg_ops[alias] = (func_name, agg.column) return agg_ops diff --git a/sdk/python/feast/aggregation/tiling/base.py b/sdk/python/feast/aggregation/tiling/base.py index c5ff765a0a9..8a4bbacf3ca 100644 --- a/sdk/python/feast/aggregation/tiling/base.py +++ b/sdk/python/feast/aggregation/tiling/base.py @@ -86,6 +86,12 @@ def get_ir_metadata_for_aggregation( ), ) + elif agg_type == "count_distinct": + raise ValueError( + "count_distinct does not support tiling. " + "Use enable_tiling=False or choose an algebraic aggregation (sum, count, min, max)." + ) + else: # Unknown aggregation: treat as algebraic return ([], IRMetadata(type="algebraic")) diff --git a/sdk/python/feast/api/registry/rest/__init__.py b/sdk/python/feast/api/registry/rest/__init__.py index 14db40d7af6..24d755386a6 100644 --- a/sdk/python/feast/api/registry/rest/__init__.py +++ b/sdk/python/feast/api/registry/rest/__init__.py @@ -5,23 +5,30 @@ from feast.api.registry.rest.feature_services import get_feature_service_router from feast.api.registry.rest.feature_views import get_feature_view_router from feast.api.registry.rest.features import get_feature_router +from feast.api.registry.rest.label_views import get_label_view_router from feast.api.registry.rest.lineage import get_lineage_router from feast.api.registry.rest.metrics import get_metrics_router +from feast.api.registry.rest.monitoring import get_monitoring_router from feast.api.registry.rest.permissions import get_permission_router from feast.api.registry.rest.projects import get_project_router from feast.api.registry.rest.saved_datasets import get_saved_dataset_router from feast.api.registry.rest.search import get_search_router -def register_all_routes(app: FastAPI, grpc_handler, server=None): +def register_all_routes(app: FastAPI, grpc_handler, server=None, store=None): app.include_router(get_entity_router(grpc_handler)) app.include_router(get_data_source_router(grpc_handler)) app.include_router(get_feature_service_router(grpc_handler)) app.include_router(get_feature_view_router(grpc_handler)) app.include_router(get_feature_router(grpc_handler)) + app.include_router(get_label_view_router(grpc_handler)) app.include_router(get_lineage_router(grpc_handler)) app.include_router(get_permission_router(grpc_handler)) app.include_router(get_project_router(grpc_handler)) app.include_router(get_saved_dataset_router(grpc_handler)) app.include_router(get_search_router(grpc_handler)) app.include_router(get_metrics_router(grpc_handler, server)) + resolved_store = store or ( + server.store if server and hasattr(server, "store") else None + ) + app.include_router(get_monitoring_router(grpc_handler, store=resolved_store)) diff --git a/sdk/python/feast/api/registry/rest/data_sources.py b/sdk/python/feast/api/registry/rest/data_sources.py index bbc120707fc..4e522644ed3 100644 --- a/sdk/python/feast/api/registry/rest/data_sources.py +++ b/sdk/python/feast/api/registry/rest/data_sources.py @@ -1,7 +1,9 @@ import logging -from typing import Dict +from typing import Dict, Optional from fastapi import APIRouter, Depends, Query +from fastapi.responses import JSONResponse +from pydantic import BaseModel from feast.api.registry.rest.codegen_utils import ( render_data_source_code, @@ -19,6 +21,7 @@ grpc_call, parse_tags, ) +from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto from feast.protos.feast.registry import RegistryServer_pb2 from feast.type_map import _convert_value_type_str_to_value_type from feast.types import from_value_type @@ -26,6 +29,54 @@ logger = logging.getLogger(__name__) +class FileOptionsModel(BaseModel): + uri: str = "" + + +class BigQueryOptionsModel(BaseModel): + table: str = "" + query: str = "" + + +class SnowflakeOptionsModel(BaseModel): + table: str = "" + database: str = "" + schema_: str = "" + + +class RedshiftOptionsModel(BaseModel): + table: str = "" + database: str = "" + schema_: str = "" + + +class KafkaOptionsModel(BaseModel): + kafka_bootstrap_servers: str = "" + topic: str = "" + + +class SparkOptionsModel(BaseModel): + table: str = "" + path: str = "" + + +class ApplyDataSourceRequestBody(BaseModel): + name: str + project: str + type: Optional[int] = None + timestamp_field: Optional[str] = "" + created_timestamp_column: Optional[str] = "" + description: Optional[str] = "" + tags: Optional[Dict[str, str]] = {} + owner: Optional[str] = "" + file_options: Optional[FileOptionsModel] = None + bigquery_options: Optional[BigQueryOptionsModel] = None + snowflake_options: Optional[SnowflakeOptionsModel] = None + redshift_options: Optional[RedshiftOptionsModel] = None + kafka_options: Optional[KafkaOptionsModel] = None + spark_options: Optional[SparkOptionsModel] = None + + def get_data_source_router(grpc_handler) -> APIRouter: router = APIRouter() @@ -157,4 +208,69 @@ def get_data_source( result["featureDefinition"] = render_data_source_code(context) return result + @router.post("/data_sources", status_code=201) + def apply_data_source(body: ApplyDataSourceRequestBody): + ds_proto = DataSourceProto( + name=body.name, + timestamp_field=body.timestamp_field or "", + created_timestamp_column=body.created_timestamp_column or "", + description=body.description or "", + tags=body.tags or {}, + owner=body.owner or "", + ) + if body.type is not None: + ds_proto.type = body.type # type: ignore[assignment] + + if body.file_options: + ds_proto.file_options.uri = body.file_options.uri + elif body.bigquery_options: + ds_proto.bigquery_options.table = body.bigquery_options.table + ds_proto.bigquery_options.query = body.bigquery_options.query + elif body.snowflake_options: + ds_proto.snowflake_options.table = body.snowflake_options.table + ds_proto.snowflake_options.database = body.snowflake_options.database + ds_proto.snowflake_options.schema = body.snowflake_options.schema_ + elif body.redshift_options: + ds_proto.redshift_options.table = body.redshift_options.table + ds_proto.redshift_options.database = body.redshift_options.database + ds_proto.redshift_options.schema = body.redshift_options.schema_ + elif body.kafka_options: + ds_proto.kafka_options.kafka_bootstrap_servers = ( + body.kafka_options.kafka_bootstrap_servers + ) + ds_proto.kafka_options.topic = body.kafka_options.topic + elif body.spark_options: + ds_proto.spark_options.table = body.spark_options.table + ds_proto.spark_options.path = body.spark_options.path + + req = RegistryServer_pb2.ApplyDataSourceRequest( + data_source=ds_proto, + project=body.project, + commit=True, + ) + grpc_call(grpc_handler.ApplyDataSource, req) + + return JSONResponse( + status_code=201, + content={ + "name": body.name, + "project": body.project, + "status": "applied", + }, + ) + + @router.delete("/data_sources/{name}") + def delete_data_source( + name: str, + project: str = Query(...), + ): + req = RegistryServer_pb2.DeleteDataSourceRequest( + name=name, + project=project, + commit=True, + ) + grpc_call(grpc_handler.DeleteDataSource, req) + + return {"name": name, "project": project, "status": "deleted"} + return router diff --git a/sdk/python/feast/api/registry/rest/entities.py b/sdk/python/feast/api/registry/rest/entities.py index d2943ea74c4..5326433c0aa 100644 --- a/sdk/python/feast/api/registry/rest/entities.py +++ b/sdk/python/feast/api/registry/rest/entities.py @@ -1,6 +1,9 @@ import logging +from typing import Dict, Optional from fastapi import APIRouter, Depends, Query +from fastapi.responses import JSONResponse +from pydantic import BaseModel from feast.api.registry.rest.codegen_utils import render_entity_code from feast.api.registry.rest.rest_utils import ( @@ -13,11 +16,23 @@ get_sorting_params, grpc_call, ) +from feast.protos.feast.core.Entity_pb2 import Entity as EntityProto +from feast.protos.feast.core.Entity_pb2 import EntitySpecV2 as EntitySpecProto from feast.protos.feast.registry import RegistryServer_pb2 logger = logging.getLogger(__name__) +class ApplyEntityRequestBody(BaseModel): + name: str + project: str + join_key: Optional[str] = None + value_type: Optional[int] = 2 + description: Optional[str] = "" + tags: Optional[Dict[str, str]] = {} + owner: Optional[str] = "" + + def get_entity_router(grpc_handler) -> APIRouter: router = APIRouter() @@ -136,4 +151,44 @@ def get_entity( result["featureDefinition"] = render_entity_code(context) return result + @router.post("/entities", status_code=201) + def apply_entity(body: ApplyEntityRequestBody): + join_key = body.join_key if body.join_key else body.name + + spec = EntitySpecProto( + name=body.name, + value_type=body.value_type, + join_key=join_key, + description=body.description or "", + tags=body.tags or {}, + owner=body.owner or "", + ) + entity_proto = EntityProto(spec=spec) + + req = RegistryServer_pb2.ApplyEntityRequest( + entity=entity_proto, + project=body.project, + commit=True, + ) + grpc_call(grpc_handler.ApplyEntity, req) + + return JSONResponse( + status_code=201, + content={"name": body.name, "project": body.project, "status": "applied"}, + ) + + @router.delete("/entities/{name}") + def delete_entity( + name: str, + project: str = Query(...), + ): + req = RegistryServer_pb2.DeleteEntityRequest( + name=name, + project=project, + commit=True, + ) + grpc_call(grpc_handler.DeleteEntity, req) + + return {"name": name, "project": project, "status": "deleted"} + return router diff --git a/sdk/python/feast/api/registry/rest/feature_views.py b/sdk/python/feast/api/registry/rest/feature_views.py index 0c921a20870..1f6e6604c80 100644 --- a/sdk/python/feast/api/registry/rest/feature_views.py +++ b/sdk/python/feast/api/registry/rest/feature_views.py @@ -1,6 +1,10 @@ -from typing import Dict +import logging +from typing import Dict, List, Optional from fastapi import APIRouter, Depends, Query +from fastapi.responses import JSONResponse +from google.protobuf.duration_pb2 import Duration +from pydantic import BaseModel from feast.api.registry.rest.codegen_utils import render_feature_view_code from feast.api.registry.rest.rest_utils import ( @@ -14,10 +18,35 @@ paginate_and_sort, parse_tags, ) +from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto +from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 +from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto +from feast.protos.feast.core.FeatureView_pb2 import FeatureViewSpec from feast.registry_server import RegistryServer_pb2 from feast.type_map import _convert_value_type_str_to_value_type from feast.types import from_value_type +logger = logging.getLogger(__name__) + + +class FeatureModel(BaseModel): + name: str + value_type: int = 2 + description: Optional[str] = "" + + +class ApplyFeatureViewRequestBody(BaseModel): + name: str + project: str + entities: Optional[List[str]] = [] + features: Optional[List[FeatureModel]] = [] + batch_source: Optional[str] = "" + ttl_seconds: Optional[int] = None + online: Optional[bool] = True + description: Optional[str] = "" + tags: Optional[Dict[str, str]] = {} + owner: Optional[str] = "" + def _extract_feature_view_from_any(any_feature_view: dict) -> dict: """Extract the specific feature view type and data from an AnyFeatureView object. @@ -275,4 +304,70 @@ def list_all_feature_views( return result + @router.post("/feature_views", status_code=201) + def apply_feature_view(body: ApplyFeatureViewRequestBody): + feature_specs = [] + for f in body.features or []: + feature_specs.append( + FeatureSpecV2( + name=f.name, + value_type=f.value_type, + description=f.description or "", + ) + ) + + batch_source_proto = ( + DataSourceProto(name=body.batch_source) if body.batch_source else None + ) + + ttl = ( + Duration(seconds=body.ttl_seconds) if body.ttl_seconds is not None else None + ) + + spec = FeatureViewSpec( + name=body.name, + entities=body.entities or [], + features=feature_specs, + tags=body.tags or {}, + online=body.online if body.online is not None else True, + description=body.description or "", + owner=body.owner or "", + ) + if ttl is not None: + spec.ttl.CopyFrom(ttl) + if batch_source_proto: + spec.batch_source.CopyFrom(batch_source_proto) + + fv_proto = FeatureViewProto(spec=spec) + + req = RegistryServer_pb2.ApplyFeatureViewRequest( + feature_view=fv_proto, + project=body.project, + commit=True, + ) + grpc_call(grpc_handler.ApplyFeatureView, req) + + return JSONResponse( + status_code=201, + content={ + "name": body.name, + "project": body.project, + "status": "applied", + }, + ) + + @router.delete("/feature_views/{name}") + def delete_feature_view( + name: str, + project: str = Query(...), + ): + req = RegistryServer_pb2.DeleteFeatureViewRequest( + name=name, + project=project, + commit=True, + ) + grpc_call(grpc_handler.DeleteFeatureView, req) + + return {"name": name, "project": project, "status": "deleted"} + return router diff --git a/sdk/python/feast/api/registry/rest/features.py b/sdk/python/feast/api/registry/rest/features.py index 122b02577b9..f2834e32285 100644 --- a/sdk/python/feast/api/registry/rest/features.py +++ b/sdk/python/feast/api/registry/rest/features.py @@ -38,6 +38,7 @@ def list_features( feature_view=feature_view or "", name=name or "", allow_cache=allow_cache, + kind="feature", pagination=create_grpc_pagination_params(pagination_params), sorting=create_grpc_sorting_params(sorting_params), ) @@ -127,6 +128,76 @@ def list_features_all( limit=limit, sort_by=sort_by, sort_order=sort_order, + extra_request_params={"kind": "feature"}, ) + # --- Labels endpoints (items from LabelViews only) --- + + @router.get("/labels") + def list_labels( + project: str = Query(...), + feature_view: str = Query(None, description="Filter by label view name"), + name: str = Query(None, description="Filter by label name"), + include_relationships: bool = Query( + False, description="Include relationships for each label" + ), + allow_cache: bool = Query(True), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), + ): + req = RegistryServer_pb2.ListFeaturesRequest( + project=project, + feature_view=feature_view or "", + name=name or "", + allow_cache=allow_cache, + kind="label", + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), + ) + response = grpc_call(grpc_handler.ListFeatures, req) + if "features" not in response: + response["features"] = [] + if "pagination" not in response: + response["pagination"] = {} + + # Rename key for clarity in the response + response["labels"] = response.pop("features") + + if include_relationships: + labels = response.get("labels", []) + relationships = get_relationships_for_objects( + grpc_handler, labels, "feature", project, allow_cache + ) + response["relationships"] = relationships + return response + + @router.get("/labels/all") + def list_labels_all( + page: int = Query(1, ge=1), + limit: int = Query(50, ge=1, le=100), + sort_by: str = Query(None), + sort_order: str = Query("asc"), + include_relationships: bool = Query( + False, description="Include relationships for each label" + ), + allow_cache: bool = Query(True), + ): + result = aggregate_across_projects( + grpc_handler=grpc_handler, + list_method=grpc_handler.ListFeatures, + request_cls=RegistryServer_pb2.ListFeaturesRequest, + response_key="features", + object_type="feature", + include_relationships=include_relationships, + allow_cache=allow_cache, + page=page, + limit=limit, + sort_by=sort_by, + sort_order=sort_order, + extra_request_params={"kind": "label"}, + ) + if "features" in result: + result["labels"] = result.pop("features") + return result + return router diff --git a/sdk/python/feast/api/registry/rest/label_views.py b/sdk/python/feast/api/registry/rest/label_views.py new file mode 100644 index 00000000000..c6aa199e68c --- /dev/null +++ b/sdk/python/feast/api/registry/rest/label_views.py @@ -0,0 +1,137 @@ +from fastapi import APIRouter, Depends, Query + +from feast.api.registry.rest.rest_utils import ( + create_grpc_pagination_params, + create_grpc_sorting_params, + get_object_relationships, + get_pagination_params, + get_relationships_for_objects, + get_sorting_params, + grpc_call, + paginate_and_sort, + parse_tags, +) +from feast.registry_server import RegistryServer_pb2 + + +def get_label_view_router(grpc_handler) -> APIRouter: + router = APIRouter() + + @router.get("/label_views") + def list_label_views( + project: str = Query(...), + allow_cache: bool = Query(default=True), + include_relationships: bool = Query( + False, description="Include relationships for each label view" + ), + tags: dict = Depends(parse_tags), + pagination_params: dict = Depends(get_pagination_params), + sorting_params: dict = Depends(get_sorting_params), + ): + req = RegistryServer_pb2.ListLabelViewsRequest( + project=project, + allow_cache=allow_cache, + tags=tags, + pagination=create_grpc_pagination_params(pagination_params), + sorting=create_grpc_sorting_params(sorting_params), + ) + response = grpc_call(grpc_handler.ListLabelViews, req) + label_views = response.get("labelViews", []) + + for lv in label_views: + lv["type"] = "labelView" + + result = { + "featureViews": label_views, + "pagination": response.get("pagination", {}), + } + + if include_relationships: + relationships = get_relationships_for_objects( + grpc_handler, label_views, "featureView", project, allow_cache + ) + result["relationships"] = relationships + + return result + + @router.get("/label_views/all") + def list_label_views_all( + allow_cache: bool = Query(default=True), + page: int = Query(1, ge=1), + limit: int = Query(50, ge=1, le=100), + sort_by: str = Query(None), + sort_order: str = Query("asc"), + include_relationships: bool = Query( + False, description="Include relationships for each label view" + ), + ): + projects_resp = grpc_call( + grpc_handler.ListProjects, + RegistryServer_pb2.ListProjectsRequest(allow_cache=allow_cache), + ) + projects = projects_resp.get("projects", []) + all_label_views = [] + for project in projects: + project_name = project["spec"]["name"] + req = RegistryServer_pb2.ListLabelViewsRequest( + project=project_name, + allow_cache=allow_cache, + ) + response = grpc_call(grpc_handler.ListLabelViews, req) + label_views = response.get("labelViews", []) + for lv in label_views: + lv["type"] = "labelView" + lv["project"] = project_name + all_label_views.extend(label_views) + + paged_label_views, pagination = paginate_and_sort( + all_label_views, page, limit, sort_by, sort_order + ) + result = { + "featureViews": paged_label_views, + "pagination": pagination, + } + if include_relationships: + relationships_map = {} + for project in projects: + project_name = project["spec"]["name"] + project_lvs = [ + lv for lv in all_label_views if lv.get("project") == project_name + ] + rels = get_relationships_for_objects( + grpc_handler, + project_lvs, + "featureView", + project_name, + allow_cache, + ) + relationships_map.update(rels) + result["relationships"] = relationships_map + return result + + @router.get("/label_views/{name}") + def get_label_view( + name: str, + project: str = Query(...), + include_relationships: bool = Query( + False, description="Include relationships for this label view" + ), + allow_cache: bool = Query(True), + ): + req = RegistryServer_pb2.GetLabelViewRequest( + name=name, + project=project, + allow_cache=allow_cache, + ) + response = grpc_call(grpc_handler.GetLabelView, req) + response["type"] = "labelView" + + if include_relationships: + relationships = get_object_relationships( + grpc_handler, "featureView", name, project, allow_cache + ) + response["relationships"] = relationships + + return response + + return router diff --git a/sdk/python/feast/api/registry/rest/lineage.py b/sdk/python/feast/api/registry/rest/lineage.py index 250498fcf16..360d6210aa6 100644 --- a/sdk/python/feast/api/registry/rest/lineage.py +++ b/sdk/python/feast/api/registry/rest/lineage.py @@ -171,18 +171,21 @@ def get_complete_registry_data( "entities": project_resources.get("entities", []), "dataSources": project_resources.get("dataSources", []), "featureViews": project_resources.get("featureViews", []), + "labelViews": project_resources.get("labelViews", []), "featureServices": project_resources.get("featureServices", []), "features": project_resources.get("features", []), + "labels": project_resources.get("labels", []), }, "relationships": lineage_response.get("relationships", []), "indirectRelationships": lineage_response.get("indirectRelationships", []), "pagination": { - # Get pagination metadata from project_resources if available, otherwise use empty dicts "entities": pagination.get("entities", {}), "dataSources": pagination.get("dataSources", {}), "featureViews": pagination.get("featureViews", {}), + "labelViews": pagination.get("labelViews", {}), "featureServices": pagination.get("featureServices", {}), "features": pagination.get("features", {}), + "labels": pagination.get("labels", {}), "relationships": lineage_response.get("relationshipsPagination", {}), "indirectRelationships": lineage_response.get( "indirectRelationshipsPagination", {} @@ -263,10 +266,14 @@ def get_complete_registry_data_all( ds["project"] = project_name for fv in project_resources.get("featureViews", []): fv["project"] = project_name + for lv in project_resources.get("labelViews", []): + lv["project"] = project_name for fs in project_resources.get("featureServices", []): fs["project"] = project_name for feat in project_resources.get("features", []): feat["project"] = project_name + for lbl in project_resources.get("labels", []): + lbl["project"] = project_name all_data.append( { "project": project_name, @@ -274,8 +281,10 @@ def get_complete_registry_data_all( "entities": project_resources.get("entities", []), "dataSources": project_resources.get("dataSources", []), "featureViews": project_resources.get("featureViews", []), + "labelViews": project_resources.get("labelViews", []), "featureServices": project_resources.get("featureServices", []), "features": project_resources.get("features", []), + "labels": project_resources.get("labels", []), }, "relationships": lineage_response.get("relationships", []), "indirectRelationships": lineage_response.get( diff --git a/sdk/python/feast/api/registry/rest/metrics.py b/sdk/python/feast/api/registry/rest/metrics.py index 58dc7156144..e2249c7a420 100644 --- a/sdk/python/feast/api/registry/rest/metrics.py +++ b/sdk/python/feast/api/registry/rest/metrics.py @@ -11,6 +11,9 @@ grpc_call, paginate_and_sort, ) +from feast.errors import FeastObjectNotFoundException +from feast.permissions.action import AuthzedAction +from feast.permissions.security_manager import assert_permissions from feast.protos.feast.registry import RegistryServer_pb2 @@ -65,77 +68,163 @@ async def resource_counts( ), allow_cache: bool = Query(True), ): - def count_resources_for_project(project_name: str): - entities = grpc_call( - grpc_handler.ListEntities, - RegistryServer_pb2.ListEntitiesRequest( - project=project_name, allow_cache=allow_cache - ), - ) - data_sources = grpc_call( - grpc_handler.ListDataSources, - RegistryServer_pb2.ListDataSourcesRequest( - project=project_name, allow_cache=allow_cache - ), - ) + """ + Resource counts and feature store inventory metadata. + + Returns counts per resource type, plus enriched summaries: + feature services (names), feature views (with per-view feature + count and materialization info), project list, and the registry + last-updated timestamp. + """ + + def get_registry_last_updated() -> Optional[str]: + """Read registry last_updated from in-process registry (not the Proto gRPC RPC).""" try: - saved_datasets = grpc_call( + from google.protobuf.json_format import MessageToDict + + registry = getattr(grpc_handler, "proxied_registry", None) + if registry is None: + return None + registry_proto = registry.proto() + if registry_proto is None or not registry_proto.HasField( + "last_updated" + ): + return None + return MessageToDict(registry_proto).get("lastUpdated") + except Exception: + return None + + def _extract_fv_summary(any_fv: dict, project_name: str) -> Optional[Dict]: + fv = _extract_feature_view_from_any(any_fv) + if not fv: + return None + spec = fv.get("spec", {}) + features = spec.get("features", []) + return { + "name": spec.get("name", ""), + "project": project_name, + "type": fv.get("type", "featureView"), + "featureCount": len(features) if isinstance(features, list) else 0, + } + + def collect_resources_for_project(project_name: str) -> dict: + entities_list: list = [] + try: + entities_resp = grpc_call( + grpc_handler.ListEntities, + RegistryServer_pb2.ListEntitiesRequest( + project=project_name, allow_cache=allow_cache + ), + ) + entities_list = entities_resp.get("entities", []) + except Exception: + pass + + data_sources_list: list = [] + try: + ds_resp = grpc_call( + grpc_handler.ListDataSources, + RegistryServer_pb2.ListDataSourcesRequest( + project=project_name, allow_cache=allow_cache + ), + ) + data_sources_list = ds_resp.get("dataSources", []) + except Exception: + pass + + saved_datasets_list: list = [] + try: + sd_resp = grpc_call( grpc_handler.ListSavedDatasets, RegistryServer_pb2.ListSavedDatasetsRequest( project=project_name, allow_cache=allow_cache ), ) + saved_datasets_list = sd_resp.get("savedDatasets", []) except Exception: - saved_datasets = {"savedDatasets": []} + pass + + features_list: list = [] try: - features = grpc_call( + feat_resp = grpc_call( grpc_handler.ListFeatures, RegistryServer_pb2.ListFeaturesRequest( project=project_name, allow_cache=allow_cache ), ) + features_list = feat_resp.get("features", []) except Exception: - features = {"features": []} + pass + + raw_fv_list: list = [] + fv_summaries: List[Dict] = [] try: - feature_views = grpc_call( + fv_resp = grpc_call( grpc_handler.ListAllFeatureViews, RegistryServer_pb2.ListAllFeatureViewsRequest( project=project_name, allow_cache=allow_cache ), ) + raw_fv_list = fv_resp.get("featureViews", []) + for any_fv in raw_fv_list: + summary = _extract_fv_summary(any_fv, project_name) + if summary: + fv_summaries.append(summary) except Exception: - feature_views = {"featureViews": []} + pass + + fs_summaries: List[Dict] = [] + raw_fs_list: list = [] try: - feature_services = grpc_call( + fs_resp = grpc_call( grpc_handler.ListFeatureServices, RegistryServer_pb2.ListFeatureServicesRequest( project=project_name, allow_cache=allow_cache ), ) + raw_fs_list = fs_resp.get("featureServices", []) + for fs in raw_fs_list: + spec = fs.get("spec", {}) + fs_summaries.append( + {"name": spec.get("name", ""), "project": project_name} + ) except Exception: - feature_services = {"featureServices": []} + pass + return { - "entities": len(entities.get("entities", [])), - "dataSources": len(data_sources.get("dataSources", [])), - "savedDatasets": len(saved_datasets.get("savedDatasets", [])), - "features": len(features.get("features", [])), - "featureViews": len(feature_views.get("featureViews", [])), - "featureServices": len(feature_services.get("featureServices", [])), + "counts": { + "entities": len(entities_list), + "dataSources": len(data_sources_list), + "savedDatasets": len(saved_datasets_list), + "features": len(features_list), + "featureViews": len(fv_summaries), + "featureServices": len(fs_summaries), + }, + "featureServices": fs_summaries, + "featureViews": fv_summaries, } + registry_last_updated = get_registry_last_updated() + if project: - counts = count_resources_for_project(project) - return {"project": project, "counts": counts} + resources = collect_resources_for_project(project) + return { + "project": project, + "counts": resources["counts"], + "featureServices": resources["featureServices"], + "featureViews": resources["featureViews"], + "projects": [{"name": project}], + "registryLastUpdated": registry_last_updated, + } else: - # List all projects via gRPC projects_resp = grpc_call( grpc_handler.ListProjects, RegistryServer_pb2.ListProjectsRequest(allow_cache=allow_cache), ) - all_projects = [ - p["spec"]["name"] for p in projects_resp.get("projects", []) - ] - all_counts = {} + all_projects = projects_resp.get("projects", []) + project_names = [p["spec"]["name"] for p in all_projects if "spec" in p] + + all_counts: Dict[str, dict] = {} total_counts = { "entities": 0, "dataSources": 0, @@ -144,12 +233,37 @@ def count_resources_for_project(project_name: str): "featureViews": 0, "featureServices": 0, } - for project_name in all_projects: - counts = count_resources_for_project(project_name) - all_counts[project_name] = counts + all_fs: List[Dict] = [] + all_fv: List[Dict] = [] + project_summaries: List[Dict] = [] + + for pname in project_names: + resources = collect_resources_for_project(pname) + counts = resources["counts"] + all_counts[pname] = counts for k in total_counts: total_counts[k] += counts[k] - return {"total": total_counts, "perProject": all_counts} + all_fs.extend(resources["featureServices"]) + all_fv.extend(resources["featureViews"]) + proj_info: Dict = next( + (p for p in all_projects if p.get("spec", {}).get("name") == pname), + {}, + ) + project_summaries.append( + { + "name": pname, + "description": proj_info.get("spec", {}).get("description", ""), + } + ) + + return { + "total": total_counts, + "perProject": all_counts, + "featureServices": all_fs, + "featureViews": all_fv, + "projects": project_summaries, + "registryLastUpdated": registry_last_updated, + } @router.get( "/metrics/popular_tags", tags=["Metrics"], response_model=PopularTagsResponse @@ -322,15 +436,21 @@ async def recently_visited( key = f"recently_visited_{user}" visits = [] if project: - try: - visits_json = ( - server.registry.get_project_metadata(project, key) - if server - else None - ) - visits = json.loads(visits_json) if visits_json else [] - except Exception: - visits = [] + if server: + try: + project_obj = server.registry.get_project( + name=project, allow_cache=True + ) + assert_permissions( + resource=project_obj, actions=[AuthzedAction.DESCRIBE] + ) + except FeastObjectNotFoundException: + pass + try: + visits_json = server.registry.get_project_metadata(project, key) + visits = json.loads(visits_json) if visits_json else [] + except Exception: + visits = [] else: try: if server: diff --git a/sdk/python/feast/api/registry/rest/monitoring.py b/sdk/python/feast/api/registry/rest/monitoring.py new file mode 100644 index 00000000000..e4b614d5e52 --- /dev/null +++ b/sdk/python/feast/api/registry/rest/monitoring.py @@ -0,0 +1,399 @@ +import logging +from datetime import date +from typing import Any, Dict, List, Optional + +from fastapi import APIRouter, HTTPException, Query +from pydantic import BaseModel, Field + +from feast.infra.offline_stores.offline_store import OfflineStore +from feast.permissions.action import AuthzedAction +from feast.permissions.security_manager import assert_permissions + +logger = logging.getLogger(__name__) + +VALID_GRANULARITIES = OfflineStore.MONITORING_VALID_GRANULARITIES + + +class ComputeMetricsRequest(BaseModel): + project: str + feature_view_name: Optional[str] = None + feature_names: Optional[List[str]] = None + start_date: Optional[str] = None + end_date: Optional[str] = None + granularity: str = Field("daily") + set_baseline: bool = False + + +class AutoComputeRequest(BaseModel): + project: str + feature_view_name: Optional[str] = None + + +class ComputeLogMetricsRequest(BaseModel): + project: str + feature_service_name: str + start_date: Optional[str] = None + end_date: Optional[str] = None + granularity: str = Field("daily") + set_baseline: bool = False + + +class AutoComputeLogRequest(BaseModel): + project: str + feature_service_name: Optional[str] = None + + +class ComputeTransientRequest(BaseModel): + project: str + feature_view_name: str + feature_names: Optional[List[str]] = None + start_date: Optional[str] = None + end_date: Optional[str] = None + + +def get_monitoring_router(grpc_handler, store=None): + router = APIRouter() + + _monitoring_service = None + + def _get_monitoring_service(): + nonlocal _monitoring_service + if _monitoring_service is None: + if store is None: + raise HTTPException( + status_code=503, + detail="Monitoring service is not available: no FeatureStore configured", + ) + from feast.monitoring.monitoring_service import MonitoringService + + _monitoring_service = MonitoringService(store) + return _monitoring_service + + def _get_store(): + if store is None: + raise HTTPException( + status_code=503, + detail="Monitoring service is not available: no FeatureStore configured", + ) + return store + + # ------------------------------------------------------------------ # + # DQM Job: submit and track + # ------------------------------------------------------------------ # + + @router.post("/monitoring/compute", tags=["Monitoring"]) + async def compute_metrics(request: ComputeMetricsRequest): + """Submit a DQM job to compute and store metrics. Returns job_id. + + When set_baseline is True and no date range is provided, computes + baseline from all available source data. + """ + store = _get_store() + if request.feature_view_name: + fv = store.registry.get_feature_view( + name=request.feature_view_name, project=request.project + ) + assert_permissions(fv, actions=[AuthzedAction.UPDATE]) + + svc = _get_monitoring_service() + + if request.set_baseline and not request.start_date and not request.end_date: + try: + result = svc.compute_baseline( + project=request.project, + feature_view_name=request.feature_view_name, + feature_names=request.feature_names, + ) + return result + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + if request.granularity not in VALID_GRANULARITIES: + raise HTTPException( + status_code=400, + detail=f"Invalid granularity '{request.granularity}'. " + f"Must be one of {VALID_GRANULARITIES}", + ) + + params: Dict[str, Any] = {} + if request.start_date: + params["start_date"] = request.start_date + if request.end_date: + params["end_date"] = request.end_date + if request.feature_names: + params["feature_names"] = request.feature_names + params["granularity"] = request.granularity + params["set_baseline"] = request.set_baseline + + job_id = svc.submit_job( + project=request.project, + job_type="compute", + feature_view_name=request.feature_view_name, + parameters=params, + ) + + try: + result = svc.execute_job(job_id) + return {"job_id": job_id, **result} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + @router.post("/monitoring/auto_compute", tags=["Monitoring"]) + async def auto_compute(request: AutoComputeRequest): + """Auto-detect date ranges and compute all granularities.""" + store = _get_store() + if request.feature_view_name: + fv = store.registry.get_feature_view( + name=request.feature_view_name, project=request.project + ) + assert_permissions(fv, actions=[AuthzedAction.UPDATE]) + + svc = _get_monitoring_service() + + job_id = svc.submit_job( + project=request.project, + job_type="auto_compute", + feature_view_name=request.feature_view_name, + ) + + try: + result = svc.execute_job(job_id) + return {"job_id": job_id, **result} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + # ------------------------------------------------------------------ # + # Log source: compute from feature serving logs + # ------------------------------------------------------------------ # + + @router.post("/monitoring/compute/log", tags=["Monitoring"]) + async def compute_log_metrics(request: ComputeLogMetricsRequest): + """Compute metrics from feature serving logs for a feature service.""" + if request.granularity not in VALID_GRANULARITIES: + raise HTTPException( + status_code=400, + detail=f"Invalid granularity '{request.granularity}'. " + f"Must be one of {VALID_GRANULARITIES}", + ) + + store = _get_store() + fs = store.registry.get_feature_service( + name=request.feature_service_name, project=request.project + ) + assert_permissions(fs, actions=[AuthzedAction.UPDATE]) + + svc = _get_monitoring_service() + + start_d = date.fromisoformat(request.start_date) if request.start_date else None + end_d = date.fromisoformat(request.end_date) if request.end_date else None + + try: + result = svc.compute_log_metrics( + project=request.project, + feature_service_name=request.feature_service_name, + start_date=start_d, + end_date=end_d, + granularity=request.granularity, + set_baseline=request.set_baseline, + ) + return result + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + @router.post("/monitoring/auto_compute/log", tags=["Monitoring"]) + async def auto_compute_log(request: AutoComputeLogRequest): + """Auto-detect date ranges from log data and compute all granularities.""" + store = _get_store() + if request.feature_service_name: + fs = store.registry.get_feature_service( + name=request.feature_service_name, project=request.project + ) + assert_permissions(fs, actions=[AuthzedAction.UPDATE]) + + svc = _get_monitoring_service() + try: + result = svc.auto_compute_log_metrics( + project=request.project, + feature_service_name=request.feature_service_name, + ) + return result + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + @router.get("/monitoring/jobs/{job_id}", tags=["Monitoring"]) + async def get_job_status(job_id: str): + svc = _get_monitoring_service() + job = svc.get_job(job_id) + if job is None: + raise HTTPException(status_code=404, detail=f"Job '{job_id}' not found") + return job + + # ------------------------------------------------------------------ # + # Transient compute (not stored) + # ------------------------------------------------------------------ # + + @router.post("/monitoring/compute/transient", tags=["Monitoring"]) + async def compute_transient(request: ComputeTransientRequest): + """Compute metrics on-the-fly for an arbitrary date range. Results are + returned directly and NOT persisted to the monitoring tables.""" + store = _get_store() + fv = store.registry.get_feature_view( + name=request.feature_view_name, project=request.project + ) + assert_permissions(fv, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + + start_d = date.fromisoformat(request.start_date) if request.start_date else None + end_d = date.fromisoformat(request.end_date) if request.end_date else None + + result = svc.compute_transient( + project=request.project, + feature_view_name=request.feature_view_name, + feature_names=request.feature_names, + start_date=start_d, + end_date=end_d, + ) + return result + + # ------------------------------------------------------------------ # + # Read endpoints + # ------------------------------------------------------------------ # + + @router.get("/monitoring/metrics/features", tags=["Monitoring"]) + async def get_feature_metrics( + project: str = Query(...), + feature_view_name: Optional[str] = Query(None), + feature_name: Optional[str] = Query(None), + feature_service_name: Optional[str] = Query(None), + granularity: Optional[str] = Query(None), + data_source_type: Optional[str] = Query(None), + start_date: Optional[str] = Query(None), + end_date: Optional[str] = Query(None), + ): + store = _get_store() + if feature_view_name: + fv = store.registry.get_feature_view( + name=feature_view_name, project=project + ) + assert_permissions(fv, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + return svc.get_feature_metrics( + project=project, + feature_service_name=feature_service_name, + feature_view_name=feature_view_name, + feature_name=feature_name, + granularity=granularity, + data_source_type=data_source_type, + start_date=date.fromisoformat(start_date) if start_date else None, + end_date=date.fromisoformat(end_date) if end_date else None, + ) + + @router.get("/monitoring/metrics/feature_views", tags=["Monitoring"]) + async def get_feature_view_metrics( + project: str = Query(...), + feature_view_name: Optional[str] = Query(None), + feature_service_name: Optional[str] = Query(None), + granularity: Optional[str] = Query(None), + data_source_type: Optional[str] = Query(None), + start_date: Optional[str] = Query(None), + end_date: Optional[str] = Query(None), + ): + store = _get_store() + if feature_view_name: + fv = store.registry.get_feature_view( + name=feature_view_name, project=project + ) + assert_permissions(fv, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + return svc.get_feature_view_metrics( + project=project, + feature_service_name=feature_service_name, + feature_view_name=feature_view_name, + granularity=granularity, + data_source_type=data_source_type, + start_date=date.fromisoformat(start_date) if start_date else None, + end_date=date.fromisoformat(end_date) if end_date else None, + ) + + @router.get("/monitoring/metrics/feature_services", tags=["Monitoring"]) + async def get_feature_service_metrics( + project: str = Query(...), + feature_service_name: Optional[str] = Query(None), + granularity: Optional[str] = Query(None), + data_source_type: Optional[str] = Query(None), + start_date: Optional[str] = Query(None), + end_date: Optional[str] = Query(None), + ): + store = _get_store() + if feature_service_name: + fs = store.registry.get_feature_service( + name=feature_service_name, project=project + ) + assert_permissions(fs, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + return svc.get_feature_service_metrics( + project=project, + feature_service_name=feature_service_name, + granularity=granularity, + data_source_type=data_source_type, + start_date=date.fromisoformat(start_date) if start_date else None, + end_date=date.fromisoformat(end_date) if end_date else None, + ) + + @router.get("/monitoring/metrics/baseline", tags=["Monitoring"]) + async def get_baseline( + project: str = Query(...), + feature_view_name: Optional[str] = Query(None), + feature_name: Optional[str] = Query(None), + data_source_type: Optional[str] = Query(None), + ): + store = _get_store() + if feature_view_name: + fv = store.registry.get_feature_view( + name=feature_view_name, project=project + ) + assert_permissions(fv, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + return svc.get_baseline( + project=project, + feature_view_name=feature_view_name, + feature_name=feature_name, + data_source_type=data_source_type, + ) + + @router.get("/monitoring/metrics/timeseries", tags=["Monitoring"]) + async def get_timeseries( + project: str = Query(...), + feature_view_name: Optional[str] = Query(None), + feature_name: Optional[str] = Query(None), + feature_service_name: Optional[str] = Query(None), + granularity: Optional[str] = Query(None), + data_source_type: Optional[str] = Query(None), + start_date: Optional[str] = Query(None), + end_date: Optional[str] = Query(None), + ): + store = _get_store() + if feature_view_name: + fv = store.registry.get_feature_view( + name=feature_view_name, project=project + ) + assert_permissions(fv, actions=[AuthzedAction.DESCRIBE]) + + svc = _get_monitoring_service() + return svc.get_timeseries( + project=project, + feature_view_name=feature_view_name, + feature_name=feature_name, + feature_service_name=feature_service_name, + granularity=granularity, + data_source_type=data_source_type, + start_date=date.fromisoformat(start_date) if start_date else None, + end_date=date.fromisoformat(end_date) if end_date else None, + ) + + return router diff --git a/sdk/python/feast/api/registry/rest/rest_registry_server.py b/sdk/python/feast/api/registry/rest/rest_registry_server.py index d67321abc48..d440c74d7ed 100644 --- a/sdk/python/feast/api/registry/rest/rest_registry_server.py +++ b/sdk/python/feast/api/registry/rest/rest_registry_server.py @@ -76,6 +76,21 @@ def __init__(self, store: FeatureStore): self._init_auth() self._register_routes() + registry_cfg = getattr(store.config, "registry", None) + mcp_cfg = getattr(registry_cfg, "mcp", None) + if mcp_cfg and getattr(mcp_cfg, "enabled", False) is True: + try: + from fastapi_mcp import FastApiMCP + + mcp = FastApiMCP(self.app, name="feast-registry-mcp") + mcp.mount() + logger.info("MCP support enabled on REST registry server") + except ImportError: + logger.warning( + "MCP support requested but fastapi_mcp is not installed. " + "Install it with: pip install feast[mcp]" + ) + def _add_exception_handlers(self): """Add custom exception handlers to include HTTP status codes in JSON responses.""" @@ -220,28 +235,35 @@ async def dispatch(self, request: Request, call_next): else: object_type = None object_name = None - visit = { - "path": path, - "timestamp": _utc_now().isoformat(), - "project": project, - "user": user, - "object": object_type, - "object_name": object_name, - "method": method, - } - try: - visits_json = self.registry.get_project_metadata(project, key) - visits = json.loads(visits_json) if visits_json else [] - except Exception: - visits = [] - visits.append(visit) - visits = visits[-self.recent_visits_limit :] - try: - self.registry.set_project_metadata( - project, key, json.dumps(visits) - ) - except Exception as e: - logger.warning(f"Failed to persist recent visits: {e}") + + response = await call_next(request) + + if response.status_code < 400: + visit = { + "path": path, + "timestamp": _utc_now().isoformat(), + "project": project, + "user": user, + "object": object_type, + "object_name": object_name, + "method": method, + } + try: + visits_json = self.registry.get_project_metadata( + project, key + ) + visits = json.loads(visits_json) if visits_json else [] + except Exception: + visits = [] + visits.append(visit) + visits = visits[-self.recent_visits_limit :] + try: + self.registry.set_project_metadata( + project, key, json.dumps(visits) + ) + except Exception as e: + logger.warning(f"Failed to persist recent visits: {e}") + return response response = await call_next(request) return response diff --git a/sdk/python/feast/api/registry/rest/rest_utils.py b/sdk/python/feast/api/registry/rest/rest_utils.py index 4c517b0abdf..d0c7029500b 100644 --- a/sdk/python/feast/api/registry/rest/rest_utils.py +++ b/sdk/python/feast/api/registry/rest/rest_utils.py @@ -130,6 +130,7 @@ def aggregate_across_projects( sort_by: Optional[str] = None, sort_order: str = "asc", include_relationships: bool = False, + extra_request_params: Optional[Dict] = None, ) -> Dict: """ Fetches and aggregates objects across all projects, adds project field, handles relationships, and paginates/sorts. @@ -147,6 +148,7 @@ def aggregate_across_projects( req = request_cls( project=project_name, allow_cache=allow_cache, + **(extra_request_params or {}), ) response = grpc_call(list_method, req) objects = response.get(response_key, []) @@ -434,9 +436,11 @@ def get_all_project_resources( "entities": [], "dataSources": [], "featureViews": [], + "labelViews": [], "featureServices": [], "savedDatasets": [], "features": [], + "labels": [], "pagination": {}, "errors": [], } @@ -484,6 +488,18 @@ def get_all_project_resources( if err_msg: errors.append(err_msg) + # Get label views + resources["labelViews"], pagination["labelViews"], err_msg = list_label_views( + grpc_handler=grpc_handler, + project=project, + allow_cache=allow_cache, + tags=tags, + pagination_params=pagination_params, + sorting_params=sorting_params, + ) + if err_msg: + errors.append(err_msg) + # Get feature services resources["featureServices"], pagination["featureServices"], err_msg = ( list_feature_services( @@ -523,6 +539,17 @@ def get_all_project_resources( if err_msg: errors.append(err_msg) + # Get labels + resources["labels"], pagination["labels"], err_msg = list_labels( + grpc_handler=grpc_handler, + project=project, + allow_cache=allow_cache, + pagination_params=pagination_params, + sorting_params=sorting_params, + ) + if err_msg: + errors.append(err_msg) + except Exception as e: err_msg = f"Error getting resources for project '{project}'" errors.append(err_msg) @@ -884,6 +911,87 @@ def list_features( return features, pagination, err_msg +def list_label_views( + grpc_handler, + project: str, + allow_cache: bool, + tags: Optional[Dict[str, str]] = None, + pagination_params: Optional[dict] = None, + sorting_params: Optional[dict] = None, +) -> tuple[List[Dict[str, Any]], Dict[str, Any], str]: + """List label views in a project with optional sorting and pagination""" + label_views: List[Dict[str, Any]] = [] + pagination: Dict[str, Any] = {} + err_msg = "" + + grpc_pagination = None + grpc_sorting = None + + if pagination_params: + grpc_pagination = create_grpc_pagination_params(pagination_params) + if sorting_params: + grpc_sorting = create_grpc_sorting_params(sorting_params) + + try: + req = RegistryServer_pb2.ListLabelViewsRequest( + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, + tags=tags, + ) + response = grpc_call(grpc_handler.ListLabelViews, req) + label_views, pagination = ( + response.get("labelViews", []), + response.get("pagination", {}), + ) + except Exception as e: + err_msg = f"Error searching label views in project '{project}'" + logger.error(f"{err_msg}: {e}") + finally: + return label_views, pagination, err_msg + + +def list_labels( + grpc_handler, + project: str, + allow_cache: bool, + pagination_params: Optional[dict] = None, + sorting_params: Optional[dict] = None, +) -> tuple[List[Dict[str, Any]], Dict[str, Any], str]: + """List labels in a project with optional sorting and pagination""" + labels: List[Dict[str, Any]] = [] + pagination: Dict[str, Any] = {} + err_msg = "" + + grpc_pagination = None + grpc_sorting = None + + if pagination_params: + grpc_pagination = create_grpc_pagination_params(pagination_params) + if sorting_params: + grpc_sorting = create_grpc_sorting_params(sorting_params) + + try: + req = RegistryServer_pb2.ListFeaturesRequest( + project=project, + allow_cache=allow_cache, + pagination=grpc_pagination, + sorting=grpc_sorting, + kind="label", + ) + response = grpc_call(grpc_handler.ListFeatures, req) + labels, pagination = ( + response.get("features", []), + response.get("pagination", {}), + ) + except Exception as e: + err_msg = f"Error searching labels in project '{project}'" + logger.error(f"{err_msg}: {e}") + finally: + return labels, pagination, err_msg + + def list_all_projects( grpc_handler, allow_cache: bool, diff --git a/sdk/python/feast/api/registry/rest/search.py b/sdk/python/feast/api/registry/rest/search.py index e670a8981ac..572e34c12d8 100644 --- a/sdk/python/feast/api/registry/rest/search.py +++ b/sdk/python/feast/api/registry/rest/search.py @@ -158,6 +158,19 @@ def search_resources( } ) + # Extract and convert label views + label_views = project_resources.get("labelViews", []) + for lv in label_views: + results.append( + { + "type": "labelView", + "name": lv.get("spec", {}).get("name", ""), + "description": lv.get("spec", {}).get("description", ""), + "project": current_project, + "tags": lv.get("spec", {}).get("tags", {}), + } + ) + # Extract and convert features features = project_resources.get("features", []) for feature in features: @@ -172,6 +185,20 @@ def search_resources( } ) + # Extract and convert labels + labels = project_resources.get("labels", []) + for label in labels: + results.append( + { + "type": "label", + "name": label.get("name", ""), + "description": label.get("description", ""), + "project": current_project, + "labelView": label.get("featureView", ""), + "tags": label.get("tags", {}), + } + ) + # Extract and convert feature services feature_services = project_resources.get("featureServices", []) for fs in feature_services: diff --git a/sdk/python/feast/arrow_error_handler.py b/sdk/python/feast/arrow_error_handler.py index e4862bb0982..59f889a0a34 100644 --- a/sdk/python/feast/arrow_error_handler.py +++ b/sdk/python/feast/arrow_error_handler.py @@ -1,4 +1,6 @@ +import json import logging +import time from functools import wraps import pyarrow.flight as fl @@ -7,17 +9,45 @@ logger = logging.getLogger(__name__) +BACKOFF_FACTOR = 0.5 + def arrow_client_error_handling_decorator(func): @wraps(func) def wrapper(*args, **kwargs): - try: - return func(*args, **kwargs) - except Exception as e: - mapped_error = FeastError.from_error_detail(_get_exception_data(e.args[0])) - if mapped_error is not None: - raise mapped_error - raise e + # Retry only applies to FeastFlightClient methods where args[0] (self) + # carries _connection_retries from RemoteOfflineStoreConfig. + # Standalone stream functions (write_table, read_all) get 0 retries: + # broken streams can't be reused and retrying risks duplicate writes. + max_retries = max(0, getattr(args[0], "_connection_retries", 0)) if args else 0 + + for attempt in range(max_retries + 1): + try: + return func(*args, **kwargs) + except fl.FlightUnavailableError as e: + if attempt < max_retries: + wait_time = BACKOFF_FACTOR * (2**attempt) + logger.warning( + "Transient Arrow Flight error on attempt %d/%d, " + "retrying in %.1fs: %s", + attempt + 1, + max_retries + 1, + wait_time, + e, + ) + time.sleep(wait_time) + continue + mapped_error = FeastError.from_error_detail(_get_exception_data(str(e))) + if mapped_error is not None: + raise mapped_error + raise e + except Exception as e: + mapped_error = FeastError.from_error_detail( + _get_exception_data(e.args[0]) + ) + if mapped_error is not None: + raise mapped_error + raise e return wrapper @@ -38,15 +68,27 @@ def wrapper(*args, **kwargs): def _get_exception_data(except_str) -> str: - substring = "Flight error: " + if not isinstance(except_str, str): + return "" - # Find the starting index of the substring + substring = "Flight error: " position = except_str.find(substring) - end_json_index = except_str.find("}") + if position == -1: + return "" - if position != -1 and end_json_index != -1: - # Extract the part of the string after the substring - result = except_str[position + len(substring) : end_json_index + 1] - return result + search_start = position + len(substring) + json_start = except_str.find("{", search_start) + if json_start == -1: + return "" - return "" + search_pos = json_start + while True: + json_end = except_str.find("}", search_pos + 1) + if json_end == -1: + return "" + candidate = except_str[json_start : json_end + 1] + try: + json.loads(candidate) + return candidate + except (json.JSONDecodeError, ValueError): + search_pos = json_end diff --git a/sdk/python/feast/base_feature_view.py b/sdk/python/feast/base_feature_view.py index 478058c89b3..170beb73609 100644 --- a/sdk/python/feast/base_feature_view.py +++ b/sdk/python/feast/base_feature_view.py @@ -22,6 +22,7 @@ from feast.feature_view_projection import FeatureViewProjection from feast.field import Field from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( OnDemandFeatureView as OnDemandFeatureViewProto, ) @@ -56,6 +57,8 @@ class BaseFeatureView(ABC): projection: FeatureViewProjection created_timestamp: Optional[datetime] last_updated_timestamp: Optional[datetime] + version: str + current_version_number: Optional[int] @abstractmethod def __init__( @@ -92,6 +95,10 @@ def __init__( self.projection = FeatureViewProjection.from_definition(self) self.created_timestamp = None self.last_updated_timestamp = None + if not hasattr(self, "version"): + self.version = "latest" + if not hasattr(self, "current_version_number"): + self.current_version_number = None self.source = source @@ -103,7 +110,12 @@ def proto_class(self) -> Type[Message]: @abstractmethod def to_proto( self, - ) -> Union[FeatureViewProto, OnDemandFeatureViewProto, StreamFeatureViewProto]: + ) -> Union[ + FeatureViewProto, + OnDemandFeatureViewProto, + StreamFeatureViewProto, + LabelViewProto, + ]: pass @classmethod @@ -147,6 +159,17 @@ def __getitem__(self, item): return cp + def _schema_or_udf_changed(self, other: "BaseFeatureView") -> bool: + """Check if schema or UDF-related fields have changed (version-worthy changes). + + Callers always match by name first, so name comparison is omitted here. + """ + if sorted(self.features) != sorted(other.features): + return True + # Skip metadata: description, tags, owner, projection + # Skip source changes: treat as deployment/location details, not schema changes + return False + def __eq__(self, other): if not isinstance(other, BaseFeatureView): raise TypeError( @@ -178,6 +201,18 @@ def ensure_valid(self): """ if not self.name: raise ValueError("Feature view needs a name.") + if "@" in self.name: + raise ValueError( + f"Feature view name '{self.name}' must not contain '@'. " + f"The '@' character is reserved for version-qualified references " + f"(e.g., 'fv@v2:feature')." + ) + if ":" in self.name: + raise ValueError( + f"Feature view name '{self.name}' must not contain ':'. " + f"The ':' character is reserved as the separator in fully qualified " + f"feature references (e.g., 'feature_view:feature_name')." + ) def with_name(self, name: str): """ diff --git a/sdk/python/feast/batch_feature_view.py b/sdk/python/feast/batch_feature_view.py index 925d70e58ab..0bfbdf9d936 100644 --- a/sdk/python/feast/batch_feature_view.py +++ b/sdk/python/feast/batch_feature_view.py @@ -93,6 +93,7 @@ def __init__( offline: bool = False, description: str = "", owner: str = "", + org: str = "", schema: Optional[List[Field]] = None, udf: Optional[Callable[[Any], Any]] = None, udf_string: Optional[str] = "", @@ -100,6 +101,7 @@ def __init__( batch_engine: Optional[Dict[str, Any]] = None, aggregations: Optional[List[Aggregation]] = None, enable_validation: bool = False, + version: str = "latest", ): if not flags_helper.is_test(): warnings.warn( @@ -150,11 +152,13 @@ def __init__( offline=offline, description=description, owner=owner, + org=org, schema=schema, source=source, # type: ignore[arg-type] sink_source=sink_source, mode=mode, enable_validation=enable_validation, + version=version, ) def get_feature_transformation(self) -> Optional[Transformation]: @@ -165,13 +169,14 @@ def get_feature_transformation(self) -> Optional[Transformation]: TransformationMode.PYTHON, TransformationMode.SQL, TransformationMode.RAY, - ) or self.mode in ("pandas", "python", "sql", "ray"): + TransformationMode.FLINK, + ) or self.mode in ("pandas", "python", "sql", "ray", "flink"): return Transformation( mode=self.mode, udf=self.udf, udf_string=self.udf_string or "" ) else: raise ValueError( - f"Unsupported transformation mode: {self.mode} for StreamFeatureView" + f"Unsupported transformation mode: {self.mode} for BatchFeatureView" ) @@ -187,8 +192,10 @@ def batch_feature_view( offline: bool = True, description: str = "", owner: str = "", + org: str = "", schema: Optional[List[Field]] = None, enable_validation: bool = False, + version: str = "latest", ): """ Creates a BatchFeatureView object with the given user-defined function (UDF) as the transformation. @@ -216,10 +223,12 @@ def decorator(user_function): offline=offline, description=description, owner=owner, + org=org, schema=schema, udf=user_function, udf_string=udf_string, enable_validation=enable_validation, + version=version, ) functools.update_wrapper(wrapper=batch_feature_view_obj, wrapped=user_function) return batch_feature_view_obj diff --git a/sdk/python/feast/chunker.py b/sdk/python/feast/chunker.py new file mode 100644 index 00000000000..484f2b398a8 --- /dev/null +++ b/sdk/python/feast/chunker.py @@ -0,0 +1,150 @@ +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Any, Optional + +import pandas as pd + + +@dataclass +class ChunkingConfig: + chunk_size: int = 100 + chunk_overlap: int = 20 + min_chunk_size: int = 20 + max_chunk_chars: Optional[int] = 500 + + +class BaseChunker(ABC): + """ + Abstract base class for document chunking. + + Subclasses implement load_parse_and_chunk() with their own: + - Loading logic + - Parsing logic + - Chunking strategy + """ + + def __init__(self, config: Optional[ChunkingConfig] = None): + self.config = config or ChunkingConfig() + + @abstractmethod + def load_parse_and_chunk( + self, + source: Any, + source_id: str, + source_column: str, + source_type: Optional[str] = None, + ) -> list[dict]: + """ + Load, parse, and chunk a document. + + Args: + source: File path, raw text, bytes, etc. + source_id: Document identifier. + source_type: Optional type hint. + source_column: The column containing the document sources. + + Returns: + List of chunk dicts with keys: + - chunk_id: str + - original_id: str + - text: str + - chunk_index: int + - (any additional metadata) + """ + pass + + def chunk_dataframe( + self, + df: pd.DataFrame, + id_column: str, + source_column: str, + type_column: Optional[str] = None, + ) -> pd.DataFrame: + """ + Chunk all documents in a DataFrame. + + Args: + df: The DataFrame containing the documents to chunk. + id_column: The column containing the document IDs. + source_column: The column containing the document sources. + type_column: The column containing the document types. + """ + + all_chunks = [] + for row in df.itertuples(index=False): + chunks = self.load_parse_and_chunk( + getattr(row, source_column), + str(getattr(row, id_column)), + source_column, + getattr(row, type_column) if type_column else None, + ) + all_chunks.extend(chunks) + + if not all_chunks: + return pd.DataFrame( + columns=["chunk_id", "original_id", source_column, "chunk_index"] + ) + return pd.DataFrame(all_chunks) + + +class TextChunker(BaseChunker): + """Default chunker for plain text. Chunks by word count.""" + + def load_parse_and_chunk( + self, + source: Any, + source_id: str, + source_column: str, + source_type: Optional[str] = None, + ) -> list[dict]: + # Load + text = self._load(source) + + # Chunk by words + return self._chunk_by_words(text, source_id, source_column) + + def _load(self, source: Any) -> str: + from pathlib import Path + + if isinstance(source, Path) and source.exists(): + return Path(source).read_text() + if isinstance(source, str): + if source.endswith(".txt") and Path(source).exists(): + return Path(source).read_text() + return str(source) + + def _chunk_by_words( + self, text: str, source_id: str, source_column: str + ) -> list[dict]: + words = text.split() + chunks = [] + + step = self.config.chunk_size - self.config.chunk_overlap + if step <= 0: + raise ValueError( + f"chunk_overlap ({self.config.chunk_overlap}) must be less than " + f"chunk_size ({self.config.chunk_size})" + ) + chunk_index = 0 + + for i in range(0, len(words), step): + chunk_words = words[i : i + self.config.chunk_size] + + if len(chunk_words) < self.config.min_chunk_size: + continue + + chunk_text = " ".join(chunk_words) + if self.config.max_chunk_chars: + chunk_text = chunk_text[: self.config.max_chunk_chars] + + chunks.append( + { + "chunk_id": f"{source_id}_{chunk_index}", + "original_id": source_id, + source_column: chunk_text, + "chunk_index": chunk_index, + } + ) + chunk_index += 1 + + return chunks diff --git a/sdk/python/feast/cli/cli.py b/sdk/python/feast/cli/cli.py index af746c8f3ef..3fd6f3319fb 100644 --- a/sdk/python/feast/cli/cli.py +++ b/sdk/python/feast/cli/cli.py @@ -1,593 +1,659 @@ -# Copyright 2019 The Feast Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import json -import logging -from datetime import datetime -from importlib.metadata import version as importlib_version -from pathlib import Path -from typing import List, Optional - -import click -import yaml -from colorama import Fore, Style -from dateutil import parser -from pygments import formatters, highlight, lexers - -from feast import utils -from feast.cli.data_sources import data_sources_cmd -from feast.cli.dbt_import import dbt_cmd -from feast.cli.entities import entities_cmd -from feast.cli.feature_services import feature_services_cmd -from feast.cli.feature_views import feature_views_cmd -from feast.cli.features import ( - features_cmd, - get_historical_features, - get_online_features, -) -from feast.cli.on_demand_feature_views import on_demand_feature_views_cmd -from feast.cli.permissions import feast_permissions_cmd -from feast.cli.projects import projects_cmd -from feast.cli.saved_datasets import saved_datasets_cmd -from feast.cli.serve import ( - serve_command, - serve_offline_command, - serve_registry_command, - serve_transformations_command, -) -from feast.cli.stream_feature_views import stream_feature_views_cmd -from feast.cli.ui import ui -from feast.cli.validation_references import validation_references_cmd -from feast.constants import FEAST_FS_YAML_FILE_PATH_ENV_NAME -from feast.errors import FeastProviderLoginError -from feast.repo_config import load_repo_config -from feast.repo_operations import ( - apply_total, - cli_check_repo, - create_feature_store, - generate_project_name, - init_repo, - plan, - registry_dump, - teardown, -) -from feast.utils import maybe_local_tz - -_logger = logging.getLogger(__name__) - - -class NoOptionDefaultFormat(click.Command): - def format_options(self, ctx: click.Context, formatter: click.HelpFormatter): - """Writes all the options into the formatter if they exist.""" - opts = [] - for param in self.get_params(ctx): - rv = param.get_help_record(ctx) - if rv is not None: - opts.append(rv) - if opts: - with formatter.section("Options(No current command options)"): - formatter.write_dl(opts) - - -@click.group() -@click.option( - "--chdir", - "-c", - envvar="FEATURE_REPO_DIR_ENV_VAR", - help="Switch to a different feature repository directory before executing the given subcommand. Can also be set via the FEATURE_REPO_DIR_ENV_VAR environment variable.", -) -@click.option( - "--log-level", - default="warning", - help="The logging level. One of DEBUG, INFO, WARNING, ERROR, and CRITICAL (case-insensitive).", -) -@click.option( - "--feature-store-yaml", - "-f", - help=f"Override the directory where the CLI should look for the feature_store.yaml file. Can also be set via the {FEAST_FS_YAML_FILE_PATH_ENV_NAME} environment variable.", -) -@click.pass_context -def cli( - ctx: click.Context, - chdir: Optional[str], - log_level: str, - feature_store_yaml: Optional[str], -): - """ - Feast CLI - - For more information, see our public docs at https://docs.feast.dev/ - """ - ctx.ensure_object(dict) - ctx.obj["CHDIR"] = Path.cwd() if chdir is None else Path(chdir).absolute() - ctx.obj["FS_YAML_FILE"] = ( - Path(feature_store_yaml).absolute() - if feature_store_yaml - else utils.get_default_yaml_file_path(ctx.obj["CHDIR"]) - ) - try: - level = getattr(logging, log_level.upper()) - logging.basicConfig( - format="%(asctime)s %(name)s %(levelname)s: %(message)s", - datefmt="%m/%d/%Y %I:%M:%S %p", - level=level, - ) - # Override the logging level for already created loggers (due to loggers being created at the import time) - # Note, that format & datefmt does not need to be set, because by default child loggers don't override them - - # Also note, that mypy complains that logging.root doesn't have "manager" because of the way it's written. - # So we have to put a type ignore hint for mypy. - for logger_name in logging.root.manager.loggerDict: # type: ignore - if "feast" in logger_name: - logger = logging.getLogger(logger_name) - logger.setLevel(level) - except Exception as e: - raise e - pass - - -@cli.command() -def version(): - """ - Display Feast SDK version - """ - print( - f'{Style.BRIGHT + Fore.BLUE}Feast SDK Version: {Style.BRIGHT + Fore.GREEN}"{importlib_version("feast")}"' - ) - - -@cli.command() -@click.argument("object_id") -@click.pass_context -def delete(ctx: click.Context, object_id: str): - """ - Delete Feast Object - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - store = create_feature_store(ctx) - - e = None - object_type = None - - # Order matters if names can overlap between types, - # though typically they shouldn't in a well-structured feature store. - object_getters_and_types = [ - (store.get_entity, "Entity"), - (store.get_feature_view, "FeatureView"), - (store.get_feature_service, "FeatureService"), - (store.get_data_source, "DataSource"), - (store.get_saved_dataset, "SavedDataset"), - (store.get_validation_reference, "ValidationReference"), - (store.get_stream_feature_view, "StreamFeatureView"), - (store.get_on_demand_feature_view, "OnDemandFeatureView"), - # Add other get_* methods here if needed - ] - - for getter, obj_type_str in object_getters_and_types: - try: - potential_e = getter(object_id) # type: ignore[operator] - if potential_e: - e = potential_e - object_type = obj_type_str - break - except Exception: - pass - - if isinstance(e, list): - e = e[0] - if e: - store.apply([e], objects_to_delete=[e], partial=False) - print( - f"{Style.BRIGHT + Fore.RED}Deleted {Style.BRIGHT + Fore.GREEN}{object_type} {Fore.YELLOW}{object_id} from {Fore.GREEN}{store.project}.{Style.RESET_ALL}" - ) - else: - print( - f"{Style.BRIGHT + Fore.GREEN}Object not found. Deletion skipped.{Style.RESET_ALL}" - ) - - -@cli.command() -@click.pass_context -def configuration(ctx: click.Context): - """ - Display Feast configuration - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - repo_config = load_repo_config(repo, fs_yaml_file) - if repo_config: - config_dict = repo_config.model_dump(by_alias=True, exclude_unset=True) - config_dict.pop("repo_path", None) - print(yaml.dump(config_dict, default_flow_style=False, sort_keys=False)) - else: - print("No configuration found.") - - -@cli.command() -@click.pass_context -def endpoint(ctx: click.Context): - """ - Display feature server endpoints - """ - store = create_feature_store(ctx) - endpoint = store.get_feature_server_endpoint() - if endpoint is not None: - _logger.info( - f"Feature server endpoint: {Style.BRIGHT + Fore.GREEN}{endpoint}{Style.RESET_ALL}" - ) - else: - _logger.info("There is no active feature server.") - - -@cli.command("plan", cls=NoOptionDefaultFormat) -@click.option( - "--skip-source-validation", - is_flag=True, - help="Don't validate the data sources by checking for that the tables exist.", -) -@click.option( - "--skip-feature-view-validation", - is_flag=True, - help="Don't validate feature views. Use with caution as this skips important checks.", -) -@click.pass_context -def plan_command( - ctx: click.Context, skip_source_validation: bool, skip_feature_view_validation: bool -): - """ - Create or update a feature store deployment - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - repo_config = load_repo_config(repo, fs_yaml_file) - try: - plan(repo_config, repo, skip_source_validation, skip_feature_view_validation) - except FeastProviderLoginError as e: - print(str(e)) - - -@cli.command("apply", cls=NoOptionDefaultFormat) -@click.option( - "--skip-source-validation", - is_flag=True, - help="Don't validate the data sources by checking for that the tables exist.", -) -@click.option( - "--skip-feature-view-validation", - is_flag=True, - help="Don't validate feature views. Use with caution as this skips important checks.", -) -@click.option( - "--no-progress", - is_flag=True, - help="Disable progress bars during apply operation.", -) -@click.pass_context -def apply_total_command( - ctx: click.Context, - skip_source_validation: bool, - skip_feature_view_validation: bool, - no_progress: bool, -): - """ - Create or update a feature store deployment - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - - repo_config = load_repo_config(repo, fs_yaml_file) - - # Set environment variable to disable progress if requested - if no_progress: - import os - - os.environ["FEAST_NO_PROGRESS"] = "1" - - try: - apply_total( - repo_config, - repo, - skip_source_validation, - skip_feature_view_validation, - ) - except FeastProviderLoginError as e: - print(str(e)) - - -@cli.command("teardown", cls=NoOptionDefaultFormat) -@click.pass_context -def teardown_command(ctx: click.Context): - """ - Tear down deployed feature store infrastructure - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - repo_config = load_repo_config(repo, fs_yaml_file) - - teardown(repo_config, repo) - - -@cli.command("registry-dump") -@click.pass_context -def registry_dump_command(ctx: click.Context): - """ - Print contents of the metadata registry - """ - repo = ctx.obj["CHDIR"] - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - repo_config = load_repo_config(repo, fs_yaml_file) - - click.echo(registry_dump(repo_config, repo_path=repo)) - - -@cli.command("materialize") -@click.argument("start_ts", required=False) -@click.argument("end_ts", required=False) -@click.option( - "--views", - "-v", - help="Feature views to materialize", - multiple=True, -) -@click.option( - "--disable-event-timestamp", - is_flag=True, - help="Materialize all available data using current datetime as event timestamp (useful when source data lacks event timestamps)", -) -@click.pass_context -def materialize_command( - ctx: click.Context, - start_ts: Optional[str], - end_ts: Optional[str], - views: List[str], - disable_event_timestamp: bool, -): - """ - Run a (non-incremental) materialization job to ingest data into the online store. Feast - will read all data between START_TS and END_TS from the offline store and write it to the - online store. If you don't specify feature view names using --views, all registered Feature - Views will be materialized. - - START_TS and END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' - - If --disable-event-timestamp is used, timestamps are not required and all available data will be materialized using the current datetime as the event timestamp. - """ - store = create_feature_store(ctx) - - if disable_event_timestamp: - if start_ts or end_ts: - raise click.UsageError( - "Cannot specify START_TS or END_TS when --disable-event-timestamp is used" - ) - now = datetime.now() - # Query all available data and use current datetime as event timestamp - start_date = datetime( - 1970, 1, 1 - ) # Beginning of time to capture all historical data - end_date = now - else: - if not start_ts or not end_ts: - raise click.UsageError( - "START_TS and END_TS are required unless --disable-event-timestamp is used" - ) - start_date = utils.make_tzaware(parser.parse(start_ts)) - end_date = utils.make_tzaware(parser.parse(end_ts)) - - store.materialize( - feature_views=None if not views else views, - start_date=start_date, - end_date=end_date, - disable_event_timestamp=disable_event_timestamp, - ) - - -@cli.command("materialize-incremental") -@click.argument("end_ts") -@click.option( - "--views", - "-v", - help="Feature views to incrementally materialize", - multiple=True, -) -@click.pass_context -def materialize_incremental_command(ctx: click.Context, end_ts: str, views: List[str]): - """ - Run an incremental materialization job to ingest new data into the online store. Feast will read - all data from the previously ingested point to END_TS from the offline store and write it to the - online store. If you don't specify feature view names using --views, all registered Feature - Views will be incrementally materialized. - - END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' - """ - store = create_feature_store(ctx) - store.materialize_incremental( - feature_views=None if not views else views, - end_date=utils.make_tzaware(datetime.fromisoformat(end_ts)), - ) - - -@cli.command("init") -@click.argument("PROJECT_DIRECTORY", required=False) -@click.option( - "--minimal", "-m", is_flag=True, help="Create an empty project repository" -) -@click.option( - "--template", - "-t", - type=click.Choice( - [ - "local", - "gcp", - "aws", - "snowflake", - "spark", - "postgres", - "hbase", - "cassandra", - "hazelcast", - "couchbase", - "milvus", - "ray", - "ray_rag", - "pytorch_nlp", - ], - case_sensitive=False, - ), - help="Specify a template for the created project", - default="local", -) -@click.option( - "--repo-path", - help="Directory path where the repository will be created (default: create subdirectory with project name)", -) -def init_command(project_directory, minimal: bool, template: str, repo_path: str): - """Create a new Feast repository""" - if not project_directory: - project_directory = generate_project_name() - - if minimal: - template = "minimal" - - init_repo(project_directory, template, repo_path) - - -@cli.command("listen") -@click.option( - "--address", - "-a", - type=click.STRING, - default="localhost:50051", - show_default=True, - help="Address of the gRPC server", -) -@click.option( - "--max_workers", - "-w", - type=click.INT, - default=10, - show_default=False, - help="The maximum number of threads that can be used to execute the gRPC calls", -) -@click.option( - "--registry_ttl_sec", - "-r", - help="Number of seconds after which the registry is refreshed", - type=click.INT, - default=5, - show_default=True, -) -@click.pass_context -def listen_command( - ctx: click.Context, - address: str, - max_workers: int, - registry_ttl_sec: int, -): - """Start a gRPC feature server to ingest streaming features on given address""" - from feast.infra.contrib.grpc_server import get_grpc_server - - store = create_feature_store(ctx) - server = get_grpc_server(address, store, max_workers, registry_ttl_sec) - server.start() - server.wait_for_termination() - - -@cli.command("validate") -@click.option( - "--feature-service", - "-f", - help="Specify a feature service name", -) -@click.option( - "--reference", - "-r", - help="Specify a validation reference name", -) -@click.option( - "--no-profile-cache", - is_flag=True, - help="Do not store cached profile in registry", -) -@click.argument("start_ts") -@click.argument("end_ts") -@click.pass_context -def validate( - ctx: click.Context, - feature_service: str, - reference: str, - start_ts: str, - end_ts: str, - no_profile_cache, -): - """ - Perform validation of logged features (produced by a given feature service) against provided reference. - - START_TS and END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' - """ - store = create_feature_store(ctx) - - _feature_service = store.get_feature_service(name=feature_service) - _reference = store.get_validation_reference(reference) - - result = store.validate_logged_features( - source=_feature_service, - reference=_reference, - start=maybe_local_tz(datetime.fromisoformat(start_ts)), - end=maybe_local_tz(datetime.fromisoformat(end_ts)), - throw_exception=False, - cache_profile=not no_profile_cache, - ) - - if not result: - print(f"{Style.BRIGHT + Fore.GREEN}Validation successful!{Style.RESET_ALL}") - return - - errors = [e.to_dict() for e in result.report.errors] - formatted_json = json.dumps(errors, indent=4) - colorful_json = highlight( - formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter() - ) - print(f"{Style.BRIGHT + Fore.RED}Validation failed!{Style.RESET_ALL}") - print(colorful_json) - exit(1) - - -cli.add_command(data_sources_cmd) -cli.add_command(entities_cmd) -cli.add_command(feature_services_cmd) -cli.add_command(feature_views_cmd) -cli.add_command(features_cmd) -cli.add_command(get_historical_features) -cli.add_command(get_online_features) -cli.add_command(on_demand_feature_views_cmd) -cli.add_command(feast_permissions_cmd) -cli.add_command(projects_cmd) -cli.add_command(saved_datasets_cmd) -cli.add_command(stream_feature_views_cmd) -cli.add_command(validation_references_cmd) -cli.add_command(ui) -cli.add_command(serve_command) -cli.add_command(serve_offline_command) -cli.add_command(serve_registry_command) -cli.add_command(serve_transformations_command) -cli.add_command(dbt_cmd) - -if __name__ == "__main__": - cli() +# Copyright 2019 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import json +import logging +from datetime import datetime +from importlib.metadata import version as importlib_version +from pathlib import Path +from typing import List, Optional + +import click +import yaml +from colorama import Fore, Style +from dateutil import parser +from pygments import formatters, highlight, lexers + +from feast import utils +from feast.cli.data_sources import data_sources_cmd +from feast.cli.dbt_import import dbt_cmd +from feast.cli.entities import entities_cmd +from feast.cli.feature_services import feature_services_cmd +from feast.cli.feature_views import feature_views_cmd +from feast.cli.features import ( + features_cmd, + get_historical_features, + get_online_features, +) +from feast.cli.label_views import label_views_cmd +from feast.cli.monitor import monitor_cmd +from feast.cli.on_demand_feature_views import on_demand_feature_views_cmd +from feast.cli.permissions import feast_permissions_cmd +from feast.cli.projects import projects_cmd +from feast.cli.saved_datasets import saved_datasets_cmd +from feast.cli.serve import ( + serve_command, + serve_offline_command, + serve_registry_command, + serve_transformations_command, +) +from feast.cli.stream_feature_views import stream_feature_views_cmd +from feast.cli.ui import ui +from feast.cli.validation_references import validation_references_cmd +from feast.constants import FEAST_FS_YAML_FILE_PATH_ENV_NAME +from feast.errors import FeastProviderLoginError +from feast.repo_config import load_repo_config +from feast.repo_operations import ( + apply_total, + cli_check_repo, + create_feature_store, + generate_project_name, + init_repo, + plan, + registry_dump, + teardown, +) +from feast.utils import maybe_local_tz + +_logger = logging.getLogger(__name__) + + +class NoOptionDefaultFormat(click.Command): + def format_options(self, ctx: click.Context, formatter: click.HelpFormatter): + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + if opts: + with formatter.section("Options(No current command options)"): + formatter.write_dl(opts) + + +@click.group() +@click.option( + "--chdir", + "-c", + envvar="FEATURE_REPO_DIR_ENV_VAR", + help="Switch to a different feature repository directory before executing the given subcommand. Can also be set via the FEATURE_REPO_DIR_ENV_VAR environment variable.", +) +@click.option( + "--log-level", + default="warning", + help="The logging level. One of DEBUG, INFO, WARNING, ERROR, and CRITICAL (case-insensitive).", +) +@click.option( + "--feature-store-yaml", + "-f", + help=f"Override the directory where the CLI should look for the feature_store.yaml file. Can also be set via the {FEAST_FS_YAML_FILE_PATH_ENV_NAME} environment variable.", +) +@click.pass_context +def cli( + ctx: click.Context, + chdir: Optional[str], + log_level: str, + feature_store_yaml: Optional[str], +): + """ + Feast CLI + + For more information, see our public docs at https://docs.feast.dev/ + """ + ctx.ensure_object(dict) + ctx.obj["CHDIR"] = Path.cwd() if chdir is None else Path(chdir).absolute() + ctx.obj["FS_YAML_FILE"] = ( + Path(feature_store_yaml).absolute() + if feature_store_yaml + else utils.get_default_yaml_file_path(ctx.obj["CHDIR"]) + ) + try: + level = getattr(logging, log_level.upper()) + logging.basicConfig( + format="%(asctime)s %(name)s %(levelname)s: %(message)s", + datefmt="%m/%d/%Y %I:%M:%S %p", + level=level, + ) + # Override the logging level for already created loggers (due to loggers being created at the import time) + # Note, that format & datefmt does not need to be set, because by default child loggers don't override them + + # Also note, that mypy complains that logging.root doesn't have "manager" because of the way it's written. + # So we have to put a type ignore hint for mypy. + for logger_name in logging.root.manager.loggerDict: # type: ignore + if "feast" in logger_name: + logger = logging.getLogger(logger_name) + logger.setLevel(level) + except Exception as e: + raise e + pass + + +@cli.command() +def version(): + """ + Display Feast SDK version + """ + print( + f'{Style.BRIGHT + Fore.BLUE}Feast SDK Version: {Style.BRIGHT + Fore.GREEN}"{importlib_version("feast")}"' + ) + + +@cli.command() +@click.argument("object_id") +@click.pass_context +def delete(ctx: click.Context, object_id: str): + """ + Delete Feast Object + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + store = create_feature_store(ctx) + + e = None + object_type = None + + # Order matters if names can overlap between types, + # though typically they shouldn't in a well-structured feature store. + object_getters_and_types = [ + (store.get_entity, "Entity"), + (store.get_feature_view, "FeatureView"), + (store.get_feature_service, "FeatureService"), + (store.get_data_source, "DataSource"), + (store.get_saved_dataset, "SavedDataset"), + (store.get_validation_reference, "ValidationReference"), + (store.get_stream_feature_view, "StreamFeatureView"), + (store.get_on_demand_feature_view, "OnDemandFeatureView"), + # Add other get_* methods here if needed + ] + + for getter, obj_type_str in object_getters_and_types: + try: + potential_e = getter(object_id) # type: ignore[operator] + if potential_e: + e = potential_e + object_type = obj_type_str + break + except Exception: + pass + + if isinstance(e, list): + e = e[0] + if e: + store.apply([e], objects_to_delete=[e], partial=False) + print( + f"{Style.BRIGHT + Fore.RED}Deleted {Style.BRIGHT + Fore.GREEN}{object_type} {Fore.YELLOW}{object_id} from {Fore.GREEN}{store.project}.{Style.RESET_ALL}" + ) + else: + print( + f"{Style.BRIGHT + Fore.GREEN}Object not found. Deletion skipped.{Style.RESET_ALL}" + ) + + +@cli.command() +@click.pass_context +def configuration(ctx: click.Context): + """ + Display Feast configuration + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + repo_config = load_repo_config(repo, fs_yaml_file) + if repo_config: + config_dict = repo_config.model_dump(by_alias=True, exclude_unset=True) + config_dict.pop("repo_path", None) + print(yaml.dump(config_dict, default_flow_style=False, sort_keys=False)) + else: + print("No configuration found.") + + +@cli.command() +@click.pass_context +def endpoint(ctx: click.Context): + """ + Display feature server endpoints + """ + store = create_feature_store(ctx) + endpoint = store.get_feature_server_endpoint() + if endpoint is not None: + _logger.info( + f"Feature server endpoint: {Style.BRIGHT + Fore.GREEN}{endpoint}{Style.RESET_ALL}" + ) + else: + _logger.info("There is no active feature server.") + + +@cli.command("plan", cls=NoOptionDefaultFormat) +@click.option( + "--skip-source-validation", + is_flag=True, + help="Don't validate the data sources by checking for that the tables exist.", +) +@click.option( + "--skip-feature-view-validation", + is_flag=True, + help="Don't validate feature views. Use with caution as this skips important checks.", +) +@click.pass_context +def plan_command( + ctx: click.Context, skip_source_validation: bool, skip_feature_view_validation: bool +): + """ + Create or update a feature store deployment + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + repo_config = load_repo_config(repo, fs_yaml_file) + try: + plan(repo_config, repo, skip_source_validation, skip_feature_view_validation) + except FeastProviderLoginError as e: + print(str(e)) + + +@cli.command("apply", cls=NoOptionDefaultFormat) +@click.option( + "--skip-source-validation", + is_flag=True, + help="Don't validate the data sources by checking for that the tables exist.", +) +@click.option( + "--skip-feature-view-validation", + is_flag=True, + help="Don't validate feature views. Use with caution as this skips important checks.", +) +@click.option( + "--no-progress", + is_flag=True, + help="Disable progress bars during apply operation.", +) +@click.option( + "--no-promote", + is_flag=True, + default=False, + help="Save new versions without promoting them to active. " + "New versions are accessible via @v reads and --version materialization.", +) +@click.pass_context +def apply_total_command( + ctx: click.Context, + skip_source_validation: bool, + skip_feature_view_validation: bool, + no_progress: bool, + no_promote: bool, +): + """ + Create or update a feature store deployment + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + + repo_config = load_repo_config(repo, fs_yaml_file) + + # Set environment variable to disable progress if requested + if no_progress: + import os + + os.environ["FEAST_NO_PROGRESS"] = "1" + + try: + apply_total( + repo_config, + repo, + skip_source_validation, + skip_feature_view_validation, + no_promote=no_promote, + ) + except FeastProviderLoginError as e: + print(str(e)) + + +@cli.command("teardown", cls=NoOptionDefaultFormat) +@click.pass_context +def teardown_command(ctx: click.Context): + """ + Tear down deployed feature store infrastructure + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + repo_config = load_repo_config(repo, fs_yaml_file) + + teardown(repo_config, repo) + + +@cli.command("registry-dump") +@click.pass_context +def registry_dump_command(ctx: click.Context): + """ + Print contents of the metadata registry + """ + repo = ctx.obj["CHDIR"] + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + repo_config = load_repo_config(repo, fs_yaml_file) + + click.echo(registry_dump(repo_config, repo_path=repo)) + + +@cli.command("materialize") +@click.argument("start_ts", required=False) +@click.argument("end_ts", required=False) +@click.option( + "--views", + "-v", + help="Feature views to materialize", + multiple=True, +) +@click.option( + "--disable-event-timestamp", + is_flag=True, + help="Materialize all available data using current datetime as event timestamp (useful when source data lacks event timestamps)", +) +@click.option( + "--version", + "feature_view_version", + default=None, + help="Version to materialize (e.g., 'v2'). Requires --views with exactly one feature view.", +) +@click.pass_context +def materialize_command( + ctx: click.Context, + start_ts: Optional[str], + end_ts: Optional[str], + views: List[str], + disable_event_timestamp: bool, + feature_view_version: Optional[str], +): + """ + Run a (non-incremental) materialization job to ingest data into the online store. Feast + will read all data between START_TS and END_TS from the offline store and write it to the + online store. If you don't specify feature view names using --views, all registered Feature + Views will be materialized. + + START_TS and END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' + + If --disable-event-timestamp is used, timestamps are not required and all available data will be materialized using the current datetime as the event timestamp. + """ + store = create_feature_store(ctx) + + if disable_event_timestamp: + if start_ts or end_ts: + raise click.UsageError( + "Cannot specify START_TS or END_TS when --disable-event-timestamp is used" + ) + now = datetime.now() + # Query all available data and use current datetime as event timestamp + start_date = datetime( + 1970, 1, 1 + ) # Beginning of time to capture all historical data + end_date = now + else: + if not start_ts or not end_ts: + raise click.UsageError( + "START_TS and END_TS are required unless --disable-event-timestamp is used" + ) + start_date = utils.make_tzaware(parser.parse(start_ts)) + end_date = utils.make_tzaware(parser.parse(end_ts)) + + store.materialize( + feature_views=None if not views else views, + start_date=start_date, + end_date=end_date, + disable_event_timestamp=disable_event_timestamp, + version=feature_view_version, + ) + + +@cli.command("materialize-incremental") +@click.argument("end_ts") +@click.option( + "--views", + "-v", + help="Feature views to incrementally materialize", + multiple=True, +) +@click.option( + "--version", + "feature_view_version", + default=None, + help="Version to materialize (e.g., 'v2'). Requires --views with exactly one feature view.", +) +@click.pass_context +def materialize_incremental_command( + ctx: click.Context, + end_ts: str, + views: List[str], + feature_view_version: Optional[str], +): + """ + Run an incremental materialization job to ingest new data into the online store. Feast will read + all data from the previously ingested point to END_TS from the offline store and write it to the + online store. If you don't specify feature view names using --views, all registered Feature + Views will be incrementally materialized. + + END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' + """ + store = create_feature_store(ctx) + store.materialize_incremental( + feature_views=None if not views else views, + end_date=utils.make_tzaware(datetime.fromisoformat(end_ts)), + version=feature_view_version, + ) + + +@cli.command("init") +@click.argument("PROJECT_DIRECTORY", required=False) +@click.option( + "--minimal", "-m", is_flag=True, help="Create an empty project repository" +) +@click.option( + "--template", + "-t", + type=click.Choice( + [ + "local", + "gcp", + "aws", + "snowflake", + "spark", + "postgres", + "hbase", + "cassandra", + "hazelcast", + "couchbase", + "milvus", + "ray", + "ray_rag", + "pytorch_nlp", + ], + case_sensitive=False, + ), + help="Specify a template for the created project", + default="local", +) +@click.option( + "--repo-path", + help="Directory path where the repository will be created (default: create subdirectory with project name)", +) +def init_command(project_directory, minimal: bool, template: str, repo_path: str): + """Create a new Feast repository""" + if not project_directory: + project_directory = generate_project_name() + + if minimal: + template = "minimal" + + init_repo(project_directory, template, repo_path) + + +@cli.command("listen") +@click.option( + "--address", + "-a", + type=click.STRING, + default="localhost:50051", + show_default=True, + help="Address of the gRPC server", +) +@click.option( + "--max_workers", + "-w", + type=click.INT, + default=10, + show_default=False, + help="The maximum number of threads that can be used to execute the gRPC calls", +) +@click.option( + "--registry_ttl_sec", + "-r", + help="Number of seconds after which the registry is refreshed", + type=click.INT, + default=5, + show_default=True, +) +@click.pass_context +def listen_command( + ctx: click.Context, + address: str, + max_workers: int, + registry_ttl_sec: int, +): + """Start a gRPC feature server to ingest streaming features on given address""" + from feast.infra.contrib.grpc_server import get_grpc_server + + store = create_feature_store(ctx) + server = get_grpc_server(address, store, max_workers, registry_ttl_sec) + server.start() + server.wait_for_termination() + + +@cli.command("validate") +@click.option( + "--feature-service", + "-f", + help="Specify a feature service name", +) +@click.option( + "--reference", + "-r", + help="Specify a validation reference name", +) +@click.option( + "--no-profile-cache", + is_flag=True, + help="Do not store cached profile in registry", +) +@click.argument("start_ts") +@click.argument("end_ts") +@click.pass_context +def validate( + ctx: click.Context, + feature_service: str, + reference: str, + start_ts: str, + end_ts: str, + no_profile_cache, +): + """ + Perform validation of logged features (produced by a given feature service) against provided reference. + + START_TS and END_TS should be in ISO 8601 format, e.g. '2021-07-16T19:20:01' + """ + store = create_feature_store(ctx) + + _feature_service = store.get_feature_service(name=feature_service) + _reference = store.get_validation_reference(reference) + + result = store.validate_logged_features( + source=_feature_service, + reference=_reference, + start=maybe_local_tz(datetime.fromisoformat(start_ts)), + end=maybe_local_tz(datetime.fromisoformat(end_ts)), + throw_exception=False, + cache_profile=not no_profile_cache, + ) + + if not result: + print(f"{Style.BRIGHT + Fore.GREEN}Validation successful!{Style.RESET_ALL}") + return + + errors = [e.to_dict() for e in result.report.errors] + formatted_json = json.dumps(errors, indent=4) + colorful_json = highlight( + formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter() + ) + print(f"{Style.BRIGHT + Fore.RED}Validation failed!{Style.RESET_ALL}") + print(colorful_json) + exit(1) + + +@cli.command("demo-notebooks") +@click.option( + "--output-dir", + "-o", + default="./feast-demo-notebooks", + show_default=True, + help="Directory where the demo notebooks are written.", +) +@click.option( + "--overwrite", + is_flag=True, + default=False, + help="Overwrite existing notebooks if the output directory already exists.", +) +@click.pass_context +def demo_notebooks_command(ctx: click.Context, output_dir: str, overwrite: bool): + """ + Generate demo Jupyter notebooks tailored to the feature store configuration. + + Searches for feature_store.yaml in the current directory and every file + inside feast-config/. Each file is treated as a separate project config. + For each project found, a sub-directory is created under OUTPUT_DIR. + """ + from feast.demos import copy_demo_notebooks + + repo = ctx.obj["CHDIR"] + copy_demo_notebooks( + output_dir=output_dir, + repo_path=str(repo), + overwrite=overwrite, + ) + + +cli.add_command(data_sources_cmd) +cli.add_command(entities_cmd) +cli.add_command(feature_services_cmd) +cli.add_command(feature_views_cmd) +cli.add_command(features_cmd) +cli.add_command(get_historical_features) +cli.add_command(get_online_features) +cli.add_command(on_demand_feature_views_cmd) +cli.add_command(feast_permissions_cmd) +cli.add_command(projects_cmd) +cli.add_command(saved_datasets_cmd) +cli.add_command(stream_feature_views_cmd) +cli.add_command(label_views_cmd) +cli.add_command(validation_references_cmd) +cli.add_command(ui) +cli.add_command(serve_command) +cli.add_command(serve_offline_command) +cli.add_command(serve_registry_command) +cli.add_command(serve_transformations_command) +cli.add_command(dbt_cmd) +cli.add_command(monitor_cmd) + +if __name__ == "__main__": + cli() diff --git a/sdk/python/feast/cli/feature_views.py b/sdk/python/feast/cli/feature_views.py index a1a29ac9f27..44357b0c1c1 100644 --- a/sdk/python/feast/cli/feature_views.py +++ b/sdk/python/feast/cli/feature_views.py @@ -1,10 +1,16 @@ +import sys + import click import yaml from feast import utils from feast.cli.cli_options import tagsOption from feast.errors import FeastObjectNotFoundException -from feast.feature_view import FeatureView +from feast.feature_view import ( + _VALID_STATE_TRANSITIONS, + FeatureView, + FeatureViewState, +) from feast.on_demand_feature_view import OnDemandFeatureView from feast.repo_operations import create_feature_store @@ -32,11 +38,13 @@ def feature_view_describe(ctx: click.Context, name: str): print(e) exit(1) - print( - yaml.dump( - yaml.safe_load(str(feature_view)), default_flow_style=False, sort_keys=False - ) - ) + data = yaml.safe_load(str(feature_view)) + # Always show enabled and state even when they are at default values. + if hasattr(feature_view, "enabled"): + data["enabled"] = feature_view.enabled + if hasattr(feature_view, "state"): + data["state"] = feature_view.state.name + print(yaml.dump(data, default_flow_style=False, sort_keys=False)) @feature_views_cmd.command(name="list") @@ -59,14 +67,170 @@ def feature_view_list(ctx: click.Context, tags: list[str]): elif isinstance(feature_view, OnDemandFeatureView): for backing_fv in feature_view.source_feature_view_projections.values(): entities.update(store.get_feature_view(backing_fv.name).entities) + enabled = getattr(feature_view, "enabled", True) + state = getattr(feature_view, "state", FeatureViewState.STATE_UNSPECIFIED) + state_display = ( + state.name if isinstance(state, FeatureViewState) else str(state) + ) table.append( [ feature_view.name, entities if len(entities) > 0 else "n/a", type(feature_view).__name__, + "Yes" if enabled else "No", + state_display, + ] + ) + + from tabulate import tabulate + + print( + tabulate( + table, + headers=["NAME", "ENTITIES", "TYPE", "ENABLED", "STATE"], + tablefmt="plain", + ) + ) + + +@feature_views_cmd.command("enable") +@click.argument("name", type=click.STRING) +@click.pass_context +def feature_view_enable(ctx: click.Context, name: str): + """ + Enable a feature view for serving and materialization. + """ + store = create_feature_store(ctx) + try: + fv = store.registry.get_any_feature_view(name, store.project) + except FeastObjectNotFoundException as e: + print(e) + sys.exit(1) + + if not isinstance(fv, (FeatureView, OnDemandFeatureView)): + print(f"Feature view '{name}' does not support enable/disable.") + return + + if fv.enabled: + print(f"Feature view '{name}' is already enabled.") + return + + fv.enabled = True + store.registry.apply_feature_view(fv, store.project) + print(f"Feature view '{name}' has been enabled.") + + +@feature_views_cmd.command("disable") +@click.argument("name", type=click.STRING) +@click.pass_context +def feature_view_disable(ctx: click.Context, name: str): + """ + Disable a feature view to prevent serving and materialization. + """ + store = create_feature_store(ctx) + try: + fv = store.registry.get_any_feature_view(name, store.project) + except FeastObjectNotFoundException as e: + print(e) + sys.exit(1) + + if not isinstance(fv, (FeatureView, OnDemandFeatureView)): + print(f"Feature view '{name}' does not support enable/disable.") + return + + if not fv.enabled: + print(f"Feature view '{name}' is already disabled.") + return + + fv.enabled = False + store.registry.apply_feature_view(fv, store.project) + print(f"Feature view '{name}' has been disabled.") + + +@feature_views_cmd.command("set-state") +@click.argument("name", type=click.STRING) +@click.argument( + "state", + type=click.Choice( + ["CREATED", "GENERATED", "MATERIALIZING", "AVAILABLE_ONLINE"], + case_sensitive=False, + ), +) +@click.pass_context +def feature_view_set_state(ctx: click.Context, name: str, state: str): + """ + Set the lifecycle state of a feature view. + """ + store = create_feature_store(ctx) + try: + fv = store.registry.get_any_feature_view(name, store.project) + except FeastObjectNotFoundException as e: + print(e) + sys.exit(1) + + if not isinstance(fv, (FeatureView, OnDemandFeatureView)): + print(f"Feature view '{name}' does not support state management.") + return + + new_state = FeatureViewState[state.upper()] + if fv.state == new_state: + print(f"Feature view '{name}' is already in state {new_state.name}.") + return + + if not fv.state.can_transition_to(new_state): + current = fv.state.name + allowed = _VALID_STATE_TRANSITIONS.get(fv.state, set()) + allowed_names = ", ".join(sorted(s.name for s in allowed)) or "none" + print( + f"Invalid state transition: {current} -> {new_state.name}. " + f"Allowed transitions from {current}: {allowed_names}." + ) + return + + fv.state = new_state + store.registry.apply_feature_view(fv, store.project) + print(f"Feature view '{name}' state set to {new_state.name}.") + + +@feature_views_cmd.command("list-versions") +@click.argument("name", type=click.STRING) +@click.pass_context +def feature_view_versions(ctx: click.Context, name: str): + """ + List version history for a feature view + """ + store = create_feature_store(ctx) + + try: + versions = store.list_feature_view_versions(name) + except NotImplementedError: + print("Version history is not supported by this registry backend.") + exit(1) + except Exception as e: + print(e) + exit(1) + + if not versions: + print(f"No version history found for feature view '{name}'.") + return + + table = [] + for v in versions: + table.append( + [ + v["version"], + v["feature_view_type"], + str(v["created_timestamp"]), + v["version_id"], ] ) from tabulate import tabulate - print(tabulate(table, headers=["NAME", "ENTITIES", "TYPE"], tablefmt="plain")) + print( + tabulate( + table, + headers=["VERSION", "TYPE", "CREATED", "VERSION_ID"], + tablefmt="plain", + ) + ) diff --git a/sdk/python/feast/cli/label_views.py b/sdk/python/feast/cli/label_views.py new file mode 100644 index 00000000000..232a2fbce21 --- /dev/null +++ b/sdk/python/feast/cli/label_views.py @@ -0,0 +1,69 @@ +import click +import yaml + +from feast import utils +from feast.cli.cli_options import tagsOption +from feast.errors import FeastObjectNotFoundException +from feast.repo_operations import create_feature_store + + +@click.group(name="label-views") +def label_views_cmd(): + """ + Access label views + """ + pass + + +@label_views_cmd.command("describe") +@click.argument("name", type=click.STRING) +@click.pass_context +def label_view_describe(ctx: click.Context, name: str): + """ + Describe a label view + """ + store = create_feature_store(ctx) + + try: + label_view = store.get_label_view(name) + except FeastObjectNotFoundException as e: + print(e) + exit(1) + + print( + yaml.dump( + yaml.safe_load(str(label_view)), + default_flow_style=False, + sort_keys=False, + ) + ) + + +@label_views_cmd.command(name="list") +@tagsOption +@click.pass_context +def label_view_list(ctx: click.Context, tags: list[str]): + """ + List all label views + """ + store = create_feature_store(ctx) + table = [] + tags_filter = utils.tags_list_to_dict(tags) + for label_view in store.list_label_views(tags=tags_filter): + table.append( + [ + label_view.name, + ", ".join(label_view.entities) if label_view.entities else "n/a", + str(label_view.conflict_policy.value), + ] + ) + + from tabulate import tabulate + + print( + tabulate( + table, + headers=["NAME", "ENTITIES", "CONFLICT_POLICY"], + tablefmt="plain", + ) + ) diff --git a/sdk/python/feast/cli/monitor.py b/sdk/python/feast/cli/monitor.py new file mode 100644 index 00000000000..f2f645ad1be --- /dev/null +++ b/sdk/python/feast/cli/monitor.py @@ -0,0 +1,225 @@ +from datetime import date +from typing import List, Optional + +import click + +from feast.infra.offline_stores.offline_store import OfflineStore +from feast.repo_operations import create_feature_store + +VALID_GRANULARITIES = OfflineStore.MONITORING_VALID_GRANULARITIES + + +@click.group(name="monitor") +def monitor_cmd(): + """Feature monitoring commands.""" + pass + + +@monitor_cmd.command("run") +@click.option( + "--project", + "-p", + default=None, + help="Feast project name. Defaults to the project in feature_store.yaml.", +) +@click.option( + "--feature-view", + "-v", + default=None, + help="Feature view name. If omitted, all feature views are computed.", +) +@click.option( + "--feature-name", + "-f", + multiple=True, + help="Feature name(s) to compute. Can be specified multiple times.", +) +@click.option( + "--start-date", + default=None, + help="Start date (YYYY-MM-DD). If omitted, auto-detected from source data.", +) +@click.option( + "--end-date", + default=None, + help="End date (YYYY-MM-DD). If omitted, auto-detected from source data.", +) +@click.option( + "--granularity", + "-g", + default=None, + type=click.Choice(list(VALID_GRANULARITIES)), + help="Metric granularity. If omitted, all granularities are computed (auto mode).", +) +@click.option( + "--set-baseline", + is_flag=True, + default=False, + help="Mark this computation as the baseline for drift detection.", +) +@click.option( + "--feature-service", + "-s", + default=None, + help="Feature service name (required for --source-type log with explicit dates).", +) +@click.option( + "--source-type", + type=click.Choice(["batch", "log", "all"]), + default="batch", + help="Data source type: 'batch' (offline store), 'log' (serving logs), or 'all'.", +) +@click.pass_context +def monitor_run( + ctx: click.Context, + project: Optional[str], + feature_view: Optional[str], + feature_name: tuple, + start_date: Optional[str], + end_date: Optional[str], + granularity: Optional[str], + set_baseline: bool, + feature_service: Optional[str], + source_type: str, +): + """Compute feature quality metrics. + + Without --start-date/--end-date/--granularity, runs in auto mode: + detects date ranges from source data and computes all granularities. + + Use --source-type log to compute metrics from feature serving logs + (requires feature services with logging configured). + """ + store = create_feature_store(ctx) + + if project is None: + project = store.project + + from feast.monitoring.monitoring_service import MonitoringService + + svc = MonitoringService(store) + + auto_mode = start_date is None and end_date is None and granularity is None + feat_names: Optional[List[str]] = list(feature_name) if feature_name else None + + if source_type in ("batch", "all"): + _run_batch_monitoring( + svc, + project, + feature_view, + feat_names, + start_date, + end_date, + granularity, + set_baseline, + auto_mode, + ) + + if source_type in ("log", "all"): + _run_log_monitoring( + svc, + project, + feature_service, + start_date, + end_date, + granularity, + auto_mode, + ) + + +def _run_batch_monitoring( + svc, + project, + feature_view, + feat_names, + start_date, + end_date, + granularity, + set_baseline, + auto_mode, +): + if auto_mode and set_baseline and not start_date and not end_date: + click.echo("Computing baseline from all available source data...") + result = svc.compute_baseline( + project=project, + feature_view_name=feature_view, + feature_names=feat_names, + ) + click.echo(f"Status: {result['status']}") + click.echo(f"Features computed: {result['computed_features']}") + click.echo(f"Feature views computed: {result['computed_feature_views']}") + click.echo(f"Duration: {result['duration_ms']}ms") + click.echo("Baseline: SET") + elif auto_mode and not set_baseline: + click.echo("Auto-computing batch metrics for all granularities...") + result = svc.auto_compute( + project=project, + feature_view_name=feature_view, + ) + click.echo(f"Status: {result['status']}") + click.echo(f"Feature views computed: {result['computed_feature_views']}") + click.echo(f"Features computed: {result['computed_features']}") + click.echo(f"Granularities: {', '.join(result['granularities'])}") + click.echo(f"Duration: {result['duration_ms']}ms") + else: + start_d = date.fromisoformat(start_date) if start_date else None + end_d = date.fromisoformat(end_date) if end_date else None + + result = svc.compute_metrics( + project=project, + feature_view_name=feature_view, + feature_names=feat_names, + start_date=start_d, + end_date=end_d, + granularity=granularity or "daily", + set_baseline=set_baseline, + ) + + click.echo(f"Status: {result['status']}") + click.echo(f"Granularity: {result['granularity']}") + click.echo(f"Features computed: {result['computed_features']}") + click.echo(f"Feature views computed: {result['computed_feature_views']}") + click.echo(f"Feature services computed: {result['computed_feature_services']}") + click.echo(f"Metric dates: {', '.join(result['metric_dates'])}") + click.echo(f"Duration: {result['duration_ms']}ms") + + if set_baseline: + click.echo("Baseline: SET") + + +def _run_log_monitoring( + svc, project, feature_service_name, start_date, end_date, granularity, auto_mode +): + if auto_mode: + click.echo("Auto-computing log metrics for all granularities...") + result = svc.auto_compute_log_metrics( + project=project, + feature_service_name=feature_service_name, + ) + click.echo(f"Status: {result['status']}") + click.echo(f"Feature services computed: {result['computed_feature_services']}") + click.echo(f"Features computed: {result['computed_features']}") + click.echo(f"Granularities: {', '.join(result['granularities'])}") + click.echo(f"Duration: {result['duration_ms']}ms") + else: + if not feature_service_name: + click.echo( + "Error: --feature-service is required for log source with explicit dates." + ) + return + + start_d = date.fromisoformat(start_date) if start_date else None + end_d = date.fromisoformat(end_date) if end_date else None + + result = svc.compute_log_metrics( + project=project, + feature_service_name=feature_service_name, + start_date=start_d, + end_date=end_d, + granularity=granularity or "daily", + ) + + click.echo(f"Status: {result['status']}") + click.echo("Source: log") + click.echo(f"Features computed: {result.get('computed_features', 0)}") + click.echo(f"Duration: {result['duration_ms']}ms") diff --git a/sdk/python/feast/cli/projects.py b/sdk/python/feast/cli/projects.py index ea8d5b573a6..c552a058635 100644 --- a/sdk/python/feast/cli/projects.py +++ b/sdk/python/feast/cli/projects.py @@ -3,7 +3,7 @@ from feast import utils from feast.cli.cli_options import tagsOption -from feast.errors import FeastObjectNotFoundException +from feast.errors import FeastObjectNotFoundException, ProjectNotFoundException from feast.repo_operations import create_feature_store @@ -23,16 +23,16 @@ def project_describe(ctx: click.Context, name: str): Describe a project """ store = create_feature_store(ctx) - try: project = store.get_project(name) except FeastObjectNotFoundException as e: print(e) exit(1) - print( yaml.dump( - yaml.safe_load(str(project)), default_flow_style=False, sort_keys=False + yaml.safe_load(str(project)), + default_flow_style=False, + sort_keys=False, ) ) @@ -44,20 +44,52 @@ def project_current(ctx: click.Context): Returns the current project configured with FeatureStore object """ store = create_feature_store(ctx) - try: project = store.get_project(name=None) except FeastObjectNotFoundException as e: print(e) exit(1) - print( yaml.dump( - yaml.safe_load(str(project)), default_flow_style=False, sort_keys=False + yaml.safe_load(str(project)), + default_flow_style=False, + sort_keys=False, ) ) +@projects_cmd.command("delete") +@click.argument("name", type=click.STRING) +@click.option( + "-y", + "--yes", + is_flag=True, + default=False, + help="Skip confirmation prompt and delete immediately.", +) +@click.pass_context +def project_delete(ctx: click.Context, name: str, yes: bool): + """ + Delete a project and all its resources from the registry. + """ + store = create_feature_store(ctx) + + if not yes: + click.confirm( + f"Are you sure you want to delete project '{name}'? " + "This will remove all associated resources from the registry.", + abort=True, + ) + + try: + store.delete_project(name) + except (FeastObjectNotFoundException, ProjectNotFoundException) as e: + print(str(e)) + raise SystemExit(1) + + print(f"Project '{name}' deleted successfully.") + + @projects_cmd.command(name="list") @tagsOption @click.pass_context @@ -70,11 +102,12 @@ def project_list(ctx: click.Context, tags: list[str]): tags_filter = utils.tags_list_to_dict(tags) for project in store.list_projects(tags=tags_filter): table.append([project.name, project.description, project.tags, project.owner]) - from tabulate import tabulate print( tabulate( - table, headers=["NAME", "DESCRIPTION", "TAGS", "OWNER"], tablefmt="plain" + table, + headers=["NAME", "DESCRIPTION", "TAGS", "OWNER"], + tablefmt="plain", ) ) diff --git a/sdk/python/feast/cli/ui.py b/sdk/python/feast/cli/ui.py index 9fd7b24b7cd..6962eea1e51 100644 --- a/sdk/python/feast/cli/ui.py +++ b/sdk/python/feast/cli/ui.py @@ -1,6 +1,6 @@ import click -from feast.repo_operations import create_feature_store, registry_dump +from feast.repo_operations import create_feature_store @click.command() @@ -20,14 +20,6 @@ show_default=True, help="Specify a port for the server", ) -@click.option( - "--registry_ttl_sec", - "-r", - help="Number of seconds after which the registry is refreshed", - type=click.INT, - default=5, - show_default=True, -) @click.option( "--root_path", help="Provide root path to make the UI working behind proxy", @@ -57,7 +49,6 @@ def ui( ctx: click.Context, host: str, port: int, - registry_ttl_sec: int, root_path: str = "", tls_key_path: str = "", tls_cert_path: str = "", @@ -70,12 +61,9 @@ def ui( "Please configure --key and --cert args to start the feature server in SSL mode." ) store = create_feature_store(ctx) - # Pass in the registry_dump method to get around a circular dependency store.serve_ui( host=host, port=port, - get_registry_dump=registry_dump, - registry_ttl_sec=registry_ttl_sec, root_path=root_path, tls_key_path=tls_key_path, tls_cert_path=tls_cert_path, diff --git a/sdk/python/feast/data_source.py b/sdk/python/feast/data_source.py index 2d4997ae786..e14f2a49383 100644 --- a/sdk/python/feast/data_source.py +++ b/sdk/python/feast/data_source.py @@ -205,6 +205,7 @@ class DataSource(ABC): tags: Dict[str, str] owner: str date_partition_column: str + timestamp_field_type: str created_timestamp: Optional[datetime] last_updated_timestamp: Optional[datetime] @@ -219,6 +220,7 @@ def __init__( tags: Optional[Dict[str, str]] = None, owner: Optional[str] = "", date_partition_column: Optional[str] = None, + timestamp_field_type: Optional[str] = None, ): """ Creates a DataSource object. @@ -237,6 +239,9 @@ def __init__( owner (optional): The owner of the data source, typically the email of the primary maintainer. date_partition_column (optional): Timestamp column used for partitioning. Not supported by all stores + timestamp_field_type (optional): Type of the timestamp_field column. + Defaults to "TIMESTAMP". Set to "DATE" when the event timestamp column + is a DATE type, so SQL generation uses date-only comparisons. """ self.name = name self.timestamp_field = timestamp_field or "" @@ -257,6 +262,7 @@ def __init__( self.date_partition_column = ( date_partition_column if date_partition_column else "" ) + self.timestamp_field_type = timestamp_field_type if timestamp_field_type else "" now = _utc_now() self.created_timestamp = now self.last_updated_timestamp = now @@ -280,6 +286,7 @@ def __eq__(self, other): or self.created_timestamp_column != other.created_timestamp_column or self.field_mapping != other.field_mapping or self.date_partition_column != other.date_partition_column + or self.timestamp_field_type != other.timestamp_field_type or self.description != other.description or self.tags != other.tags or self.owner != other.owner diff --git a/sdk/python/feast/dbt/parser.py b/sdk/python/feast/dbt/parser.py index f7d3e587e54..676a5a76f11 100644 --- a/sdk/python/feast/dbt/parser.py +++ b/sdk/python/feast/dbt/parser.py @@ -107,6 +107,7 @@ def parse(self) -> None: try: from dbt_artifacts_parser.parser import parse_manifest + assert self._raw_manifest is not None self._parsed_manifest = parse_manifest(manifest=self._raw_manifest) except ImportError: raise ImportError( diff --git a/sdk/python/feast/demos.py b/sdk/python/feast/demos.py new file mode 100644 index 00000000000..9970f90316b --- /dev/null +++ b/sdk/python/feast/demos.py @@ -0,0 +1,851 @@ +# Copyright 2026 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Demo notebook generation for Feast projects. + +Usage:: + + from feast import copy_demo_notebooks + copy_demo_notebooks() + +This will search for ``feature_store.yaml`` in the current directory and every +file inside the ``feast-config/`` directory, then write tailored Jupyter +notebooks into a ``./feast-demo-notebooks//`` directory for each +project found. +""" + +import json +import logging +import os +import pathlib +from typing import Any, Optional + +import yaml + +_logger = logging.getLogger(__name__) + + +# --------------------------------------------------------------------------- +# Discovery helpers +# --------------------------------------------------------------------------- + + +def _find_feature_store_yamls(repo_path: pathlib.Path) -> list[pathlib.Path]: + """Return all feature-store config paths found under *repo_path*. + + Searches: + 1. ``repo_path/feature_store.yaml`` + 2. Every file directly inside ``repo_path/feast-config/`` + — each file is treated as a separate project config. + """ + found: list[pathlib.Path] = [] + + direct = repo_path / "feature_store.yaml" + if direct.exists(): + found.append(direct) + + feast_config_dir = repo_path / "feast-config" + if feast_config_dir.is_dir(): + for entry in sorted(feast_config_dir.iterdir()): + if entry.is_file(): + found.append(entry) + + return found + + +def _parse_yaml(yaml_path: pathlib.Path) -> dict[str, Any]: + with open(yaml_path) as fh: + return yaml.safe_load(os.path.expandvars(fh.read())) or {} + + +def _extract_store_info(config: dict[str, Any]) -> dict[str, Any]: + """Summarise the key fields from a raw ``feature_store.yaml`` dict.""" + info: dict[str, Any] = { + "project": config.get("project", "my_feast_project"), + "provider": config.get("provider", "local"), + "online_store_type": "sqlite", + "offline_store_type": "file", + "registry_type": "file", + "auth_type": "no_auth", + "vector_enabled": False, + "embedding_dim": None, + } + + online = config.get("online_store", {}) + if isinstance(online, dict): + info["online_store_type"] = online.get("type", "sqlite").lower() + info["vector_enabled"] = bool(online.get("vector_enabled", False)) + if online.get("embedding_dim"): + info["embedding_dim"] = online["embedding_dim"] + elif isinstance(online, str): + info["online_store_type"] = online.lower() + + offline = config.get("offline_store", {}) + if isinstance(offline, dict): + info["offline_store_type"] = offline.get("type", "file").lower() + elif isinstance(offline, str): + info["offline_store_type"] = offline.lower() + + registry = config.get("registry", {}) + if isinstance(registry, dict): + # Operator client YAML uses "registry_type" key; standard Feast uses "type" + info["registry_type"] = ( + registry.get("registry_type") or registry.get("type", "file") + ).lower() + # string registry value is a plain file path — keep default "file" + + auth = config.get("auth", {}) + if isinstance(auth, dict): + info["auth_type"] = auth.get("type", "no_auth").lower() + + return info + + +# --------------------------------------------------------------------------- +# Notebook cell builders +# --------------------------------------------------------------------------- + + +def _md(source: str) -> dict[str, Any]: + return { + "cell_type": "markdown", + "metadata": {}, + "source": source, + } + + +def _code(source: str, tags: Optional[list[str]] = None) -> dict[str, Any]: + meta: dict[str, Any] = {} + if tags: + meta["tags"] = tags + return { + "cell_type": "code", + "execution_count": None, + "metadata": meta, + "outputs": [], + "source": source, + } + + +def _notebook(cells: list[dict[str, Any]]) -> dict[str, Any]: + return { + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3", + }, + }, + "cells": cells, + } + + +# --------------------------------------------------------------------------- +# Per-store setup snippets +# --------------------------------------------------------------------------- + + +def _is_operator_client(info: dict[str, Any]) -> bool: + """Return True when the feature_store.yaml was generated by the Feast operator. + + The operator sets provider=local with registry_type=remote, online_store.type=remote, + and offline_store.type=remote. + """ + return ( + info["registry_type"] == "remote" + and info["online_store_type"] == "remote" + and info["offline_store_type"] == "remote" + ) + + +# --------------------------------------------------------------------------- +# Notebook generators +# --------------------------------------------------------------------------- + + +def _apply_md(info: dict[str, Any]) -> dict[str, Any]: + """Return the markdown cell that introduces the apply / registry-sync section.""" + if info["registry_type"] == "remote": + return _md( + "## 4. Registry Sync\n\nRefresh the registry cache to load the latest feature definitions." + ) + return _md( + "## 4. Apply Feature Definitions\n\n" + "Register entities, feature views, and services into the registry. " + "Skip if already applied." + ) + + +def _apply_code(info: dict[str, Any]) -> dict[str, Any]: + """Return the code cell that applies (local) or refreshes (remote) the registry.""" + if info["registry_type"] == "remote": + return _code( + "store.refresh_registry()\n" + "fvs = store.list_feature_views()\n" + "print(f'Registry synced — {len(fvs)} feature view(s) available.')" + ) + # Local file registry — auto-apply if empty, then refresh. + return _code( + "fvs = store.list_feature_views()\n" + "entities = store.list_entities()\n" + "\n" + "if fvs or entities:\n" + " print(f'Registry ready: {len(entities)} entity/entities, {len(fvs)} feature view(s)')\n" + "else:\n" + " print('Registry is empty — running feast apply ...')\n" + " !feast -f {FEAST_FS_YAML} apply\n" + " store.refresh_registry()\n" + " print('Apply complete.')" + ) + + +def _path_setup_cell(yaml_abs: str) -> dict[str, Any]: + """Return a code cell that sets ``FEAST_FS_YAML`` to the absolute path of + the feature-store config resolved at generation time.""" + return _code( + "import os\n" + "\n" + f"FEAST_FS_YAML = r{repr(yaml_abs)}\n" + "\n" + "assert os.path.exists(FEAST_FS_YAML), (\n" + " f'Config not found at {FEAST_FS_YAML!r}. '\n" + " 'Update FEAST_FS_YAML to the correct path.'\n" + ")\n" + "print(f'Using feature_store.yaml: {FEAST_FS_YAML}')", + tags=["parameters"], + ) + + +def _nb_overview(info: dict[str, Any], yaml_abs: str) -> dict[str, Any]: + project = info["project"] + ost = info["online_store_type"] + offst = info["offline_store_type"] + auth = info["auth_type"] + provider = info["provider"] + vector_enabled = info["vector_enabled"] + + cells: list[dict[str, Any]] = [ + _md( + f"# Feature Store Overview — `{project}`\n\n" + "Explore the entities, feature views, feature services, and data sources " + "registered in this project." + ), + _md("## 1. Prerequisites"), + _code( + "# Verify feast installation\nimport feast\nprint(f'Feast version: {feast.__version__}')" + ), + _md("## 2. Feature Store Path"), + _path_setup_cell(yaml_abs), + _md( + f"## 3. Connect to the Feature Store\n" + f"The feature store for project **`{project}`** is configured with:\n\n" + f"| Setting | Value |\n" + f"|---------|-------|\n" + f"| Provider | `{provider}` |\n" + f"| Online store | `{ost}` |\n" + f"| Offline store | `{offst}` |\n" + f"| Auth | `{auth}` |\n" + + ( + f"| Vector search | enabled (embedding dim: {info['embedding_dim']}) |\n" + if vector_enabled + else "" + ) + ), + _code( + "from feast import FeatureStore\n" + "\n" + "store = FeatureStore(fs_yaml_file=FEAST_FS_YAML)\n" + "print(f'Connected to project: {store.project}')" + ), + _apply_md(info), + _apply_code(info), + _md("## 5. List Entities"), + _code( + "entities = store.list_entities()\n" + "print(f'Found {len(entities)} entity/entities\\n')\n" + "for e in entities:\n" + " print(f' • {e.name} (join_key={e.join_key}, type={e.value_type})')" + ), + _md("## 6. List Feature Views"), + _code( + "feature_views = store.list_feature_views()\n" + "print(f'Found {len(feature_views)} batch feature view(s)\\n')\n" + "for fv in feature_views:\n" + " feature_names = [f.name for f in fv.features]\n" + " print(f' • {fv.name}')\n" + " print(f' Features : {feature_names}')\n" + " print(f' Entities : {fv.entities}')\n" + " print(f' TTL : {fv.ttl}')\n" + ), + _md("## 7. List On-Demand Feature Views"), + _code( + "odfvs = store.list_on_demand_feature_views()\n" + "if odfvs:\n" + " print(f'Found {len(odfvs)} on-demand feature view(s)\\n')\n" + " for odfv in odfvs:\n" + " print(f' • {odfv.name}')\n" + "else:\n" + " print('No on-demand feature views defined.')" + ), + _md("## 8. List Feature Services"), + _code( + "services = store.list_feature_services()\n" + "if services:\n" + " print(f'Found {len(services)} feature service(s)\\n')\n" + " for svc in services:\n" + " views = [p.name for p in svc.feature_view_projections]\n" + " print(f' • {svc.name} -> views: {views}')\n" + "else:\n" + " print('No feature services defined.')" + ), + _md("## 9. List Data Sources"), + _code( + "sources = store.list_data_sources()\n" + "print(f'Found {len(sources)} data source(s)\\n')\n" + "for src in sources:\n" + " print(f' • {src.name} ({type(src).__name__})')" + ), + _md( + "## Next Steps\n\n" + "- **`02_historical_features_training.ipynb`** — retrieve historical features for training.\n" + "- **`03_online_features_serving.ipynb`** — materialize and serve online features." + ), + ] + return _notebook(cells) + + +def _nb_historical(info: dict[str, Any], yaml_abs: str) -> dict[str, Any]: + project = info["project"] + + cells: list[dict[str, Any]] = [ + _md( + f"# Historical Features & Training Datasets — `{project}`\n\n" + "Retrieve point-in-time correct feature values to build ML training datasets." + ), + _md("## 1. Feature Store Path"), + _path_setup_cell(yaml_abs), + _md("## 2. Connect to the Feature Store"), + _code( + "from feast import FeatureStore\n" + "\n" + "store = FeatureStore(fs_yaml_file=FEAST_FS_YAML)\n" + "print(f'Project : {store.project}')\n" + "print('Feature views:', [fv.name for fv in store.list_feature_views()])" + ), + _md( + "## 3. Discover Available Features\n\nList feature views and read a sample of entity data." + ), + _code( + "import pandas as pd\n" + "from datetime import datetime, timedelta, timezone\n" + "\n" + "fvs = store.list_feature_views()\n" + "entities = store.list_entities()\n" + "\n" + "if not fvs:\n" + " print('No feature views found — run `feast apply` first.')\n" + "else:\n" + " first_fv = fvs[0]\n" + "\n" + " # Identify the entity join key.\n" + " entity_name = entities[0].join_key if entities else 'entity_id'\n" + " if first_fv.entities:\n" + " fv_entity = next(\n" + " (e for e in entities if e.name in set(first_fv.entities)),\n" + " entities[0] if entities else None,\n" + " )\n" + " if fv_entity:\n" + " entity_name = fv_entity.join_key\n" + "\n" + " # Read latest entity values from the offline store.\n" + " # This uses the same mechanism Feast uses for materialization.\n" + " source = first_fv.batch_source\n" + " provider = store._get_provider()\n" + " sample_df = provider.offline_store.pull_latest_from_table_or_query(\n" + " config=store.config,\n" + " data_source=source,\n" + " join_key_columns=[entity_name],\n" + " feature_name_columns=[f.name for f in first_fv.features],\n" + " timestamp_field=source.timestamp_field,\n" + " created_timestamp_column=source.created_timestamp_column or '',\n" + " start_date=datetime(2000, 1, 1, tzinfo=timezone.utc),\n" + " end_date=datetime.now(tz=timezone.utc),\n" + " ).to_df()\n" + "\n" + " print(f'Feature view : {first_fv.name}')\n" + " print(f'Entity join key : {entity_name!r}')\n" + " print(f'Rows in source : {len(sample_df):,}')\n" + " print(f'Columns : {list(sample_df.columns)}')\n" + " if len(sample_df) > 0:\n" + " display(sample_df.head())\n" + " else:\n" + " print('No data found — check that your data source has been populated.')" + ), + _md( + "## 4. Build an Entity DataFrame\n\n" + "Specify which entity IDs and at what timestamps you want features for." + ), + _code( + "if not fvs:\n" + " raise SystemExit('No feature views — run feast apply first.')\n" + "\n" + "# Use real entity IDs and timestamps from the sample.\n" + "if entity_name in sample_df.columns and len(sample_df) > 0:\n" + " entity_ids = sample_df[entity_name].dropna().unique()[:5].tolist()\n" + " # Detect the timestamp column from the source's configuration.\n" + " ts_col = source.timestamp_field if source.timestamp_field in sample_df.columns else None\n" + " if not ts_col:\n" + " ts_col = next((c for c in sample_df.columns if 'timestamp' in c.lower()), None)\n" + " if ts_col:\n" + " timestamps = (\n" + " sample_df[sample_df[entity_name].isin(entity_ids)]\n" + " .sort_values(ts_col, ascending=False)\n" + " .drop_duplicates(subset=[entity_name])[ts_col]\n" + " .tolist()\n" + " )\n" + " else:\n" + " timestamps = [datetime.now() - timedelta(hours=i) for i in range(len(entity_ids))]\n" + "else:\n" + " entity_ids = [1001, 1002, 1003]\n" + " timestamps = [datetime.now() - timedelta(hours=i) for i in range(len(entity_ids))]\n" + " print('Using placeholder entity IDs — replace with real values from your data.')\n" + "\n" + "entity_df = pd.DataFrame(\n" + " {\n" + " entity_name: entity_ids[:len(timestamps)],\n" + " 'event_timestamp': timestamps[:len(entity_ids)],\n" + " }\n" + ")\n" + "print(f'Entity IDs : {entity_ids}')\n" + "print(f'Rows : {len(entity_df)}')\n" + "entity_df" + ), + _md("## 5. Choose Features to Retrieve"), + _code( + "# List all available feature views and their features.\n" + "print('Available feature views:')\n" + "for fv in fvs:\n" + " features = [f.name for f in fv.features]\n" + " print(f' {fv.name}: {features}')\n" + "\n" + "# Select features from the first feature view.\n" + "# Using a single view avoids name collisions across views with identical column names.\n" + "feature_refs = [f'{first_fv.name}:{f.name}' for f in first_fv.features]\n" + "print('\\nWill retrieve:', feature_refs)" + ), + _md("## 6. Retrieve Historical Features"), + _code( + "if feature_refs:\n" + " training_df = store.get_historical_features(\n" + " entity_df=entity_df,\n" + " features=feature_refs,\n" + " ).to_df()\n" + " print(f'Training dataset shape: {training_df.shape}')\n" + " training_df.head()\n" + "else:\n" + " print('No feature views found — run `feast apply` first.')" + ), + _md( + "## 7. (Optional) Retrieve via FeatureService\n\nRetrieve features using a versioned FeatureService instead of individual feature references." + ), + _code( + "services = store.list_feature_services()\n" + "if not services:\n" + " print('No feature services found — define one in your feature repo.')\n" + "else:\n" + " svc = services[0]\n" + "\n" + " # Detect extra request-data columns required by ODFVs in this service.\n" + " odfv_map = {v.name: v for v in store.list_on_demand_feature_views()}\n" + " missing_cols = {\n" + " field.name: field.dtype\n" + " for proj in svc.feature_view_projections\n" + " if proj.name in odfv_map\n" + " for rs in odfv_map[proj.name].source_request_sources.values()\n" + " for field in rs.schema\n" + " if field.name not in entity_df.columns\n" + " }\n" + "\n" + " if missing_cols:\n" + " print('This service requires the following extra columns in entity_df:')\n" + " for col, dtype in missing_cols.items():\n" + " print(f' entity_df[{col!r}] = ')\n" + " print('Add them to entity_df above and re-run this cell.')\n" + " else:\n" + " # Check if service needs entity keys not already in entity_df.\n" + " svc_entities = set()\n" + " for proj in svc.feature_view_projections:\n" + " fv_match = next((fv for fv in fvs if fv.name == proj.name), None)\n" + " if fv_match:\n" + " for ent_name in fv_match.entities:\n" + " ent_obj = next((e for e in entities if e.name == ent_name), None)\n" + " if ent_obj:\n" + " svc_entities.add(ent_obj.join_key)\n" + " missing_keys = svc_entities - set(entity_df.columns)\n" + " if missing_keys:\n" + " print(f'This service requires additional entity columns: {missing_keys}')\n" + " print('Add them to entity_df above and re-run this cell.')\n" + " else:\n" + " print(f'Using feature service: {svc.name}')\n" + " training_df_svc = store.get_historical_features(\n" + " entity_df=entity_df,\n" + " features=svc,\n" + " full_feature_names=True,\n" + " ).to_df()\n" + " print(f'Dataset shape: {training_df_svc.shape}')\n" + " training_df_svc.head()" + ), + _md("## 8. Use the Training Dataset"), + _code( + "# Example: split into features (X) and labels (y)\n" + "# Adjust column names to match your actual feature names and label.\n" + "if feature_refs and 'training_df' in dir():\n" + " label_col = 'label' # TODO: replace with your label column\n" + " feature_cols = [c for c in training_df.columns\n" + " if c not in ('event_timestamp', entity_name, label_col)]\n" + " X = training_df[feature_cols]\n" + " print('Feature matrix shape:', X.shape)\n" + " print('Feature columns:', feature_cols)" + ), + _md( + "## Next Steps\n\n" + "- **`03_online_features_serving.ipynb`** — materialize and serve online features." + ), + ] + return _notebook(cells) + + +def _nb_online(info: dict[str, Any], yaml_abs: str) -> dict[str, Any]: + project = info["project"] + auth = info["auth_type"] + vector_enabled = info["vector_enabled"] + + cells: list[dict[str, Any]] = [ + _md( + f"# Online Feature Serving — `{project}`\n\n" + "Materialize features and retrieve them at low latency for inference." + ), + _md("## 1. Feature Store Path"), + _path_setup_cell(yaml_abs), + _md("## 2. Connect to the Feature Store"), + _code( + "from feast import FeatureStore\n" + "\n" + "store = FeatureStore(fs_yaml_file=FEAST_FS_YAML)\n" + "print(f'Project : {store.project}')" + ), + ] + + # Materialization section. + materialize_md = ( + "## 3. Materialize Features\n\n" + + ( + "> **Optional** — materialization is typically handled server-side.\n\n" + if _is_operator_client(info) + else "" + ) + + "Load feature values into the online store for low-latency serving.\n\n" + "| Method | When to use |\n" + "|--------|-------------|\n" + "| `materialize_incremental` | Regular runs — only new data since last run |\n" + "| `materialize` | First run or full refresh of a time window |" + ) + cells += [ + _md(materialize_md), + _code( + "from datetime import datetime, timedelta, timezone\n" + "\n" + "fvs = store.list_feature_views()\n" + "\n" + "if not fvs:\n" + " print('No feature views found — run feast apply first (see section 3).')\n" + "else:\n" + " # Check last materialization watermarks across all feature views.\n" + " last_written = [\n" + " fv.materialization_intervals[-1][1]\n" + " for fv in fvs\n" + " if fv.materialization_intervals\n" + " ]\n" + "\n" + " if not last_written:\n" + " # No materialization history — do a full initial load.\n" + " end_date = datetime.now(tz=timezone.utc)\n" + " start_date = end_date - timedelta(days=30)\n" + " print(f'First materialization: loading {start_date.date()} → {end_date.date()} ...')\n" + " store.materialize(start_date=start_date, end_date=end_date)\n" + " else:\n" + " # Incremental: only pick up data since the last run.\n" + " end_date = datetime.now(tz=timezone.utc)\n" + " print(f'Incremental materialization up to {end_date} ...')\n" + " store.materialize_incremental(end_date=end_date)\n" + "\n" + " print('Materialization complete.')" + ), + _md("### 3b. Force a Full Refresh"), + _code( + "# from datetime import datetime, timedelta, timezone\n" + "# store.materialize(\n" + "# start_date=datetime.now(tz=timezone.utc) - timedelta(days=7),\n" + "# end_date=datetime.now(tz=timezone.utc),\n" + "# )" + ), + ] + + cells += [ + _md("## 4. Retrieve Online Features"), + _code( + "entities = store.list_entities()\n" + "fvs = store.list_feature_views()\n" + "\n" + "if not entities or not fvs:\n" + " print('No entities or feature views — run `feast apply` first.')\n" + "else:\n" + " first_fv = fvs[0]\n" + " feature_refs = [f'{first_fv.name}:{f.name}' for f in first_fv.features[:3]]\n" + "\n" + " # Resolve the correct entity join key for the first feature view.\n" + " entity_name = entities[0].join_key\n" + " if first_fv.entities:\n" + " fv_entity = next(\n" + " (e for e in entities if e.name in set(first_fv.entities)),\n" + " entities[0],\n" + " )\n" + " entity_name = fv_entity.join_key\n" + "\n" + " # Discover real entity IDs from the offline source.\n" + " from datetime import timezone\n" + " source = first_fv.batch_source\n" + " provider = store._get_provider()\n" + " sample_df = provider.offline_store.pull_latest_from_table_or_query(\n" + " config=store.config,\n" + " data_source=source,\n" + " join_key_columns=[entity_name],\n" + " feature_name_columns=[f.name for f in first_fv.features],\n" + " timestamp_field=source.timestamp_field,\n" + " created_timestamp_column=source.created_timestamp_column or '',\n" + " start_date=datetime(2000, 1, 1, tzinfo=timezone.utc),\n" + " end_date=datetime.now(tz=timezone.utc),\n" + " ).to_df()\n" + "\n" + " if len(sample_df) > 0 and entity_name in sample_df.columns:\n" + " entity_ids = sample_df[entity_name].dropna().unique()[:5].tolist()\n" + " else:\n" + " entity_ids = [1001, 1002]\n" + " print('Using placeholder IDs — replace with real values.')\n" + "\n" + " entity_rows = [{entity_name: eid} for eid in entity_ids]\n" + "\n" + " response = store.get_online_features(\n" + " features=feature_refs,\n" + " entity_rows=entity_rows,\n" + " )\n" + " import pandas as pd\n" + " print(pd.DataFrame(response.to_dict()))" + ), + _md( + "## 5. Online Features via FeatureService\n\nRetrieve features using a versioned FeatureService." + ), + _code( + "services = store.list_feature_services()\n" + "if not services:\n" + " print('No feature services defined.')\n" + "else:\n" + " svc = services[0]\n" + "\n" + " # Detect extra request-data fields required by ODFVs in this service.\n" + " odfv_map = {v.name: v for v in store.list_on_demand_feature_views()}\n" + " current_keys = set(entity_rows[0].keys()) if entity_rows else set()\n" + " missing_fields = {\n" + " field.name: field.dtype\n" + " for proj in svc.feature_view_projections\n" + " if proj.name in odfv_map\n" + " for rs in odfv_map[proj.name].source_request_sources.values()\n" + " for field in rs.schema\n" + " if field.name not in current_keys\n" + " }\n" + "\n" + " if missing_fields:\n" + " print('This service requires the following extra fields in each entity row:')\n" + " for col, dtype in missing_fields.items():\n" + " print(f' {col!r}: ')\n" + " print('Add them to entity_rows above and re-run this cell.')\n" + " else:\n" + " # Check if service needs extra entity keys beyond what we have.\n" + " svc_entities = set()\n" + " for proj in svc.feature_view_projections:\n" + " fv_match = next((fv for fv in fvs if fv.name == proj.name), None)\n" + " if fv_match:\n" + " for ent_name in fv_match.entities:\n" + " ent_obj = next((e for e in entities if e.name == ent_name), None)\n" + " if ent_obj:\n" + " svc_entities.add(ent_obj.join_key)\n" + " missing_keys = svc_entities - current_keys\n" + " if missing_keys:\n" + " print(f'This service requires additional entity keys: {missing_keys}')\n" + " print('Add them to entity_rows above and re-run this cell.')\n" + " else:\n" + " print(f'Using feature service: {svc.name}')\n" + " response = store.get_online_features(\n" + " features=svc,\n" + " entity_rows=entity_rows,\n" + " full_feature_names=True,\n" + " )\n" + " import pandas as pd\n" + " print(pd.DataFrame(response.to_dict()))" + ), + ] + + if auth in ("kubernetes", "oidc"): + cells.append(_md(f"## 6. Authentication (`{auth}`)")) + cells.append(_code("print(store.config.auth)")) + + if vector_enabled: + dim = info.get("embedding_dim") or 384 + section = 7 if auth in ("kubernetes", "oidc") else 6 + cells.append( + _md( + f"## {section}. Vector / RAG Feature Retrieval\n\nSearch stored embeddings (dim: {dim})." + ) + ) + cells.append( + _code( + "import numpy as np\n" + "\n" + "# TODO: replace with a real query embedding from your encoder model\n" + f"query_embedding = np.random.rand({dim}).tolist()\n" + "\n" + "# List feature views with vector features\n" + "fvs = store.list_feature_views()\n" + "vec_fvs = [\n" + " fv for fv in fvs\n" + " if any(getattr(f, 'vector_index', False) for f in fv.features)\n" + "]\n" + "\n" + "if vec_fvs:\n" + " fv = vec_fvs[0]\n" + " results = store.retrieve_online_documents(\n" + " feature=f'{fv.name}:{fv.features[0].name}',\n" + " query=query_embedding,\n" + " top_k=5,\n" + " )\n" + " import pandas as pd\n" + " print(pd.DataFrame(results.to_dict()))\n" + "else:\n" + " print('No vector feature views found.')" + ) + ) + + cells.append( + _md( + "## Next Steps\n\n" + "- Schedule `materialize_incremental` to keep the online store fresh.\n" + ) + ) + + return _notebook(cells) + + +# --------------------------------------------------------------------------- +# Public API +# --------------------------------------------------------------------------- + + +def copy_demo_notebooks( + output_dir: str = "./feast-demo-notebooks", + repo_path: str = ".", + overwrite: bool = False, +) -> None: + """Generate tailored demo notebooks for each Feast project found nearby. + + The function searches *repo_path* (default: current working directory) for + feature-store YAML files in: + + * ``/feature_store.yaml`` + * Every file inside ``/feast-config/`` + + For each project discovered a sub-directory is created under *output_dir* + and one or more notebooks are written (the exact set depends on the project + configuration and may grow in future releases). + + Parameters + ---------- + output_dir: + Root directory where notebooks are written. + Defaults to ``./feast-demo-notebooks``. + repo_path: + Directory to search for ``feature_store.yaml`` files. + Defaults to the current working directory. + overwrite: + When *False* (default) raise :class:`FileExistsError` if *output_dir* + already exists. Set to *True* to update notebooks in place. + """ + out = pathlib.Path(output_dir).resolve() + + if not overwrite and out.exists(): + raise FileExistsError( + f"Directory '{out}' already exists. " + "Remove it or pass overwrite=True to update notebooks in place." + ) + + root = pathlib.Path(repo_path).absolute() + yaml_paths = _find_feature_store_yamls(root) + + if not yaml_paths: + _logger.warning( + "No feature_store.yaml found under '%s'. " + "Make sure you run this from a directory that contains feature_store.yaml " + "or a feast-config/ subdirectory.", + root, + ) + return + + out.mkdir(parents=True, exist_ok=True) + print(f"Writing demo notebooks to: {out}\n") + + for yaml_path in yaml_paths: + raw = _parse_yaml(yaml_path) + info = _extract_store_info(raw) + project = info["project"] + + project_dir = out / project + project_dir.mkdir(parents=True, exist_ok=True) + + # Absolute path — use absolute() instead of resolve() to preserve + # Kubernetes ConfigMap/Secret symlinks. + yaml_abs_str = str(yaml_path.absolute()) + + notebooks = { + "01_feature_store_overview.ipynb": _nb_overview(info, yaml_abs_str), + "02_historical_features_training.ipynb": _nb_historical(info, yaml_abs_str), + "03_online_features_serving.ipynb": _nb_online(info, yaml_abs_str), + } + + for nb_name, nb_content in notebooks.items(): + nb_path = project_dir / nb_name + with open(nb_path, "w") as fh: + json.dump(nb_content, fh, indent=1) + + print( + f" [{project}]\n" + f" feature_store.yaml : {yaml_abs_str}\n" + f" online_store : {info['online_store_type']}\n" + f" offline_store : {info['offline_store_type']}\n" + f" auth : {info['auth_type']}\n" + + (" vector search : enabled\n" if info["vector_enabled"] else "") + + f" → {project_dir}/" + ) + for nb_name in notebooks: + print(f" ✓ {nb_name}") + print() diff --git a/sdk/python/feast/diff/registry_diff.py b/sdk/python/feast/diff/registry_diff.py index 272c4590d88..9c201cf46ad 100644 --- a/sdk/python/feast/diff/registry_diff.py +++ b/sdk/python/feast/diff/registry_diff.py @@ -1,416 +1,425 @@ -from dataclasses import dataclass -from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, cast - -from feast.base_feature_view import BaseFeatureView -from feast.data_source import DataSource -from feast.diff.property_diff import PropertyDiff, TransitionType -from feast.entity import Entity -from feast.feast_object import FeastObject, FeastObjectSpecProto -from feast.feature_service import FeatureService -from feast.feature_view import DUMMY_ENTITY_NAME -from feast.infra.registry.base_registry import BaseRegistry -from feast.infra.registry.registry import FEAST_OBJECT_TYPES, FeastObjectType -from feast.permissions.permission import Permission -from feast.project import Project -from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto -from feast.protos.feast.core.Entity_pb2 import Entity as EntityProto -from feast.protos.feast.core.FeatureService_pb2 import ( - FeatureService as FeatureServiceProto, -) -from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto -from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( - OnDemandFeatureView as OnDemandFeatureViewProto, -) -from feast.protos.feast.core.OnDemandFeatureView_pb2 import OnDemandFeatureViewSpec -from feast.protos.feast.core.Permission_pb2 import Permission as PermissionProto -from feast.protos.feast.core.SavedDataset_pb2 import SavedDataset as SavedDatasetProto -from feast.protos.feast.core.StreamFeatureView_pb2 import ( - StreamFeatureView as StreamFeatureViewProto, -) -from feast.protos.feast.core.ValidationProfile_pb2 import ( - ValidationReference as ValidationReferenceProto, -) -from feast.repo_contents import RepoContents - - -@dataclass -class FeastObjectDiff: - name: str - feast_object_type: FeastObjectType - current_feast_object: Optional[FeastObject] - new_feast_object: Optional[FeastObject] - feast_object_property_diffs: List[PropertyDiff] - transition_type: TransitionType - - -@dataclass -class RegistryDiff: - feast_object_diffs: List[FeastObjectDiff] - - def __init__(self): - self.feast_object_diffs = [] - - def add_feast_object_diff(self, feast_object_diff: FeastObjectDiff): - self.feast_object_diffs.append(feast_object_diff) - - def to_string(self): - from colorama import Fore, Style - - log_string = "" - - message_action_map = { - TransitionType.CREATE: ("Created", Fore.GREEN), - TransitionType.DELETE: ("Deleted", Fore.RED), - TransitionType.UNCHANGED: ("Unchanged", Fore.LIGHTBLUE_EX), - TransitionType.UPDATE: ("Updated", Fore.YELLOW), - } - for feast_object_diff in self.feast_object_diffs: - if feast_object_diff.name == DUMMY_ENTITY_NAME: - continue - if feast_object_diff.transition_type == TransitionType.UNCHANGED: - continue - if feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: - # TODO(adchia): Print statements out starting in Feast 0.24 - continue - action, color = message_action_map[feast_object_diff.transition_type] - log_string += f"{action} {feast_object_diff.feast_object_type.value} {Style.BRIGHT + color}{feast_object_diff.name}{Style.RESET_ALL}\n" - if feast_object_diff.transition_type == TransitionType.UPDATE: - for _p in feast_object_diff.feast_object_property_diffs: - log_string += f"\t{_p.property_name}: {Style.BRIGHT + color}{_p.val_existing}{Style.RESET_ALL} -> {Style.BRIGHT + Fore.LIGHTGREEN_EX}{_p.val_declared}{Style.RESET_ALL}\n" - - log_string = ( - f"{Style.BRIGHT + Fore.LIGHTBLUE_EX}No changes to registry" - if not log_string - else log_string - ) - - return log_string - - -def tag_objects_for_keep_delete_update_add( - existing_objs: Iterable[FeastObject], desired_objs: Iterable[FeastObject] -) -> Tuple[Set[FeastObject], Set[FeastObject], Set[FeastObject], Set[FeastObject]]: - # TODO(adchia): Remove the "if X.name" condition when data sources are forced to have names - existing_obj_names = {e.name for e in existing_objs if e.name} - desired_objs = [obj for obj in desired_objs if obj.name] - existing_objs = [obj for obj in existing_objs if obj.name] - desired_obj_names = {e.name for e in desired_objs if e.name} - - objs_to_add = {e for e in desired_objs if e.name not in existing_obj_names} - objs_to_update = {e for e in desired_objs if e.name in existing_obj_names} - objs_to_keep = {e for e in existing_objs if e.name in desired_obj_names} - objs_to_delete = {e for e in existing_objs if e.name not in desired_obj_names} - - return objs_to_keep, objs_to_delete, objs_to_update, objs_to_add - - -FeastObjectProto = TypeVar( - "FeastObjectProto", - DataSourceProto, - EntityProto, - FeatureViewProto, - FeatureServiceProto, - OnDemandFeatureViewProto, - StreamFeatureViewProto, - ValidationReferenceProto, - SavedDatasetProto, - PermissionProto, -) - - -FIELDS_TO_IGNORE = {"project"} - - -def diff_registry_objects( - current: FeastObject, new: FeastObject, object_type: FeastObjectType -) -> FeastObjectDiff: - current_proto = current.to_proto() - new_proto = new.to_proto() - assert current_proto.DESCRIPTOR.full_name == new_proto.DESCRIPTOR.full_name - property_diffs = [] - transition: TransitionType = TransitionType.UNCHANGED - - current_spec: FeastObjectSpecProto - new_spec: FeastObjectSpecProto - if isinstance( - current_proto, (DataSourceProto, ValidationReferenceProto) - ) or isinstance(new_proto, (DataSourceProto, ValidationReferenceProto)): - assert type(current_proto) == type(new_proto) - current_spec = cast(DataSourceProto, current_proto) - new_spec = cast(DataSourceProto, new_proto) - else: - current_spec = current_proto.spec - new_spec = new_proto.spec - if current != new: - for _field in current_spec.DESCRIPTOR.fields: - if _field.name in FIELDS_TO_IGNORE: - continue - elif getattr(current_spec, _field.name) != getattr(new_spec, _field.name): - if _field.name == "feature_transformation": - current_spec = cast(OnDemandFeatureViewSpec, current_spec) - new_spec = cast(OnDemandFeatureViewSpec, new_spec) - # Check if the old proto is populated and use that if it is - feature_transformation_udf = ( - current_spec.feature_transformation.user_defined_function - ) - if ( - current_spec.HasField("user_defined_function") - and not feature_transformation_udf - ): - deprecated_udf = current_spec.user_defined_function - else: - deprecated_udf = None - current_udf = ( - deprecated_udf - if deprecated_udf is not None - else feature_transformation_udf - ) - new_udf = new_spec.feature_transformation.user_defined_function - for _udf_field in current_udf.DESCRIPTOR.fields: - if _udf_field.name == "body": - continue - if getattr(current_udf, _udf_field.name) != getattr( - new_udf, _udf_field.name - ): - transition = TransitionType.UPDATE - property_diffs.append( - PropertyDiff( - _field.name + "." + _udf_field.name, - getattr(current_udf, _udf_field.name), - getattr(new_udf, _udf_field.name), - ) - ) - else: - transition = TransitionType.UPDATE - property_diffs.append( - PropertyDiff( - _field.name, - getattr(current_spec, _field.name), - getattr(new_spec, _field.name), - ) - ) - return FeastObjectDiff( - name=new_spec.name, - feast_object_type=object_type, - current_feast_object=current, - new_feast_object=new, - feast_object_property_diffs=property_diffs, - transition_type=transition, - ) - - -def extract_objects_for_keep_delete_update_add( - registry: BaseRegistry, - current_project: str, - desired_repo_contents: RepoContents, -) -> Tuple[ - Dict[FeastObjectType, Set[FeastObject]], - Dict[FeastObjectType, Set[FeastObject]], - Dict[FeastObjectType, Set[FeastObject]], - Dict[FeastObjectType, Set[FeastObject]], -]: - """ - Returns the objects in the registry that must be modified to achieve the desired repo state. - - Args: - registry: The registry storing the current repo state. - current_project: The Feast project whose objects should be compared. - desired_repo_contents: The desired repo state. - """ - objs_to_keep = {} - objs_to_delete = {} - objs_to_update = {} - objs_to_add = {} - - registry_object_type_to_objects: Dict[FeastObjectType, List[Any]] = ( - FeastObjectType.get_objects_from_registry(registry, current_project) - ) - registry_object_type_to_repo_contents: Dict[FeastObjectType, List[Any]] = ( - FeastObjectType.get_objects_from_repo_contents(desired_repo_contents) - ) - - for object_type in FEAST_OBJECT_TYPES: - ( - to_keep, - to_delete, - to_update, - to_add, - ) = tag_objects_for_keep_delete_update_add( - registry_object_type_to_objects[object_type], - registry_object_type_to_repo_contents[object_type], - ) - - objs_to_keep[object_type] = to_keep - objs_to_delete[object_type] = to_delete - objs_to_update[object_type] = to_update - objs_to_add[object_type] = to_add - - return objs_to_keep, objs_to_delete, objs_to_update, objs_to_add - - -def diff_between( - registry: BaseRegistry, - current_project: str, - desired_repo_contents: RepoContents, -) -> RegistryDiff: - """ - Returns the difference between the current and desired repo states. - - Args: - registry: The registry storing the current repo state. - current_project: The Feast project for which the diff is being computed. - desired_repo_contents: The desired repo state. - """ - diff = RegistryDiff() - - ( - objs_to_keep, - objs_to_delete, - objs_to_update, - objs_to_add, - ) = extract_objects_for_keep_delete_update_add( - registry, current_project, desired_repo_contents - ) - - for object_type in FEAST_OBJECT_TYPES: - objects_to_keep = objs_to_keep[object_type] - objects_to_delete = objs_to_delete[object_type] - objects_to_update = objs_to_update[object_type] - objects_to_add = objs_to_add[object_type] - - for e in objects_to_add: - diff.add_feast_object_diff( - FeastObjectDiff( - name=e.name, - feast_object_type=object_type, - current_feast_object=None, - new_feast_object=e, - feast_object_property_diffs=[], - transition_type=TransitionType.CREATE, - ) - ) - for e in objects_to_delete: - diff.add_feast_object_diff( - FeastObjectDiff( - name=e.name, - feast_object_type=object_type, - current_feast_object=e, - new_feast_object=None, - feast_object_property_diffs=[], - transition_type=TransitionType.DELETE, - ) - ) - for e in objects_to_update: - current_obj = [_e for _e in objects_to_keep if _e.name == e.name][0] - diff.add_feast_object_diff( - diff_registry_objects(current_obj, e, object_type) - ) - - return diff - - -def apply_diff_to_registry( - registry: BaseRegistry, - registry_diff: RegistryDiff, - project: str, - commit: bool = True, -): - """ - Applies the given diff to the given Feast project in the registry. - - Args: - registry: The registry to be updated. - registry_diff: The diff to apply. - project: Feast project to be updated. - commit: Whether the change should be persisted immediately - """ - for feast_object_diff in registry_diff.feast_object_diffs: - # There is no need to delete the object on an update, since applying the new object - # will automatically delete the existing object. - if feast_object_diff.transition_type == TransitionType.DELETE: - if feast_object_diff.feast_object_type == FeastObjectType.ENTITY: - entity_obj = cast(Entity, feast_object_diff.current_feast_object) - registry.delete_entity(entity_obj.name, project, commit=False) - elif feast_object_diff.feast_object_type == FeastObjectType.FEATURE_SERVICE: - feature_service_obj = cast( - FeatureService, feast_object_diff.current_feast_object - ) - registry.delete_feature_service( - feature_service_obj.name, project, commit=False - ) - elif feast_object_diff.feast_object_type in [ - FeastObjectType.FEATURE_VIEW, - FeastObjectType.ON_DEMAND_FEATURE_VIEW, - FeastObjectType.STREAM_FEATURE_VIEW, - ]: - feature_view_obj = cast( - BaseFeatureView, feast_object_diff.current_feast_object - ) - registry.delete_feature_view( - feature_view_obj.name, - project, - commit=False, - ) - elif feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: - ds_obj = cast(DataSource, feast_object_diff.current_feast_object) - registry.delete_data_source( - ds_obj.name, - project, - commit=False, - ) - elif feast_object_diff.feast_object_type == FeastObjectType.PERMISSION: - permission_obj = cast( - Permission, feast_object_diff.current_feast_object - ) - registry.delete_permission( - permission_obj.name, - project, - commit=False, - ) - - if feast_object_diff.transition_type in [ - TransitionType.CREATE, - TransitionType.UPDATE, - ]: - if feast_object_diff.feast_object_type == FeastObjectType.PROJECT: - registry.apply_project( - cast(Project, feast_object_diff.new_feast_object), - commit=False, - ) - if feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: - registry.apply_data_source( - cast(DataSource, feast_object_diff.new_feast_object), - project, - commit=False, - ) - if feast_object_diff.feast_object_type == FeastObjectType.ENTITY: - registry.apply_entity( - cast(Entity, feast_object_diff.new_feast_object), - project, - commit=False, - ) - elif feast_object_diff.feast_object_type == FeastObjectType.FEATURE_SERVICE: - registry.apply_feature_service( - cast(FeatureService, feast_object_diff.new_feast_object), - project, - commit=False, - ) - elif feast_object_diff.feast_object_type in [ - FeastObjectType.FEATURE_VIEW, - FeastObjectType.ON_DEMAND_FEATURE_VIEW, - FeastObjectType.STREAM_FEATURE_VIEW, - ]: - registry.apply_feature_view( - cast(BaseFeatureView, feast_object_diff.new_feast_object), - project, - commit=False, - ) - elif feast_object_diff.feast_object_type == FeastObjectType.PERMISSION: - registry.apply_permission( - cast(Permission, feast_object_diff.new_feast_object), - project, - commit=False, - ) - - if commit: - registry.commit() +from dataclasses import dataclass +from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, cast + +from feast.base_feature_view import BaseFeatureView +from feast.data_source import DataSource +from feast.diff.property_diff import PropertyDiff, TransitionType +from feast.entity import Entity +from feast.feast_object import FeastObject, FeastObjectSpecProto +from feast.feature_service import FeatureService +from feast.feature_view import DUMMY_ENTITY_NAME +from feast.infra.registry.base_registry import BaseRegistry +from feast.infra.registry.registry import FEAST_OBJECT_TYPES, FeastObjectType +from feast.permissions.permission import Permission +from feast.project import Project +from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto +from feast.protos.feast.core.Entity_pb2 import Entity as EntityProto +from feast.protos.feast.core.FeatureService_pb2 import ( + FeatureService as FeatureServiceProto, +) +from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto +from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( + OnDemandFeatureView as OnDemandFeatureViewProto, +) +from feast.protos.feast.core.OnDemandFeatureView_pb2 import OnDemandFeatureViewSpec +from feast.protos.feast.core.Permission_pb2 import Permission as PermissionProto +from feast.protos.feast.core.SavedDataset_pb2 import SavedDataset as SavedDatasetProto +from feast.protos.feast.core.StreamFeatureView_pb2 import ( + StreamFeatureView as StreamFeatureViewProto, +) +from feast.protos.feast.core.ValidationProfile_pb2 import ( + ValidationReference as ValidationReferenceProto, +) +from feast.repo_contents import RepoContents + + +@dataclass +class FeastObjectDiff: + name: str + feast_object_type: FeastObjectType + current_feast_object: Optional[FeastObject] + new_feast_object: Optional[FeastObject] + feast_object_property_diffs: List[PropertyDiff] + transition_type: TransitionType + + +@dataclass +class RegistryDiff: + feast_object_diffs: List[FeastObjectDiff] + + def __init__(self): + self.feast_object_diffs = [] + + def add_feast_object_diff(self, feast_object_diff: FeastObjectDiff): + self.feast_object_diffs.append(feast_object_diff) + + def to_string(self): + from colorama import Fore, Style + + log_string = "" + + message_action_map = { + TransitionType.CREATE: ("Created", Fore.GREEN), + TransitionType.DELETE: ("Deleted", Fore.RED), + TransitionType.UNCHANGED: ("Unchanged", Fore.LIGHTBLUE_EX), + TransitionType.UPDATE: ("Updated", Fore.YELLOW), + } + for feast_object_diff in self.feast_object_diffs: + if feast_object_diff.name == DUMMY_ENTITY_NAME: + continue + if feast_object_diff.transition_type == TransitionType.UNCHANGED: + continue + if feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: + # TODO(adchia): Print statements out starting in Feast 0.24 + continue + action, color = message_action_map[feast_object_diff.transition_type] + log_string += f"{action} {feast_object_diff.feast_object_type.value} {Style.BRIGHT + color}{feast_object_diff.name}{Style.RESET_ALL}\n" + if feast_object_diff.transition_type == TransitionType.UPDATE: + for _p in feast_object_diff.feast_object_property_diffs: + log_string += f"\t{_p.property_name}: {Style.BRIGHT + color}{_p.val_existing}{Style.RESET_ALL} -> {Style.BRIGHT + Fore.LIGHTGREEN_EX}{_p.val_declared}{Style.RESET_ALL}\n" + + log_string = ( + f"{Style.BRIGHT + Fore.LIGHTBLUE_EX}No changes to registry" + if not log_string + else log_string + ) + + return log_string + + +def tag_objects_for_keep_delete_update_add( + existing_objs: Iterable[FeastObject], desired_objs: Iterable[FeastObject] +) -> Tuple[Set[FeastObject], Set[FeastObject], Set[FeastObject], Set[FeastObject]]: + # TODO(adchia): Remove the "if X.name" condition when data sources are forced to have names + existing_obj_names = {e.name for e in existing_objs if e.name} + desired_objs = [obj for obj in desired_objs if obj.name] + existing_objs = [obj for obj in existing_objs if obj.name] + desired_obj_names = {e.name for e in desired_objs if e.name} + + objs_to_add = {e for e in desired_objs if e.name not in existing_obj_names} + objs_to_update = {e for e in desired_objs if e.name in existing_obj_names} + objs_to_keep = {e for e in existing_objs if e.name in desired_obj_names} + objs_to_delete = {e for e in existing_objs if e.name not in desired_obj_names} + + return objs_to_keep, objs_to_delete, objs_to_update, objs_to_add + + +FeastObjectProto = TypeVar( + "FeastObjectProto", + DataSourceProto, + EntityProto, + FeatureViewProto, + FeatureServiceProto, + OnDemandFeatureViewProto, + StreamFeatureViewProto, + LabelViewProto, + ValidationReferenceProto, + SavedDatasetProto, + PermissionProto, +) + + +FIELDS_TO_IGNORE = {"project"} + + +def diff_registry_objects( + current: FeastObject, new: FeastObject, object_type: FeastObjectType +) -> FeastObjectDiff: + current_proto = current.to_proto() + new_proto = new.to_proto() + assert current_proto.DESCRIPTOR.full_name == new_proto.DESCRIPTOR.full_name + property_diffs = [] + transition: TransitionType = TransitionType.UNCHANGED + + current_spec: FeastObjectSpecProto + new_spec: FeastObjectSpecProto + if isinstance( + current_proto, (DataSourceProto, ValidationReferenceProto) + ) or isinstance(new_proto, (DataSourceProto, ValidationReferenceProto)): + assert type(current_proto) == type(new_proto) + current_spec = cast(DataSourceProto, current_proto) + new_spec = cast(DataSourceProto, new_proto) + else: + current_spec = current_proto.spec + new_spec = new_proto.spec + if current != new: + for _field in current_spec.DESCRIPTOR.fields: + if _field.name in FIELDS_TO_IGNORE: + continue + elif getattr(current_spec, _field.name) != getattr(new_spec, _field.name): + if _field.name == "feature_transformation": + current_spec = cast(OnDemandFeatureViewSpec, current_spec) + new_spec = cast(OnDemandFeatureViewSpec, new_spec) + # Check if the old proto is populated and use that if it is + feature_transformation_udf = ( + current_spec.feature_transformation.user_defined_function + ) + if ( + current_spec.HasField("user_defined_function") + and not feature_transformation_udf + ): + deprecated_udf = current_spec.user_defined_function + else: + deprecated_udf = None + current_udf = ( + deprecated_udf + if deprecated_udf is not None + else feature_transformation_udf + ) + new_udf = new_spec.feature_transformation.user_defined_function + for _udf_field in current_udf.DESCRIPTOR.fields: + if _udf_field.name == "body": + continue + if getattr(current_udf, _udf_field.name) != getattr( + new_udf, _udf_field.name + ): + transition = TransitionType.UPDATE + property_diffs.append( + PropertyDiff( + _field.name + "." + _udf_field.name, + getattr(current_udf, _udf_field.name), + getattr(new_udf, _udf_field.name), + ) + ) + else: + transition = TransitionType.UPDATE + property_diffs.append( + PropertyDiff( + _field.name, + getattr(current_spec, _field.name), + getattr(new_spec, _field.name), + ) + ) + return FeastObjectDiff( + name=new_spec.name, + feast_object_type=object_type, + current_feast_object=current, + new_feast_object=new, + feast_object_property_diffs=property_diffs, + transition_type=transition, + ) + + +def extract_objects_for_keep_delete_update_add( + registry: BaseRegistry, + current_project: str, + desired_repo_contents: RepoContents, +) -> Tuple[ + Dict[FeastObjectType, Set[FeastObject]], + Dict[FeastObjectType, Set[FeastObject]], + Dict[FeastObjectType, Set[FeastObject]], + Dict[FeastObjectType, Set[FeastObject]], +]: + """ + Returns the objects in the registry that must be modified to achieve the desired repo state. + + Args: + registry: The registry storing the current repo state. + current_project: The Feast project whose objects should be compared. + desired_repo_contents: The desired repo state. + """ + objs_to_keep = {} + objs_to_delete = {} + objs_to_update = {} + objs_to_add = {} + + registry_object_type_to_objects: Dict[FeastObjectType, List[Any]] = ( + FeastObjectType.get_objects_from_registry(registry, current_project) + ) + registry_object_type_to_repo_contents: Dict[FeastObjectType, List[Any]] = ( + FeastObjectType.get_objects_from_repo_contents(desired_repo_contents) + ) + + for object_type in FEAST_OBJECT_TYPES: + ( + to_keep, + to_delete, + to_update, + to_add, + ) = tag_objects_for_keep_delete_update_add( + registry_object_type_to_objects[object_type], + registry_object_type_to_repo_contents[object_type], + ) + + objs_to_keep[object_type] = to_keep + objs_to_delete[object_type] = to_delete + objs_to_update[object_type] = to_update + objs_to_add[object_type] = to_add + + return objs_to_keep, objs_to_delete, objs_to_update, objs_to_add + + +def diff_between( + registry: BaseRegistry, + current_project: str, + desired_repo_contents: RepoContents, +) -> RegistryDiff: + """ + Returns the difference between the current and desired repo states. + + Args: + registry: The registry storing the current repo state. + current_project: The Feast project for which the diff is being computed. + desired_repo_contents: The desired repo state. + """ + diff = RegistryDiff() + + ( + objs_to_keep, + objs_to_delete, + objs_to_update, + objs_to_add, + ) = extract_objects_for_keep_delete_update_add( + registry, current_project, desired_repo_contents + ) + + for object_type in FEAST_OBJECT_TYPES: + objects_to_keep = objs_to_keep[object_type] + objects_to_delete = objs_to_delete[object_type] + objects_to_update = objs_to_update[object_type] + objects_to_add = objs_to_add[object_type] + + for e in objects_to_add: + diff.add_feast_object_diff( + FeastObjectDiff( + name=e.name, + feast_object_type=object_type, + current_feast_object=None, + new_feast_object=e, + feast_object_property_diffs=[], + transition_type=TransitionType.CREATE, + ) + ) + for e in objects_to_delete: + diff.add_feast_object_diff( + FeastObjectDiff( + name=e.name, + feast_object_type=object_type, + current_feast_object=e, + new_feast_object=None, + feast_object_property_diffs=[], + transition_type=TransitionType.DELETE, + ) + ) + for e in objects_to_update: + current_obj = [_e for _e in objects_to_keep if _e.name == e.name][0] + diff.add_feast_object_diff( + diff_registry_objects(current_obj, e, object_type) + ) + + return diff + + +def apply_diff_to_registry( + registry: BaseRegistry, + registry_diff: RegistryDiff, + project: str, + commit: bool = True, + no_promote: bool = False, +): + """ + Applies the given diff to the given Feast project in the registry. + + Args: + registry: The registry to be updated. + registry_diff: The diff to apply. + project: Feast project to be updated. + commit: Whether the change should be persisted immediately + no_promote: If True, save new feature view version snapshots without + promoting them to the active definition. New versions are accessible + only via explicit @v reads. + """ + for feast_object_diff in registry_diff.feast_object_diffs: + # There is no need to delete the object on an update, since applying the new object + # will automatically delete the existing object. + if feast_object_diff.transition_type == TransitionType.DELETE: + if feast_object_diff.feast_object_type == FeastObjectType.ENTITY: + entity_obj = cast(Entity, feast_object_diff.current_feast_object) + registry.delete_entity(entity_obj.name, project, commit=False) + elif feast_object_diff.feast_object_type == FeastObjectType.FEATURE_SERVICE: + feature_service_obj = cast( + FeatureService, feast_object_diff.current_feast_object + ) + registry.delete_feature_service( + feature_service_obj.name, project, commit=False + ) + elif feast_object_diff.feast_object_type in [ + FeastObjectType.FEATURE_VIEW, + FeastObjectType.ON_DEMAND_FEATURE_VIEW, + FeastObjectType.STREAM_FEATURE_VIEW, + FeastObjectType.LABEL_VIEW, + ]: + feature_view_obj = cast( + BaseFeatureView, feast_object_diff.current_feast_object + ) + registry.delete_feature_view( + feature_view_obj.name, + project, + commit=False, + ) + elif feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: + ds_obj = cast(DataSource, feast_object_diff.current_feast_object) + registry.delete_data_source( + ds_obj.name, + project, + commit=False, + ) + elif feast_object_diff.feast_object_type == FeastObjectType.PERMISSION: + permission_obj = cast( + Permission, feast_object_diff.current_feast_object + ) + registry.delete_permission( + permission_obj.name, + project, + commit=False, + ) + + if feast_object_diff.transition_type in [ + TransitionType.CREATE, + TransitionType.UPDATE, + ]: + if feast_object_diff.feast_object_type == FeastObjectType.PROJECT: + registry.apply_project( + cast(Project, feast_object_diff.new_feast_object), + commit=False, + ) + if feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE: + registry.apply_data_source( + cast(DataSource, feast_object_diff.new_feast_object), + project, + commit=False, + ) + if feast_object_diff.feast_object_type == FeastObjectType.ENTITY: + registry.apply_entity( + cast(Entity, feast_object_diff.new_feast_object), + project, + commit=False, + ) + elif feast_object_diff.feast_object_type == FeastObjectType.FEATURE_SERVICE: + registry.apply_feature_service( + cast(FeatureService, feast_object_diff.new_feast_object), + project, + commit=False, + ) + elif feast_object_diff.feast_object_type in [ + FeastObjectType.FEATURE_VIEW, + FeastObjectType.ON_DEMAND_FEATURE_VIEW, + FeastObjectType.STREAM_FEATURE_VIEW, + FeastObjectType.LABEL_VIEW, + ]: + registry.apply_feature_view( + cast(BaseFeatureView, feast_object_diff.new_feast_object), + project, + commit=False, + no_promote=no_promote, + ) + elif feast_object_diff.feast_object_type == FeastObjectType.PERMISSION: + registry.apply_permission( + cast(Permission, feast_object_diff.new_feast_object), + project, + commit=False, + ) + + if commit: + registry.commit() diff --git a/sdk/python/feast/doc_embedder.py b/sdk/python/feast/doc_embedder.py new file mode 100644 index 00000000000..9ccd8ec461b --- /dev/null +++ b/sdk/python/feast/doc_embedder.py @@ -0,0 +1,380 @@ +import inspect +import os +import warnings +from pathlib import Path +from typing import TYPE_CHECKING, Callable, Optional, Protocol, runtime_checkable + +import pandas as pd + +from feast.chunker import BaseChunker, TextChunker +from feast.embedder import BaseEmbedder, MultiModalEmbedder + +if TYPE_CHECKING: + from feast.feature_store import FeatureStore + + +@runtime_checkable +class SchemaTransformFn(Protocol): + """ + Protocol defining the structure for schema transform functions. + + The schema transform converts the output of Chunker + Embedder + into the format expected by the FeatureView schema. + """ + + def __call__(self, df: pd.DataFrame) -> pd.DataFrame: + """ + Transform chunked + embedded DataFrame to FeatureView schema. + + Args: + df: Input DataFrame with chunks and embeddings. + + Returns: + DataFrame with columns matching FeatureView schema. + """ + ... + + +def default_schema_transform_fn(df: pd.DataFrame) -> pd.DataFrame: + """ + Default schema transform function that transforms the output of Chunker + Embedder + into the format expected by the FeatureView schema. + """ + from datetime import datetime, timezone + + return pd.DataFrame( + { + "passage_id": df["chunk_id"], + "text": df["text"], + "embedding": df["text_embedding"], + "event_timestamp": [datetime.now(timezone.utc)] * len(df), + "source_id": df["original_id"], + } + ) + + +def generate_repo_file( + repo_path: str, + feature_view_name: str = "text_feature_view", + vector_length: int = 384, +) -> str: + """ + Generate a Python file with Entity and FeatureView definitions. + + This file is compatible with `feast apply` CLI. + + Args: + repo_path: Path to the feature repo directory. + feature_view_name: Name of the feature view to create. + vector_length: Dimension of the embedding vectors. Should match the + output dimension of the embedding model being used. Defaults to + 384 (matching the default all-MiniLM-L6-v2 model). + + Returns: + Path to generated file. + """ + from feast.repo_operations import is_valid_name + + if not is_valid_name(feature_view_name) or not feature_view_name.isidentifier(): + raise ValueError( + f"feature_view_name '{feature_view_name}' is invalid. " + "It should only contain alphanumeric characters, underscores, " + "and must not start with an underscore." + ) + code = f'''""" +Auto-generated by DocEmbedder. +Compatible with `feast apply` CLI. +""" +from datetime import timedelta + +from feast import Entity, FeatureView, Field, FileSource +from feast.types import Array, Float32, String, ValueType + + +# Entity +text_entity = Entity( + name="passage_id", + join_keys=["passage_id"], + description="Passage identifier", + value_type=ValueType.STRING, +) + +# Source +{feature_view_name.replace(" ", "_").replace("-", "_")}_source = FileSource( + name="{feature_view_name}_source", + path="data/{feature_view_name}.parquet", + timestamp_field="event_timestamp", +) + +# FeatureView +{feature_view_name.replace(" ", "_").replace("-", "_")} = FeatureView( + name="{feature_view_name}", + entities=[text_entity], + ttl=timedelta(days=1), + schema=[ + Field( + name="text", + dtype=String, + description="Document text content", + ), + Field( + name="embedding", + dtype=Array(Float32), + description="Vector embedding", + vector_index=True, + vector_length={vector_length}, + vector_search_metric="COSINE", + ), + Field( + name="source_id", + dtype=String, + description="Source ID", + ), + ], + source={feature_view_name.replace(" ", "_").replace("-", "_")}_source, + online=True, +) +''' + + filepath = os.path.join( + repo_path, feature_view_name.replace(" ", "_").replace("-", "_") + ".py" + ) + with open(filepath, "w") as f: + f.write(code) + + return filepath + + +class DocEmbedder: + """ + DocEmbedder is a class that embeds documents and chunks them into a format expected by the FeatureView schema using a Logic Implementation By the user. + + Args: + repo_path: Path to the feature repo (can be "." for current directory). + yaml_file: Name of the feature_store.yaml file inside repo_path. + Defaults to "feature_store.yaml". + feature_view_name: Name of the feature view to create. + chunker: Chunker to use for chunking the documents. + embedder: Embedder to use for embedding the documents. + schema_transform_fn: Schema transform function to use for transforming the output of the chunker and embedder into the format expected by the FeatureView schema. + create_feature_view: Whether to create a feature view in the feature repo. By default it will generate a Python file with the FeatureView definition. + vector_length: Explicit embedding dimension for the generated FeatureView schema. + If None (default), the dimension is auto-detected from the embedder + via ``get_embedding_dim("text")``. Falls back to 384 if detection + is not supported by the embedder. + auto_apply_repo: Whether to apply the repository automatically. By default it will apply the repository after creating the feature view. + """ + + def __init__( + self, + repo_path: str, + yaml_file: str = "feature_store.yaml", + feature_view_name: str = "text_feature_view", + chunker: Optional[BaseChunker] = None, + embedder: Optional[BaseEmbedder] = None, + schema_transform_fn: SchemaTransformFn = default_schema_transform_fn, + create_feature_view: bool = True, + vector_length: Optional[int] = None, + auto_apply_repo: bool = True, + ): + self.repo_path = repo_path + self.yaml_path = os.path.join(Path(repo_path).resolve(), yaml_file) + self.feature_view_name = feature_view_name + self.chunker = chunker or TextChunker() + self.embedder = embedder or MultiModalEmbedder() + self.store: Optional[FeatureStore] = None + + sig = inspect.signature(schema_transform_fn) + params = list(sig.parameters.values()) + if ( + len(params) != 1 + or params[0].annotation != pd.DataFrame + or sig.return_annotation != pd.DataFrame + ): + raise ValueError( + "schema_transform_fn must be a function that takes a DataFrame and returns a DataFrame" + ) + self.schema_transform_fn = schema_transform_fn + if create_feature_view: + resolved_vector_length = self._resolve_vector_length(vector_length, "text") + generate_repo_file( + repo_path=repo_path, + feature_view_name=feature_view_name, + vector_length=resolved_vector_length, + ) + if auto_apply_repo: + self.apply_repo() + + def _resolve_vector_length( + self, explicit_length: Optional[int], modality: str + ) -> int: + """ + Determine the vector length to use for the generated FeatureView. + + Priority: + 1. Explicitly provided vector_length + 2. Auto-detected from embedder via get_embedding_dim("text") + 3. Default of 384 (matching all-MiniLM-L6-v2) + + Args: + explicit_length: User-provided vector length, or None. + + Returns: + The resolved vector length as an integer. + """ + _DEFAULT_VECTOR_LENGTH = 384 + + if explicit_length is not None: + return explicit_length + + try: + dim = self.embedder.get_embedding_dim(modality) + if dim is not None: + return dim + except Exception: + pass + + return _DEFAULT_VECTOR_LENGTH + + def save_to_online_store(self, df: pd.DataFrame, feature_view_name: str) -> None: + """ + Save the embedded documents to the online store. + """ + from feast.feature_store import FeatureStore + + if self.store is None: + self.store = FeatureStore(repo_path=self.repo_path) + self.store.write_to_online_store( + feature_view_name=feature_view_name, + df=df, + ) + + # TODO (Future scope): Implement save_to_offline_store to write embedded + # documents to the offline store. Currently blocked by DaskOfflineStore + # .offline_write_batch not creating the parquet file if it does not exist. + # Once that is fixed, add a method that calls: + # store = FeatureStore(repo_path=self.repo_path) + # store.write_to_offline_store(feature_view_name=feature_view_name, df=df) + + def apply_repo(self) -> None: + """ + Apply the repository to register feature views in the registry. + """ + from feast.repo_config import load_repo_config + from feast.repo_operations import apply_total + + original_cwd = None + try: + original_cwd = os.getcwd() + repo_path = Path(self.repo_path).resolve() + config = load_repo_config( + repo_path=repo_path, + fs_yaml_file=Path(self.yaml_path), + ) + apply_total( + repo_config=config, + repo_path=repo_path, + skip_source_validation=True, + ) + finally: + if original_cwd is not None: + os.chdir(original_cwd) + + def embed_documents( + self, + documents: pd.DataFrame, + id_column: str, + source_column: str, + type_column: Optional[str] = None, + column_mapping: Optional[tuple[str, str]] = None, + custom_schema_transform_fn: Optional[ + Callable[[pd.DataFrame], pd.DataFrame] + ] = None, + ) -> pd.DataFrame: + """ + Embed a list of documents and chunk them into a format expected by the FeatureView schema using a Logic Implementation By the user and save the DataFrame to the online store. + + Args: + documents: DataFrame containing the documents to embed. + id_column: Column name containing the document IDs. + source_column: Column name containing the document sources. + type_column: Column name containing the document types. + column_mapping: Tuple mapping source columns to (modality, output column). + custom_schema_transform_fn: Custom schema transform function to use for transforming the output of the chunker and embedder into the format expected by the FeatureView schema. + Returns: + DataFrame with the embedded documents. + + Example: + documents = pd.DataFrame({ + "id": [1, 2, 3], + "source": ["source1", "source2", "source3"], + "type": ["type1", "type2", "type3"], + "text": ["text1", "text2", "text3"], + }) + column_mapping = ("text", "text_embedding") + df = embed_documents(documents=documents, id_column="id", source_column="source", type_column="type", column_mapping=column_mapping) + + """ + if custom_schema_transform_fn is not None: + sig = inspect.signature(custom_schema_transform_fn) + params = list(sig.parameters.values()) + if ( + len(params) != 1 + or params[0].annotation != pd.DataFrame + or sig.return_annotation != pd.DataFrame + ): + raise ValueError( + "custom_schema_transform_fn must be a function that takes a DataFrame and returns a DataFrame" + ) + current_schema_transform_fn = ( + custom_schema_transform_fn + if custom_schema_transform_fn is not None + else self.schema_transform_fn + ) + + if column_mapping is None: + column_mapping = ("text", "text_embedding") + + if ( + current_schema_transform_fn is default_schema_transform_fn + and column_mapping[0] == "text" + and (source_column != "text" or column_mapping[1] != "text_embedding") + ): + raise ValueError( + f"source_column='{source_column}' with output column='{column_mapping[1]}' " + f"is not compatible with default_schema_transform_fn, which expects " + f"source_column='text' and column_mapping=('text', 'text_embedding'). " + f"Provide a custom schema_transform_fn." + ) + + if column_mapping[0] == "text": + df = self.chunker.chunk_dataframe( + df=documents, + id_column=id_column, + source_column=source_column, + type_column=type_column, + ) + else: + df = documents + + df = self.embedder.embed_dataframe( + df, column_mapping={source_column: column_mapping} + ) + + if ( + column_mapping[0] == "text" + or current_schema_transform_fn is not default_schema_transform_fn + ): + df = current_schema_transform_fn(df) + else: + warnings.warn( + f"Modality '{column_mapping[0]}' is not supported by the default schema transform function. " + f"The output DataFrame will be passed directly to the online store. " + f"Ensure your FeatureView schema matches the output columns. " + f"You can provide a custom schema transform function to handle this.", + UserWarning, + stacklevel=2, + ) + + self.save_to_online_store(df=df, feature_view_name=self.feature_view_name) + return df diff --git a/sdk/python/feast/embedded_go/online_features_service.py b/sdk/python/feast/embedded_go/online_features_service.py index 8dd7b5ba0a1..cc54808d4e2 100644 --- a/sdk/python/feast/embedded_go/online_features_service.py +++ b/sdk/python/feast/embedded_go/online_features_service.py @@ -1,345 +1,346 @@ -import logging -from functools import partial -from pathlib import Path -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union - -import pyarrow as pa -from google.protobuf.timestamp_pb2 import Timestamp -from pyarrow.cffi import ffi - -from feast.errors import ( - FeatureNameCollisionError, - RequestDataNotFoundInEntityRowsException, -) -from feast.feature_service import FeatureService -from feast.infra.feature_servers.base_config import FeatureLoggingConfig -from feast.online_response import OnlineResponse -from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse -from feast.protos.feast.types import Value_pb2 -from feast.repo_config import RepoConfig -from feast.types import from_value_type -from feast.value_type import ValueType - -from .lib.embedded import ( - DataTable, - LoggingOptions, - NewOnlineFeatureService, - OnlineFeatureServiceConfig, -) -from .lib.go import Slice_string -from .type_map import FEAST_TYPE_TO_ARROW_TYPE, arrow_array_to_array_of_proto - -if TYPE_CHECKING: - from feast.feature_store import FeatureStore - -NANO_SECOND = 1 -MICRO_SECOND = 1000 * NANO_SECOND -MILLI_SECOND = 1000 * MICRO_SECOND -SECOND = 1000 * MILLI_SECOND - -logger = logging.getLogger(__name__) - - -class EmbeddedOnlineFeatureServer: - def __init__( - self, repo_path: str, repo_config: RepoConfig, feature_store: "FeatureStore" - ): - # keep callback in self to prevent it from GC - self._transformation_callback = partial(transformation_callback, feature_store) - self._logging_callback = partial(logging_callback, feature_store) - - self._config = OnlineFeatureServiceConfig( - RepoPath=repo_path, RepoConfig=repo_config.json() - ) - - self._service = NewOnlineFeatureService( - self._config, - self._transformation_callback, - ) - - # This should raise an exception if there were any errors in NewOnlineFeatureService. - self._service.CheckForInstantiationError() - - def get_online_features( - self, - features_refs: List[str], - feature_service: Optional[FeatureService], - entities: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], - request_data: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], - full_feature_names: bool = False, - ): - if feature_service: - join_keys_types = self._service.GetEntityTypesMapByFeatureService( - feature_service.name - ) - else: - join_keys_types = self._service.GetEntityTypesMap( - Slice_string(features_refs) - ) - - join_keys_types = { - join_key: ValueType(enum_value) for join_key, enum_value in join_keys_types - } - - # Here we create C structures that will be shared between Python and Go. - # We will pass entities as arrow Record Batch to Go part (in_c_array & in_c_schema) - # and receive features as Record Batch from Go (out_c_array & out_c_schema) - # This objects needs to be initialized here in order to correctly - # free them later using Python GC. - ( - entities_c_schema, - entities_ptr_schema, - entities_c_array, - entities_ptr_array, - ) = allocate_schema_and_array() - ( - req_data_c_schema, - req_data_ptr_schema, - req_data_c_array, - req_data_ptr_array, - ) = allocate_schema_and_array() - - ( - features_c_schema, - features_ptr_schema, - features_c_array, - features_ptr_array, - ) = allocate_schema_and_array() - - batch, schema = map_to_record_batch(entities, join_keys_types) - schema._export_to_c(entities_ptr_schema) - batch._export_to_c(entities_ptr_array) - - batch, schema = map_to_record_batch(request_data) - schema._export_to_c(req_data_ptr_schema) - batch._export_to_c(req_data_ptr_array) - - try: - self._service.GetOnlineFeatures( - featureRefs=Slice_string(features_refs), - featureServiceName=feature_service and feature_service.name or "", - entities=DataTable( - SchemaPtr=entities_ptr_schema, DataPtr=entities_ptr_array - ), - requestData=DataTable( - SchemaPtr=req_data_ptr_schema, DataPtr=req_data_ptr_array - ), - fullFeatureNames=full_feature_names, - output=DataTable( - SchemaPtr=features_ptr_schema, DataPtr=features_ptr_array - ), - ) - except RuntimeError as exc: - (msg,) = exc.args - if msg.startswith("featureNameCollisionError"): - feature_refs = msg[len("featureNameCollisionError: ") : msg.find(";")] - feature_refs = feature_refs.split(",") - raise FeatureNameCollisionError( - feature_refs_collisions=feature_refs, - full_feature_names=full_feature_names, - ) - - if msg.startswith("requestDataNotFoundInEntityRowsException"): - feature_refs = msg[len("requestDataNotFoundInEntityRowsException: ") :] - feature_refs = feature_refs.split(",") - raise RequestDataNotFoundInEntityRowsException(feature_refs) - - raise - - record_batch = pa.RecordBatch._import_from_c( - features_ptr_array, features_ptr_schema - ) - resp = record_batch_to_online_response(record_batch) - del record_batch - return OnlineResponse(resp) - - def start_grpc_server( - self, - host: str, - port: int, - enable_logging: bool = True, - logging_options: Optional[FeatureLoggingConfig] = None, - ): - if enable_logging: - if logging_options: - self._service.StartGprcServerWithLogging( - host, - port, - self._logging_callback, - LoggingOptions( - FlushInterval=logging_options.flush_interval_secs * SECOND, - WriteInterval=logging_options.write_to_disk_interval_secs - * SECOND, - EmitTimeout=logging_options.emit_timeout_micro_secs - * MICRO_SECOND, - ChannelCapacity=logging_options.queue_capacity, - ), - ) - else: - self._service.StartGprcServerWithLoggingDefaultOpts( - host, port, self._logging_callback - ) - else: - self._service.StartGprcServer(host, port) - - def start_http_server( - self, - host: str, - port: int, - enable_logging: bool = True, - logging_options: Optional[FeatureLoggingConfig] = None, - ): - if enable_logging: - if logging_options: - self._service.StartHttpServerWithLogging( - host, - port, - self._logging_callback, - LoggingOptions( - FlushInterval=logging_options.flush_interval_secs * SECOND, - WriteInterval=logging_options.write_to_disk_interval_secs - * SECOND, - EmitTimeout=logging_options.emit_timeout_micro_secs - * MICRO_SECOND, - ChannelCapacity=logging_options.queue_capacity, - ), - ) - else: - self._service.StartHttpServerWithLoggingDefaultOpts( - host, port, self._logging_callback - ) - else: - self._service.StartHttpServer(host, port) - - def stop_grpc_server(self): - self._service.StopGrpcServer() - - def stop_http_server(self): - self._service.StopHttpServer() - - -def _to_arrow(value, type_hint: Optional[ValueType]) -> pa.Array: - if isinstance(value, Value_pb2.RepeatedValue): - _proto_to_arrow(value) - - if type_hint: - feast_type = from_value_type(type_hint) - if feast_type in FEAST_TYPE_TO_ARROW_TYPE: - return pa.array(value, FEAST_TYPE_TO_ARROW_TYPE[feast_type]) - - return pa.array(value) - - -def _proto_to_arrow(value: Value_pb2.RepeatedValue) -> pa.Array: - """ - ToDo: support entity rows already packed in protos - """ - raise NotImplementedError - - -def transformation_callback( - fs: "FeatureStore", - on_demand_feature_view_name: str, - input_arr_ptr: int, - input_schema_ptr: int, - output_arr_ptr: int, - output_schema_ptr: int, - full_feature_names: bool, -) -> int: - try: - odfv = fs.get_on_demand_feature_view(on_demand_feature_view_name) - - input_record = pa.RecordBatch._import_from_c(input_arr_ptr, input_schema_ptr) - - # For some reason, the callback is called with `full_feature_names` as a 1 if True or 0 if false. This handles - # the typeguard requirement. - full_feature_names = bool(full_feature_names) - - if odfv.mode != "pandas": - raise Exception( - f"OnDemandFeatureView mode '{odfv.mode} not supported by EmbeddedOnlineFeatureServer." - ) - - output = odfv.get_transformed_features_df( # type: ignore - input_record.to_pandas(), full_feature_names=full_feature_names - ) - output_record = pa.RecordBatch.from_pandas(output) - - output_record.schema._export_to_c(output_schema_ptr) - output_record._export_to_c(output_arr_ptr) - - return output_record.num_rows - except Exception as e: - logger.exception(f"transformation callback failed with exception: {e}", e) - return 0 - - -def logging_callback( - fs: "FeatureStore", - feature_service_name: str, - dataset_dir: str, -) -> bytes: - feature_service = fs.get_feature_service(feature_service_name, allow_cache=True) - try: - fs.write_logged_features(logs=Path(dataset_dir), source=feature_service) - except Exception as exc: - return repr(exc).encode() - - return "".encode() # no error - - -def allocate_schema_and_array(): - c_schema = ffi.new("struct ArrowSchema*") - ptr_schema = int(ffi.cast("uintptr_t", c_schema)) - - c_array = ffi.new("struct ArrowArray*") - ptr_array = int(ffi.cast("uintptr_t", c_array)) - return c_schema, ptr_schema, c_array, ptr_array - - -def map_to_record_batch( - map: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], - type_hint: Optional[Dict[str, ValueType]] = None, -) -> Tuple[pa.RecordBatch, pa.Schema]: - fields = [] - columns = [] - type_hint = type_hint or {} - - for name, values in map.items(): - arr = _to_arrow(values, type_hint.get(name)) - fields.append((name, arr.type)) - columns.append(arr) - - schema = pa.schema(fields) - batch = pa.RecordBatch.from_arrays(columns, schema=schema) - return batch, schema - - -def record_batch_to_online_response(record_batch): - resp = GetOnlineFeaturesResponse() - - for idx, field in enumerate(record_batch.schema): - if field.name.endswith("__timestamp") or field.name.endswith("__status"): - continue - - feature_vector = GetOnlineFeaturesResponse.FeatureVector( - statuses=record_batch.columns[idx + 1].to_pylist(), - event_timestamps=[ - Timestamp(seconds=seconds) - for seconds in record_batch.columns[idx + 2].to_pylist() - ], - ) - - if field.type == pa.null(): - feature_vector.values.extend( - [Value_pb2.Value()] * len(record_batch.columns[idx]) - ) - else: - feature_vector.values.extend( - arrow_array_to_array_of_proto(field.type, record_batch.columns[idx]) - ) - - resp.results.append(feature_vector) - resp.metadata.feature_names.val.append(field.name) - - return resp +import logging +from functools import partial +from pathlib import Path +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union + +import pyarrow as pa +from google.protobuf.timestamp_pb2 import Timestamp +from pyarrow.cffi import ffi + +from feast.errors import ( + FeatureNameCollisionError, + RequestDataNotFoundInEntityRowsException, +) +from feast.feature_service import FeatureService +from feast.infra.feature_servers.base_config import FeatureLoggingConfig +from feast.online_response import OnlineResponse +from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse +from feast.protos.feast.types import Value_pb2 +from feast.repo_config import RepoConfig +from feast.types import from_value_type +from feast.value_type import ValueType + +from .lib.embedded import ( + DataTable, + LoggingOptions, + NewOnlineFeatureService, + OnlineFeatureServiceConfig, +) +from .lib.go import Slice_string +from .type_map import FEAST_TYPE_TO_ARROW_TYPE, arrow_array_to_array_of_proto + +if TYPE_CHECKING: + from feast.feature_store import FeatureStore + +NANO_SECOND = 1 +MICRO_SECOND = 1000 * NANO_SECOND +MILLI_SECOND = 1000 * MICRO_SECOND +SECOND = 1000 * MILLI_SECOND + +logger = logging.getLogger(__name__) + + +class EmbeddedOnlineFeatureServer: + def __init__( + self, repo_path: str, repo_config: RepoConfig, feature_store: "FeatureStore" + ): + # keep callback in self to prevent it from GC + self._transformation_callback = partial(transformation_callback, feature_store) + self._logging_callback = partial(logging_callback, feature_store) + + self._config = OnlineFeatureServiceConfig( + RepoPath=repo_path, RepoConfig=repo_config.json() + ) + + self._service = NewOnlineFeatureService( + self._config, + self._transformation_callback, + ) + + # This should raise an exception if there were any errors in NewOnlineFeatureService. + self._service.CheckForInstantiationError() + + def get_online_features( + self, + features_refs: List[str], + feature_service: Optional[FeatureService], + entities: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], + request_data: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], + full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, + ): + if feature_service: + join_keys_types = self._service.GetEntityTypesMapByFeatureService( + feature_service.name + ) + else: + join_keys_types = self._service.GetEntityTypesMap( + Slice_string(features_refs) + ) + + join_keys_types = { + join_key: ValueType(enum_value) for join_key, enum_value in join_keys_types + } + + # Here we create C structures that will be shared between Python and Go. + # We will pass entities as arrow Record Batch to Go part (in_c_array & in_c_schema) + # and receive features as Record Batch from Go (out_c_array & out_c_schema) + # This objects needs to be initialized here in order to correctly + # free them later using Python GC. + ( + entities_c_schema, + entities_ptr_schema, + entities_c_array, + entities_ptr_array, + ) = allocate_schema_and_array() + ( + req_data_c_schema, + req_data_ptr_schema, + req_data_c_array, + req_data_ptr_array, + ) = allocate_schema_and_array() + + ( + features_c_schema, + features_ptr_schema, + features_c_array, + features_ptr_array, + ) = allocate_schema_and_array() + + batch, schema = map_to_record_batch(entities, join_keys_types) + schema._export_to_c(entities_ptr_schema) + batch._export_to_c(entities_ptr_array) + + batch, schema = map_to_record_batch(request_data) + schema._export_to_c(req_data_ptr_schema) + batch._export_to_c(req_data_ptr_array) + + try: + self._service.GetOnlineFeatures( + featureRefs=Slice_string(features_refs), + featureServiceName=feature_service and feature_service.name or "", + entities=DataTable( + SchemaPtr=entities_ptr_schema, DataPtr=entities_ptr_array + ), + requestData=DataTable( + SchemaPtr=req_data_ptr_schema, DataPtr=req_data_ptr_array + ), + fullFeatureNames=full_feature_names, + output=DataTable( + SchemaPtr=features_ptr_schema, DataPtr=features_ptr_array + ), + ) + except RuntimeError as exc: + (msg,) = exc.args + if msg.startswith("featureNameCollisionError"): + feature_refs = msg[len("featureNameCollisionError: ") : msg.find(";")] + feature_refs = feature_refs.split(",") + raise FeatureNameCollisionError( + feature_refs_collisions=feature_refs, + full_feature_names=full_feature_names, + ) + + if msg.startswith("requestDataNotFoundInEntityRowsException"): + feature_refs = msg[len("requestDataNotFoundInEntityRowsException: ") :] + feature_refs = feature_refs.split(",") + raise RequestDataNotFoundInEntityRowsException(feature_refs) + + raise + + record_batch = pa.RecordBatch._import_from_c( + features_ptr_array, features_ptr_schema + ) + resp = record_batch_to_online_response(record_batch) + del record_batch + return OnlineResponse(resp) + + def start_grpc_server( + self, + host: str, + port: int, + enable_logging: bool = True, + logging_options: Optional[FeatureLoggingConfig] = None, + ): + if enable_logging: + if logging_options: + self._service.StartGprcServerWithLogging( + host, + port, + self._logging_callback, + LoggingOptions( + FlushInterval=logging_options.flush_interval_secs * SECOND, + WriteInterval=logging_options.write_to_disk_interval_secs + * SECOND, + EmitTimeout=logging_options.emit_timeout_micro_secs + * MICRO_SECOND, + ChannelCapacity=logging_options.queue_capacity, + ), + ) + else: + self._service.StartGprcServerWithLoggingDefaultOpts( + host, port, self._logging_callback + ) + else: + self._service.StartGprcServer(host, port) + + def start_http_server( + self, + host: str, + port: int, + enable_logging: bool = True, + logging_options: Optional[FeatureLoggingConfig] = None, + ): + if enable_logging: + if logging_options: + self._service.StartHttpServerWithLogging( + host, + port, + self._logging_callback, + LoggingOptions( + FlushInterval=logging_options.flush_interval_secs * SECOND, + WriteInterval=logging_options.write_to_disk_interval_secs + * SECOND, + EmitTimeout=logging_options.emit_timeout_micro_secs + * MICRO_SECOND, + ChannelCapacity=logging_options.queue_capacity, + ), + ) + else: + self._service.StartHttpServerWithLoggingDefaultOpts( + host, port, self._logging_callback + ) + else: + self._service.StartHttpServer(host, port) + + def stop_grpc_server(self): + self._service.StopGrpcServer() + + def stop_http_server(self): + self._service.StopHttpServer() + + +def _to_arrow(value, type_hint: Optional[ValueType]) -> pa.Array: + if isinstance(value, Value_pb2.RepeatedValue): + _proto_to_arrow(value) + + if type_hint: + feast_type = from_value_type(type_hint) + if feast_type in FEAST_TYPE_TO_ARROW_TYPE: + return pa.array(value, FEAST_TYPE_TO_ARROW_TYPE[feast_type]) + + return pa.array(value) + + +def _proto_to_arrow(value: Value_pb2.RepeatedValue) -> pa.Array: + """ + ToDo: support entity rows already packed in protos + """ + raise NotImplementedError + + +def transformation_callback( + fs: "FeatureStore", + on_demand_feature_view_name: str, + input_arr_ptr: int, + input_schema_ptr: int, + output_arr_ptr: int, + output_schema_ptr: int, + full_feature_names: bool, +) -> int: + try: + odfv = fs.get_on_demand_feature_view(on_demand_feature_view_name) + + input_record = pa.RecordBatch._import_from_c(input_arr_ptr, input_schema_ptr) + + # For some reason, the callback is called with `full_feature_names` as a 1 if True or 0 if false. This handles + # the typeguard requirement. + full_feature_names = bool(full_feature_names) + + if odfv.mode != "pandas": + raise Exception( + f"OnDemandFeatureView mode '{odfv.mode} not supported by EmbeddedOnlineFeatureServer." + ) + + output = odfv.get_transformed_features_df( # type: ignore + input_record.to_pandas(), full_feature_names=full_feature_names + ) + output_record = pa.RecordBatch.from_pandas(output) + + output_record.schema._export_to_c(output_schema_ptr) + output_record._export_to_c(output_arr_ptr) + + return output_record.num_rows + except Exception as e: + logger.exception(f"transformation callback failed with exception: {e}", e) + return 0 + + +def logging_callback( + fs: "FeatureStore", + feature_service_name: str, + dataset_dir: str, +) -> bytes: + feature_service = fs.get_feature_service(feature_service_name, allow_cache=True) + try: + fs.write_logged_features(logs=Path(dataset_dir), source=feature_service) + except Exception as exc: + return repr(exc).encode() + + return "".encode() # no error + + +def allocate_schema_and_array(): + c_schema = ffi.new("struct ArrowSchema*") + ptr_schema = int(ffi.cast("uintptr_t", c_schema)) + + c_array = ffi.new("struct ArrowArray*") + ptr_array = int(ffi.cast("uintptr_t", c_array)) + return c_schema, ptr_schema, c_array, ptr_array + + +def map_to_record_batch( + map: Dict[str, Union[List[Any], Value_pb2.RepeatedValue]], + type_hint: Optional[Dict[str, ValueType]] = None, +) -> Tuple[pa.RecordBatch, pa.Schema]: + fields = [] + columns = [] + type_hint = type_hint or {} + + for name, values in map.items(): + arr = _to_arrow(values, type_hint.get(name)) + fields.append((name, arr.type)) + columns.append(arr) + + schema = pa.schema(fields) + batch = pa.RecordBatch.from_arrays(columns, schema=schema) + return batch, schema + + +def record_batch_to_online_response(record_batch): + resp = GetOnlineFeaturesResponse() + + for idx, field in enumerate(record_batch.schema): + if field.name.endswith("__timestamp") or field.name.endswith("__status"): + continue + + feature_vector = GetOnlineFeaturesResponse.FeatureVector( + statuses=record_batch.columns[idx + 1].to_pylist(), + event_timestamps=[ + Timestamp(seconds=seconds) + for seconds in record_batch.columns[idx + 2].to_pylist() + ], + ) + + if field.type == pa.null(): + feature_vector.values.extend( + [Value_pb2.Value()] * len(record_batch.columns[idx]) + ) + else: + feature_vector.values.extend( + arrow_array_to_array_of_proto(field.type, record_batch.columns[idx]) + ) + + resp.results.append(feature_vector) + resp.metadata.feature_names.val.append(field.name) + + return resp diff --git a/sdk/python/feast/embedder.py b/sdk/python/feast/embedder.py new file mode 100644 index 00000000000..c847f78a21c --- /dev/null +++ b/sdk/python/feast/embedder.py @@ -0,0 +1,241 @@ +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Callable, List, Optional + +if TYPE_CHECKING: + import numpy as np +import pandas as pd + + +@dataclass +class EmbeddingConfig: + batch_size: int = 64 + show_progress: bool = True + + +class BaseEmbedder(ABC): + """ + Abstract base class for embedding generation. + + Supports multiple modalities via routing. + Users can register custom modality handlers. + """ + + def __init__(self, config: Optional[EmbeddingConfig] = None): + self.config = config or EmbeddingConfig() + + # Registry: modality -> embedding function + self._modality_handlers: dict[str, Callable[[List[Any]], "np.ndarray"]] = {} + + # Register default modalities (subclass can override) + self._register_default_modalities() + + def _register_default_modalities(self) -> None: + """Override in subclass to register default modality handlers.""" + pass + + def register_modality( + self, + modality: str, + handler: Callable[[List[Any]], "np.ndarray"], + ) -> None: + """ + Register a handler for a modality. + + Args: + modality: Name of modality ("text", "image", "video", etc.) + handler: Function that takes list of inputs and returns embeddings. + """ + self._modality_handlers[modality] = handler + + @property + def supported_modalities(self) -> List[str]: + """Return list of supported modalities.""" + return list(self._modality_handlers.keys()) + + def get_embedding_dim(self, modality: str) -> Optional[int]: + """ + Return the embedding dimension for a given modality. + + Subclasses should override this to return the actual dimension + so that auto-generated FeatureView schemas use the correct vector_length. + + Args: + modality: The modality to query (e.g. "text", "image"). + + Returns: + The embedding dimension, or None if unknown. + """ + return None + + @abstractmethod + def embed(self, inputs: List[Any], modality: str) -> "np.ndarray": + """ + Generate embeddings for inputs of a given modality. + + Args: + inputs: List of inputs. + modality: Type of content ("text", "image", "video", etc.) + + Returns: + numpy array of shape (len(inputs), embedding_dim) + """ + pass + + def embed_dataframe( + self, + df: pd.DataFrame, + column_mapping: dict[str, tuple[str, str]], + ) -> pd.DataFrame: + """ + Add embeddings for multiple columns with modality routing. + + Args: + df: Input DataFrame. + column_mapping: Dict mapping source_column -> (modality, output_column). + Example: { + "text": ("text", "text_embedding"), + "image_path": ("image", "image_embedding"), + "video_path": ("video", "video_embedding"), + } + """ + df = df.copy() + + for source_column, (modality, output_column) in column_mapping.items(): + inputs = df[source_column].tolist() + embeddings = self.embed(inputs, modality) + df[output_column] = pd.Series( + [emb.tolist() for emb in embeddings], dtype=object, index=df.index + ) + + return df + + +class MultiModalEmbedder(BaseEmbedder): + """ + Multi-modal embedder with built-in support for common modalities. + + Supports: text, image, video (extensible) + """ + + def __init__( + self, + text_model: str = "all-MiniLM-L6-v2", + image_model: str = "openai/clip-vit-base-patch32", + config: Optional[EmbeddingConfig] = None, + ): + self.text_model_name = text_model + self.image_model_name = image_model + + # Lazy-loaded models + self._text_model = None + self._image_model = None + self._image_processor = None + + super().__init__(config) + + def _register_default_modalities(self) -> None: + """Register built-in modality handlers.""" + self.register_modality("text", self._embed_text) + self.register_modality("image", self._embed_image) + # Future: add more as needed + # self.register_modality("video", self._embed_video) + # self.register_modality("audio", self._embed_audio) + + def embed(self, inputs: List[Any], modality: str) -> "np.ndarray": + """Route to appropriate handler based on modality.""" + if modality not in self._modality_handlers: + raise ValueError( + f"Unsupported modality: '{modality}'. " + f"Supported: {self.supported_modalities}" + ) + + handler = self._modality_handlers[modality] + return handler(inputs) + + def get_embedding_dim(self, modality: str) -> Optional[int]: + """ + Return the embedding dimension for a given modality. + + For "text", this queries the SentenceTransformer model's dimension + (which triggers lazy model loading). + + Args: + modality: The modality to query (e.g. "text", "image"). + + Returns: + The embedding dimension, or None if unknown. + """ + if modality == "text": + return self.text_model.get_sentence_embedding_dimension() + elif modality == "image": + return self.image_model.config.vision_config.hidden_size + return None + + # Text Embedding + @property + def text_model(self): + if self._text_model is None: + from sentence_transformers import SentenceTransformer + + self._text_model = SentenceTransformer(self.text_model_name) + return self._text_model + + def _embed_text(self, inputs: List[str]) -> "np.ndarray": + return self.text_model.encode( + inputs, + batch_size=self.config.batch_size, + show_progress_bar=self.config.show_progress, + ) + + # Image Embedding + @property + def image_model(self): + if self._image_model is None: + from transformers import CLIPModel + + self._image_model = CLIPModel.from_pretrained(self.image_model_name) + return self._image_model + + @property + def image_processor(self): + if self._image_processor is None: + from transformers import CLIPProcessor + + self._image_processor = CLIPProcessor.from_pretrained(self.image_model_name) + return self._image_processor + + def _embed_image(self, inputs: List[Any]) -> "np.ndarray": + from pathlib import Path + + import numpy as np + from PIL import Image + + all_embeddings: List["np.ndarray"] = [] + batch_size = self.config.batch_size + + for start in range(0, len(inputs), batch_size): + batch = inputs[start : start + batch_size] + images = [] + opened: List[Image.Image] = [] + try: + for inp in batch: + if isinstance( + inp, (str, Path) + ): # If the input string path is too large that It gives error and we could not open the image. + img = Image.open(inp) + opened.append(img) + images.append(img) + else: + images.append(inp) + + processed = self.image_processor(images=images, return_tensors="pt") + finally: + for opened_img in opened: + opened_img.close() + + embeddings = self.image_model.get_image_features(**processed) + embeddings = embeddings / embeddings.norm(p=2, dim=-1, keepdim=True) + all_embeddings.append(embeddings.detach().numpy()) + + return np.concatenate(all_embeddings, axis=0) diff --git a/sdk/python/feast/entity.py b/sdk/python/feast/entity.py index 7f4eadc6352..bcfa170a96d 100644 --- a/sdk/python/feast/entity.py +++ b/sdk/python/feast/entity.py @@ -203,7 +203,7 @@ def to_proto(self) -> EntityProto: spec = EntitySpecProto( name=self.name, - value_type=self.value_type.value, + value_type=self.value_type.value, # type: ignore[arg-type] join_key=self.join_key, description=self.description, tags=self.tags, diff --git a/sdk/python/feast/errors.py b/sdk/python/feast/errors.py index 53895344d3b..515a6c39b11 100644 --- a/sdk/python/feast/errors.py +++ b/sdk/python/feast/errors.py @@ -128,6 +128,38 @@ def __init__(self, name, project=None): super().__init__(f"Feature view {name} does not exist") +class FeatureViewVersionNotFound(FeastObjectNotFoundException): + def __init__(self, name, version, project=None): + if project: + super().__init__( + f"Version {version} of feature view {name} does not exist in project {project}" + ) + else: + super().__init__(f"Version {version} of feature view {name} does not exist") + + +class VersionedOnlineReadNotSupported(FeastError): + def __init__(self, store_name: str, version: int): + super().__init__( + f"Versioned feature reads (@v{version}) are not yet supported by {store_name}. " + f"Currently only SQLite, PostgreSQL, MySQL, FAISS, Redis, and DynamoDB support version-qualified feature references. " + ) + + +class FeatureViewPinConflict(FeastError): + def __init__(self, name, version): + super().__init__( + f"Cannot pin feature view '{name}' to {version} because the definition has also been modified. " + f"To pin to an older version, only change the 'version' parameter — do not modify other fields. " + f"To apply a new definition, use version='latest' or omit the version parameter." + ) + + +class ConcurrentVersionConflict(FeastError): + def __init__(self, msg: str): + super().__init__(msg) + + class OnDemandFeatureViewNotFoundException(FeastObjectNotFoundException): def __init__(self, name, project=None): if project: diff --git a/sdk/python/feast/feast_object.py b/sdk/python/feast/feast_object.py index 63fa1e913b4..c092b25d7be 100644 --- a/sdk/python/feast/feast_object.py +++ b/sdk/python/feast/feast_object.py @@ -8,12 +8,14 @@ from .entity import Entity from .feature_service import FeatureService from .feature_view import FeatureView +from .labeling.label_view import LabelView from .on_demand_feature_view import OnDemandFeatureView from .permissions.permission import Permission from .protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto from .protos.feast.core.Entity_pb2 import EntitySpecV2 from .protos.feast.core.FeatureService_pb2 import FeatureServiceSpec from .protos.feast.core.FeatureView_pb2 import FeatureViewSpec +from .protos.feast.core.LabelView_pb2 import LabelViewSpec from .protos.feast.core.OnDemandFeatureView_pb2 import OnDemandFeatureViewSpec from .protos.feast.core.Permission_pb2 import PermissionSpec as PermissionSpec from .protos.feast.core.SavedDataset_pb2 import SavedDatasetSpec @@ -31,6 +33,7 @@ OnDemandFeatureView, BatchFeatureView, StreamFeatureView, + LabelView, Entity, FeatureService, DataSource, @@ -44,6 +47,7 @@ FeatureViewSpec, OnDemandFeatureViewSpec, StreamFeatureViewSpec, + LabelViewSpec, EntitySpecV2, FeatureServiceSpec, DataSourceProto, @@ -58,4 +62,5 @@ OnDemandFeatureView, BatchFeatureView, StreamFeatureView, + LabelView, ] diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py index c0ba3051df0..bba91130db3 100644 --- a/sdk/python/feast/feature_server.py +++ b/sdk/python/feast/feature_server.py @@ -38,10 +38,9 @@ ) from fastapi.concurrency import run_in_threadpool from fastapi.logger import logger -from fastapi.responses import JSONResponse, ORJSONResponse +from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles -from google.protobuf.json_format import MessageToDict -from pydantic import BaseModel +from pydantic import BaseModel, field_validator import feast from feast import metrics as feast_metrics @@ -52,9 +51,14 @@ FeastError, ) from feast.feast_object import FeastObject +from feast.feature_server_utils import convert_response_to_dict from feast.feature_view_utils import get_feature_view_from_feature_store from feast.permissions.action import WRITE, AuthzedAction -from feast.permissions.security_manager import assert_permissions +from feast.permissions.security_manager import ( + assert_permissions, + get_security_manager, + is_auth_necessary, +) from feast.permissions.server.rest import inject_user_details from feast.permissions.server.utils import ( ServerType, @@ -99,18 +103,46 @@ class GetOnlineFeaturesRequest(BaseModel): feature_service: Optional[str] = None features: List[str] = [] full_feature_names: bool = False + include_feature_view_version_metadata: bool = False class GetOnlineDocumentsRequest(BaseModel): feature_service: Optional[str] = None features: List[str] = [] full_feature_names: bool = False + include_feature_view_version_metadata: bool = False top_k: Optional[int] = None query: Optional[List[float]] = None query_string: Optional[str] = None api_version: Optional[int] = 1 +class FeatureVectorResponse(BaseModel): + values: List[Any] = [] + statuses: List[str] = [] + event_timestamps: List[str] = [] + + +class OnlineFeaturesMetadataResponse(BaseModel): + feature_names: List[str] = [] + + @field_validator("feature_names", mode="before") + @classmethod + def _unwrap_feature_list(cls, v: Any) -> Any: + """Accept both the proto_json-patched flat list and the raw + protobuf ``{"val": [...]}`` dict produced by ``MessageToDict`` + when the monkey-patch is absent or ineffective.""" + if isinstance(v, dict) and "val" in v: + return v["val"] + return v + + +class OnlineFeaturesResponse(BaseModel): + metadata: Optional[OnlineFeaturesMetadataResponse] = None + results: List[FeatureVectorResponse] = [] + status: Optional[bool] = None + + class ChatMessage(BaseModel): role: str content: str @@ -120,28 +152,71 @@ class ChatRequest(BaseModel): messages: List[ChatMessage] -def _resolve_feature_counts( +def _parse_feature_info( features: Union[List[str], "feast.FeatureService"], ) -> tuple: - """Return (feature_count, feature_view_count) from the resolved features. + """Return ``(feature_view_names, feature_count)`` from resolved features. ``features`` is either a list of ``"feature_view:feature"`` strings or a ``FeatureService`` with ``feature_view_projections``. + + Returns: + (fv_names, feat_count) where fv_names is a list of unique feature + view name strings and feat_count is the total number of features. """ from feast.feature_service import FeatureService + from feast.utils import _parse_feature_ref if isinstance(features, FeatureService): projections = features.feature_view_projections - fv_count = len(projections) + fv_names = [p.name for p in projections] feat_count = sum(len(p.features) for p in projections) elif isinstance(features, list): feat_count = len(features) - fv_names = {ref.split(":")[0] for ref in features if ":" in ref} - fv_count = len(fv_names) + fv_names = list({_parse_feature_ref(ref)[0] for ref in features if ":" in ref}) else: + fv_names = [] feat_count = 0 - fv_count = 0 - return str(feat_count), str(fv_count) + return fv_names, feat_count + + +def _resolve_feature_counts( + features: Union[List[str], "feast.FeatureService"], +) -> tuple: + """Return ``(feature_count_str, feature_view_count_str)`` for Prometheus labels.""" + fv_names, feat_count = _parse_feature_info(features) + return str(feat_count), str(len(fv_names)) + + +def _emit_online_audit( + request: GetOnlineFeaturesRequest, + features: Union[List[str], "feast.FeatureService"], + entity_count: int, + status: str, + latency_ms: float, +): + """Best-effort audit log emission for online feature requests.""" + try: + from feast.permissions.security_manager import get_security_manager + + requestor_id = "anonymous" + sm = get_security_manager() + if sm and sm.current_user: + requestor_id = sm.current_user.username or "anonymous" + + fv_names, feat_count = _parse_feature_info(features) + + feast_metrics.emit_online_audit_log( + requestor_id=requestor_id, + entity_keys=list(request.entities.keys()), + entity_count=entity_count, + feature_views=fv_names, + feature_count=feat_count, + status=status, + latency_ms=latency_ms, + ) + except Exception: + logger.warning("Failed to emit online audit log", exc_info=True) async def _get_features( @@ -156,7 +231,7 @@ async def _get_features( resource=feature_service, actions=[AuthzedAction.READ_ONLINE] ) features = feature_service # type: ignore - else: + elif is_auth_necessary(get_security_manager()): all_feature_views, all_on_demand_feature_views = await run_in_threadpool( utils._get_feature_views_to_use, store.registry, @@ -174,6 +249,8 @@ async def _get_features( resource=od_feature_view, actions=[AuthzedAction.READ_ONLINE] ) features = request.features # type: ignore + else: + features = request.features # type: ignore return features @@ -260,7 +337,6 @@ def get_app( """ proto_json.patch() # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down - registry_proto = None shutting_down = False active_timer: Optional[threading.Timer] = None # --- Offline write batching config and batcher --- @@ -310,8 +386,6 @@ def async_refresh(): return store.refresh_registry() - nonlocal registry_proto - registry_proto = store.registry.proto() if registry_ttl_sec: nonlocal active_timer @@ -338,8 +412,9 @@ async def lifespan(app: FastAPI): @app.post( "/get-online-features", dependencies=[Depends(inject_user_details)], + response_model=OnlineFeaturesResponse, ) - async def get_online_features(request: GetOnlineFeaturesRequest) -> ORJSONResponse: + async def get_online_features(request: GetOnlineFeaturesRequest) -> Any: with feast_metrics.track_request_latency( "/get-online-features", ) as metrics_ctx: @@ -355,30 +430,40 @@ async def get_online_features(request: GetOnlineFeaturesRequest) -> ORJSONRespon features=features, entity_rows=request.entities, full_feature_names=request.full_feature_names, + include_feature_view_version_metadata=request.include_feature_view_version_metadata, ) - if store._get_provider().async_supported.online.read: - response = await store.get_online_features_async(**read_params) # type: ignore - else: - response = await run_in_threadpool( - lambda: store.get_online_features(**read_params) # type: ignore + audit_start_ms = time.monotonic() * 1000 + audit_status = "success" + try: + if store._get_provider().async_supported.online.read: + response = await store.get_online_features_async(**read_params) # type: ignore + else: + response = await run_in_threadpool( + lambda: store.get_online_features(**read_params) # type: ignore + ) + except Exception: + audit_status = "error" + raise + finally: + audit_latency_ms = time.monotonic() * 1000 - audit_start_ms + _emit_online_audit( + request, features, entity_count, audit_status, audit_latency_ms ) response_dict = await run_in_threadpool( - MessageToDict, - response.proto, - preserving_proto_field_name=True, - float_precision=18, + convert_response_to_dict, response.proto ) - return ORJSONResponse(content=response_dict) + return JSONResponse(content=response_dict) @app.post( "/retrieve-online-documents", dependencies=[Depends(inject_user_details)], + response_model=OnlineFeaturesResponse, ) async def retrieve_online_documents( request: GetOnlineDocumentsRequest, - ) -> ORJSONResponse: + ) -> Any: with feast_metrics.track_request_latency("/retrieve-online-documents"): logger.warning( "This endpoint is in alpha and will be moved to /get-online-features when stable." @@ -386,12 +471,17 @@ async def retrieve_online_documents( features = await _get_features(request, store) read_params = dict( - features=features, query=request.query, top_k=request.top_k + features=features, + query=request.query, + top_k=request.top_k, ) if request.api_version == 2 and request.query_string is not None: read_params["query_string"] = request.query_string if request.api_version == 2: + read_params["include_feature_view_version_metadata"] = ( + request.include_feature_view_version_metadata + ) response = await run_in_threadpool( lambda: store.retrieve_online_documents_v2(**read_params) # type: ignore ) @@ -401,12 +491,9 @@ async def retrieve_online_documents( ) response_dict = await run_in_threadpool( - MessageToDict, - response.proto, - preserving_proto_field_name=True, - float_precision=18, + convert_response_to_dict, response.proto ) - return ORJSONResponse(content=response_dict) + return JSONResponse(content=response_dict) @app.post("/push", dependencies=[Depends(inject_user_details)]) async def push(request: PushFeaturesRequest) -> Response: @@ -533,11 +620,11 @@ async def write_to_online_store(request: WriteToFeatureStoreRequest) -> None: @app.get("/health") async def health(): - return ( - Response(status_code=status.HTTP_200_OK) - if registry_proto - else Response(status_code=status.HTTP_503_SERVICE_UNAVAILABLE) - ) + try: + store.registry.list_projects(allow_cache=True) + return Response(status_code=status.HTTP_200_OK) + except Exception: + return Response(status_code=status.HTTP_503_SERVICE_UNAVAILABLE) @app.post("/chat") async def chat(request: ChatRequest): @@ -557,12 +644,22 @@ async def chat_ui(): @app.post("/materialize", dependencies=[Depends(inject_user_details)]) async def materialize(request: MaterializeRequest) -> None: with feast_metrics.track_request_latency("/materialize"): - for feature_view in request.feature_views or []: - resource = await _get_feast_object(feature_view, True) - assert_permissions( - resource=resource, - actions=[AuthzedAction.WRITE_ONLINE], + if request.feature_views: + for feature_view in request.feature_views: + resource = await _get_feast_object(feature_view, True) + assert_permissions( + resource=resource, + actions=[AuthzedAction.WRITE_ONLINE], + ) + else: + feature_views_to_materialize = store._get_feature_views_to_materialize( + None ) + for fv in feature_views_to_materialize: + assert_permissions( + resource=fv, + actions=[AuthzedAction.WRITE_ONLINE], + ) if request.disable_event_timestamp: now = datetime.now() @@ -588,12 +685,22 @@ async def materialize(request: MaterializeRequest) -> None: @app.post("/materialize-incremental", dependencies=[Depends(inject_user_details)]) async def materialize_incremental(request: MaterializeIncrementalRequest) -> None: with feast_metrics.track_request_latency("/materialize-incremental"): - for feature_view in request.feature_views or []: - resource = await _get_feast_object(feature_view, True) - assert_permissions( - resource=resource, - actions=[AuthzedAction.WRITE_ONLINE], + if request.feature_views: + for feature_view in request.feature_views: + resource = await _get_feast_object(feature_view, True) + assert_permissions( + resource=resource, + actions=[AuthzedAction.WRITE_ONLINE], + ) + else: + feature_views_to_materialize = store._get_feature_views_to_materialize( + None ) + for fv in feature_views_to_materialize: + assert_permissions( + resource=fv, + actions=[AuthzedAction.WRITE_ONLINE], + ) await run_in_threadpool( store.materialize_incremental, utils.make_tzaware(parser.parse(request.end_ts)), @@ -694,6 +801,7 @@ async def websocket_endpoint(websocket: WebSocket): def _add_mcp_support_if_enabled(app, store: "feast.FeatureStore"): """Add MCP support to the FastAPI app if enabled in configuration.""" + mcp_transport_not_supported_error = None try: # Check if MCP is enabled in feature server config if ( @@ -702,7 +810,16 @@ def _add_mcp_support_if_enabled(app, store: "feast.FeatureStore"): and store.config.feature_server.type == "mcp" and getattr(store.config.feature_server, "mcp_enabled", False) ): - from feast.infra.mcp_servers.mcp_server import add_mcp_support_to_app + try: + from feast.infra.mcp_servers.mcp_server import ( + McpTransportNotSupportedError, + add_mcp_support_to_app, + ) + + mcp_transport_not_supported_error = McpTransportNotSupportedError + except ImportError as e: + logger.error(f"Error checking/adding MCP support: {e}") + return mcp_server = add_mcp_support_to_app(app, store, store.config.feature_server) @@ -713,6 +830,10 @@ def _add_mcp_support_if_enabled(app, store: "feast.FeatureStore"): else: logger.debug("MCP support is not enabled in feature server configuration") except Exception as e: + if mcp_transport_not_supported_error and isinstance( + e, mcp_transport_not_supported_error + ): + raise logger.error(f"Error checking/adding MCP support: {e}") # Don't fail the entire server if MCP fails to initialize diff --git a/sdk/python/feast/feature_server_utils.py b/sdk/python/feast/feature_server_utils.py new file mode 100644 index 00000000000..946fae8a9b4 --- /dev/null +++ b/sdk/python/feast/feature_server_utils.py @@ -0,0 +1,160 @@ +"""Fast serialization utilities for Feature Server responses. + +Matches the output format of MessageToDict with proto_json.patch() applied. +Values are serialized as native Python types (not wrapped dicts). +""" + +import base64 +import logging +from datetime import datetime, timezone +from typing import Any, Dict, Optional + +from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse +from feast.protos.feast.types.Value_pb2 import Value + +logger = logging.getLogger(__name__) + +# FieldStatus enum mapping (protos/feast/serving/ServingService.proto) +_STATUS_NAMES: Dict[int, str] = { + 0: "INVALID", + 1: "PRESENT", + 2: "NULL_VALUE", + 3: "NOT_FOUND", + 4: "OUTSIDE_MAX_AGE", +} + + +def convert_response_to_dict(response: GetOnlineFeaturesResponse) -> Dict[str, Any]: + """Convert GetOnlineFeaturesResponse to a JSON-serializable dict. + + Matches the structure produced by MessageToDict(proto, preserving_proto_field_name=True) + with proto_json.patch() applied, with one intentional difference: + + - double_val fields are returned as Python float objects (json.dumps uses Python 3.1+ + shortest round-trip form, ~15-17 sig digits) rather than 18 fixed significant digits + (float_precision=18). Values are numerically identical; only the JSON string length + may differ. This is safe for all ML feature types and avoids unnecessary precision + overhead. + """ + result: Dict[str, Any] = { + "results": [ + { + "values": [_value_to_native(v) for v in feature_vector.values], + "statuses": [ + _STATUS_NAMES.get(s, "INVALID") for s in feature_vector.statuses + ], + **( + { + "event_timestamps": [ + _timestamp_to_str(ts) + for ts in feature_vector.event_timestamps + ] + } + if feature_vector.event_timestamps + else {} + ), + } + for feature_vector in response.results + ] + } + + if response.HasField("metadata"): + result["metadata"] = _metadata_to_dict(response.metadata) + + if response.status: + result["status"] = response.status + + return result + + +def _value_to_native(v: Value) -> Optional[Any]: + """Convert a Value proto to a JSON-serializable Python type. + + bytes_val and bytes_list_val are base64-encoded (RFC 4648) so that + JSONResponse can serialize them without TypeError. This matches standard + protobuf JSON encoding for bytes fields and is safe for all HTTP clients. + """ + which = v.WhichOneof("val") + if which is None or which == "null_val": + return None + # bytes must be base64-encoded for JSON serialization + elif which == "bytes_val": + return base64.b64encode(v.bytes_val).decode("ascii") + # RepeatedValue — nested Values that must be recursively converted + elif which in ("list_val", "set_val"): + return [_value_to_native(nested) for nested in getattr(v, which).val] + # Map — recursively convert nested Values + elif which in ("map_val", "struct_val"): + return {k: _value_to_native(vv) for k, vv in getattr(v, which).val.items()} + # MapList — list of Map + elif which in ("map_list_val", "struct_list_val"): + return [ + {k: _value_to_native(vv) for k, vv in m.val.items()} + for m in getattr(v, which).val + ] + # scalar_map_val has non-string keys; full conversion requires extra work and + # this type is not returned by standard get_online_features paths today. + elif which == "scalar_map_val": + logger.warning( + "scalar_map_val is not yet supported by convert_response_to_dict; value will be None" + ) + return None + # zoned_timestamp_val is a ZonedTimestamp message; serialize as an ISO 8601 + # string in its stored zone so JSONResponse can encode it (the raw message + # is not JSON-serializable). + elif which == "zoned_timestamp_val": + return _zoned_timestamp_to_str(v.zoned_timestamp_val) + # bytes_list_val / bytes_set_val — base64-encode each element + elif which in ("bytes_list_val", "bytes_set_val"): + return [base64.b64encode(b).decode("ascii") for b in getattr(v, which).val] + # All other list/set types have scalar .val fields + elif "_list_" in which or "_set_" in which: + return list(getattr(v, which).val) + else: + return getattr(v, which) + + +def _zoned_timestamp_to_str(zoned) -> Optional[str]: + """Convert a ZonedTimestamp proto to an ISO 8601 string in its stored zone. + + A null instant (NaT sentinel) returns None. The zone is resolved via the + same logic used on the read path so IANA names and fixed offsets round-trip. + """ + from feast.type_map import NULL_TIMESTAMP_INT_VALUE, _zone_from_name + + if zoned.unix_timestamp == NULL_TIMESTAMP_INT_VALUE: + return None + tz = _zone_from_name(zoned.zone) + return datetime.fromtimestamp(zoned.unix_timestamp, tz=tz).isoformat() + + +def _timestamp_to_str(ts) -> str: + """Convert protobuf Timestamp to RFC 3339 format with Z suffix. + + Uses adaptive precision to match MessageToDict output: + - No fractional seconds when nanos == 0 + - 3 digits (milliseconds) when nanos % 1_000_000 == 0 + - 6 digits (microseconds) when nanos % 1_000 == 0 + - 9 digits (nanoseconds) otherwise + """ + if ts.seconds == 0 and ts.nanos == 0: + return "1970-01-01T00:00:00Z" + dt = datetime.fromtimestamp(ts.seconds, tz=timezone.utc) + base = dt.strftime("%Y-%m-%dT%H:%M:%S") + nanos = ts.nanos + if nanos == 0: + return base + "Z" + elif nanos % 1_000_000 == 0: + return base + ".%03dZ" % (nanos // 1_000_000) + elif nanos % 1_000 == 0: + return base + ".%06dZ" % (nanos // 1_000) + else: + return base + ".%09dZ" % nanos + + +def _metadata_to_dict(metadata) -> Dict[str, Any]: + """Convert FeatureResponseMeta to dict (matches proto_json.patch() format).""" + result: Dict[str, Any] = {} + if metadata.HasField("feature_names"): + result["feature_names"] = list(metadata.feature_names.val) + return result diff --git a/sdk/python/feast/feature_service.py b/sdk/python/feast/feature_service.py index 5c062f15c67..983ead2c416 100644 --- a/sdk/python/feast/feature_service.py +++ b/sdk/python/feast/feature_service.py @@ -9,6 +9,7 @@ from feast.feature_logging import LoggingConfig from feast.feature_view import FeatureView from feast.feature_view_projection import FeatureViewProjection +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.protos.feast.core.FeatureService_pb2 import ( FeatureService as FeatureServiceProto, @@ -40,7 +41,7 @@ class FeatureService: """ name: str - _features: List[Union[FeatureView, OnDemandFeatureView]] + _features: List[Union[FeatureView, OnDemandFeatureView, LabelView]] feature_view_projections: List[FeatureViewProjection] description: str tags: Dict[str, str] @@ -49,27 +50,32 @@ class FeatureService: last_updated_timestamp: Optional[datetime] = None logging_config: Optional[LoggingConfig] = None + precompute_online: bool = False + def __init__( self, *, name: str, - features: List[Union[FeatureView, OnDemandFeatureView]], + features: List[Union[FeatureView, OnDemandFeatureView, LabelView]], tags: Optional[Dict[str, str]] = None, description: str = "", owner: str = "", logging_config: Optional[LoggingConfig] = None, + precompute_online: bool = False, ): """ Creates a FeatureService object. Args: name: The unique name of the feature service. - feature_view_projections: A list containing feature views and feature view + features: A list containing feature views and feature view projections, representing the features in the feature service. description (optional): A human-readable description. tags (optional): A dictionary of key-value pairs to store arbitrary metadata. owner (optional): The owner of the feature view, typically the email of the primary maintainer. + precompute_online (optional): When True, a pre-computed feature vector is + maintained per entity for single-read online retrieval. """ self.name = name self._features = features @@ -80,6 +86,7 @@ def __init__( self.created_timestamp = None self.last_updated_timestamp = None self.logging_config = logging_config + self.precompute_online = precompute_online for feature_grouping in self._features: if isinstance(feature_grouping, BaseFeatureView): self.feature_view_projections.append(feature_grouping.projection) @@ -175,6 +182,7 @@ def __eq__(self, other): or self.description != other.description or self.tags != other.tags or self.owner != other.owner + or self.precompute_online != other.precompute_online ): return False @@ -202,6 +210,7 @@ def from_proto(cls, feature_service_proto: FeatureServiceProto): logging_config=LoggingConfig.from_proto( feature_service_proto.spec.logging_config ), + precompute_online=feature_service_proto.spec.precompute_online, ) fs.feature_view_projections.extend( [ @@ -245,9 +254,20 @@ def to_proto(self) -> FeatureServiceProto: logging_config=self.logging_config.to_proto() if self.logging_config else None, + precompute_online=self.precompute_online, ) return FeatureServiceProto(spec=spec, meta=meta) def validate(self): - pass + if not self.precompute_online: + return + + for fv in self._features: + if isinstance(fv, OnDemandFeatureView) and not fv.write_to_online_store: + raise ValueError( + f"FeatureService '{self.name}' has precompute_online=True but " + f"contains OnDemandFeatureView '{fv.name}' with " + f"write_to_online_store=False. On-demand transforms computed at " + f"serve time cannot be pre-computed." + ) diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py index fe0e7967345..3dcd4189d3c 100644 --- a/sdk/python/feast/feature_store.py +++ b/sdk/python/feast/feature_store.py @@ -14,6 +14,7 @@ import asyncio import copy import itertools +import logging import os import time import warnings @@ -22,7 +23,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Dict, Iterable, List, @@ -68,7 +68,12 @@ ) from feast.feast_object import FeastObject from feast.feature_service import FeatureService -from feast.feature_view import DUMMY_ENTITY, DUMMY_ENTITY_NAME, FeatureView +from feast.feature_view import ( + DUMMY_ENTITY, + DUMMY_ENTITY_NAME, + FeatureView, + FeatureViewState, +) from feast.inference import ( update_data_sources_with_inferred_event_timestamp_col, update_feature_views_with_inferred_features_and_entities, @@ -81,6 +86,7 @@ from feast.infra.registry.base_registry import BaseRegistry from feast.infra.registry.registry import Registry from feast.infra.registry.sql import SqlRegistry +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.online_response import OnlineResponse from feast.permissions.permission import Permission @@ -100,10 +106,18 @@ from feast.transformation.pandas_transformation import PandasTransformation from feast.transformation.python_transformation import PythonTransformation from feast.utils import _get_feature_view_vector_field_metadata, _utc_now +from feast.version_utils import parse_version + +try: + from datetime import timezone as _timezone +except ImportError: + _timezone = None # type: ignore[assignment,misc] _track_materialization = None # Lazy-loaded on first materialization call _track_materialization_loaded = False +_logger = logging.getLogger(__name__) + def _get_track_materialization(): """Lazy-import feast.metrics only when materialization tracking is needed. @@ -126,6 +140,8 @@ def _get_track_materialization(): warnings.simplefilter("once", DeprecationWarning) +_UNSET = object() + class FeatureStore: """ @@ -193,6 +209,132 @@ def __init__( # Initialize feature service cache for performance optimization self._feature_service_cache = {} + # Cache for _resolve_feature_service_name lookups + self._fs_name_cache: Dict[frozenset, Optional[str]] = {} + self._fs_name_index: Dict[frozenset, str] = {} + self._fs_name_index_ts: float = -self._FS_NAME_INDEX_TTL_SECONDS + + self._mlflow_client: Any = _UNSET + + def _init_mlflow(self) -> Optional[Any]: + """Bootstrap MLflow integration on first access. + + Checks the config, imports the module, and creates the integration + client. Returns the client or ``None`` if MLflow is disabled or + unavailable. + """ + try: + mlflow_cfg = getattr(self.config, "mlflow", None) + if mlflow_cfg is None or not mlflow_cfg.enabled: + return None + from feast.mlflow import _register_store + + _register_store(self) + + from feast.mlflow_integration.client import FeastMlflowClient + + return FeastMlflowClient(self) + except ImportError: + return None + except Exception as e: + warnings.warn(f"Failed to configure MLflow tracking: {e}") + return None + + @property + def mlflow(self) -> Any: + """Access the Feast–MLflow integration client. + + Lazily initializes on first access. Returns ``None`` when MLflow + integration is not enabled, allowing callers to guard with + ``if store.mlflow:``. + """ + if self._mlflow_client is _UNSET: + self._mlflow_client = self._init_mlflow() + return self._mlflow_client + + @staticmethod + def _count_entities(entity_rows: Any) -> int: + """Count entities from either a list or columnar mapping.""" + if isinstance(entity_rows, list): + return len(entity_rows) + if isinstance(entity_rows, Mapping): + try: + _first_col = next(iter(entity_rows.values())) + if isinstance(_first_col, RepeatedValue): + return len(_first_col.val) + return len(_first_col) + except Exception: + return 0 + return 0 + + _FS_NAME_INDEX_TTL_SECONDS = 300 + + def _rebuild_fs_name_index(self) -> None: + """Rebuild the {frozenset(refs) → service_name} index from the registry.""" + index: Dict[frozenset, str] = {} + for fs in self.registry.list_feature_services(self.project, allow_cache=True): + fs_refs = frozenset( + f"{p.name_to_use()}:{f.name}" + for p in fs.feature_view_projections + for f in p.features + ) + index[fs_refs] = fs.name + self._fs_name_index = index + self._fs_name_cache = {} + self._fs_name_index_ts = time.monotonic() + + def _resolve_feature_service_name(self, feature_refs: List[str]) -> Optional[str]: + """Find the best-matching feature service for the given feature refs. + + Resolution: exact match wins immediately; otherwise the smallest + superset (fewest extra features) is returned. The full index is + rebuilt from the registry every _FS_NAME_INDEX_TTL_SECONDS and + per-query results are cached for O(1) repeated lookups. + """ + try: + now = time.monotonic() + if (now - self._fs_name_index_ts) >= self._FS_NAME_INDEX_TTL_SECONDS: + self._rebuild_fs_name_index() + + ref_key = frozenset(feature_refs) + if ref_key in self._fs_name_cache: + return self._fs_name_cache[ref_key] + + if ref_key in self._fs_name_index: + self._fs_name_cache[ref_key] = self._fs_name_index[ref_key] + return self._fs_name_index[ref_key] + + best_match = None + best_extra = float("inf") + for fs_refs, fs_name in self._fs_name_index.items(): + if ref_key.issubset(fs_refs): + extra = len(fs_refs) - len(ref_key) + if extra < best_extra: + best_match = fs_name + best_extra = extra + + self._fs_name_cache[ref_key] = best_match + return best_match + except Exception as e: + _logger.debug("Failed to resolve feature service name: %s", e) + return None + + def _log_entity_df_metadata(self, entity_df, start_date=None, end_date=None): + """Log lightweight entity_df metadata to MLflow.""" + try: + if self.mlflow is not None: + self.mlflow.log_entity_df_metadata(entity_df, start_date, end_date) + except Exception as e: + _logger.debug("Failed to log entity_df metadata to MLflow: %s", e) + + def _log_entity_df_artifact(self, entity_df): + """Upload entity DataFrame as a parquet artifact to MLflow.""" + try: + if self.mlflow is not None: + self.mlflow.log_entity_df_artifact(entity_df) + except Exception as e: + _logger.debug("Failed to log entity_df artifact to MLflow: %s", e) + def _init_openlineage_emitter(self) -> Optional[Any]: """Initialize OpenLineage emitter if configured and enabled.""" try: @@ -294,6 +436,9 @@ def _clear_feature_service_cache(self): self._feature_service_cache.clear() if hasattr(self.registry, "_feature_service_cache"): getattr(self.registry, "_feature_service_cache").clear() + self._fs_name_cache.clear() + self._fs_name_index.clear() + self._fs_name_index_ts = -self._FS_NAME_INDEX_TTL_SECONDS def refresh_registry(self): """Fetches and caches a copy of the feature registry in memory. @@ -484,6 +629,43 @@ def list_stream_feature_views( """ return self._list_stream_feature_views(allow_cache, tags=tags) + def list_label_views( + self, allow_cache: bool = False, tags: Optional[dict[str, str]] = None + ) -> List[LabelView]: + """ + Retrieves the list of label views from the registry. + + Args: + allow_cache: Whether to allow returning label views from a cached registry. + tags: Filter by tags. + + Returns: + A list of label views. + """ + return self.registry.list_label_views( + self.project, allow_cache=allow_cache, tags=tags + ) + + def get_label_view( + self, name: str, allow_registry_cache: bool = False + ) -> LabelView: + """ + Retrieves a label view by name. + + Args: + name: Name of the label view. + allow_registry_cache: Whether to allow returning the label view from a cached registry. + + Returns: + The specified label view. + + Raises: + FeatureViewNotFoundException: The label view could not be found. + """ + return self.registry.get_label_view( + name, self.project, allow_cache=allow_registry_cache + ) + def list_data_sources( self, allow_cache: bool = False, tags: Optional[dict[str, str]] = None ) -> List[DataSource]: @@ -568,6 +750,18 @@ def _get_feature_view( feature_view.entities = [] return feature_view + def list_feature_view_versions(self, name: str) -> List[Dict[str, Any]]: + """ + List version history for a feature view. + + Args: + name: Name of feature view. + + Returns: + List of version records. + """ + return self.registry.list_feature_view_versions(name, self.project) + def get_stream_feature_view( self, name: str, allow_registry_cache: bool = False ) -> StreamFeatureView: @@ -647,6 +841,44 @@ def delete_feature_view(self, name: str): """ return self.registry.delete_feature_view(name, self.project) + def enable_feature_view(self, name: str): + """ + Enable a feature view for serving and materialization. + + Args: + name: Name of feature view. + """ + fv = self.registry.get_any_feature_view(name, self.project) + fv.enabled = True # type: ignore[attr-defined] + self.registry.apply_feature_view(fv, self.project) + + def disable_feature_view(self, name: str): + """ + Disable a feature view to prevent serving and materialization. + + Args: + name: Name of feature view. + """ + fv = self.registry.get_any_feature_view(name, self.project) + fv.enabled = False # type: ignore[attr-defined] + self.registry.apply_feature_view(fv, self.project) + + def set_feature_view_state(self, name: str, state: FeatureViewState): + """ + Set the lifecycle state of a feature view. + + Args: + name: Name of feature view. + state: Target state. + """ + fv = self.registry.get_any_feature_view(name, self.project) + if not fv.state.can_transition_to(state): # type: ignore[attr-defined] + raise ValueError( + f"Invalid state transition: {fv.state.name} -> {state.name}." # type: ignore[attr-defined] + ) + fv.state = state # type: ignore[attr-defined] + self.registry.apply_feature_view(fv, self.project) + def delete_feature_service(self, name: str): """ Deletes a feature service. @@ -671,6 +903,7 @@ def _validate_all_feature_views( views_to_update: List[FeatureView], odfvs_to_update: List[OnDemandFeatureView], sfvs_to_update: List[StreamFeatureView], + lvs_to_update: Optional[List[LabelView]] = None, ): """Validates all feature views.""" if len(odfvs_to_update) > 0 and not flags_helper.is_test(): @@ -684,6 +917,7 @@ def _validate_all_feature_views( *views_to_update, *odfvs_to_update, *sfvs_to_update, + *(lvs_to_update or []), ] ) @@ -695,8 +929,11 @@ def _make_inferences( odfvs_to_update: List[OnDemandFeatureView], sfvs_to_update: List[StreamFeatureView], feature_services_to_update: List[FeatureService], + lvs_to_update: Optional[List[LabelView]] = None, ): """Makes inferences for entities, feature views, odfvs, and feature services.""" + lvs_to_update = lvs_to_update or [] + update_data_sources_with_inferred_event_timestamp_col( data_sources_to_update, self.config ) @@ -719,6 +956,11 @@ def _make_inferences( self.config, ) + update_data_sources_with_inferred_event_timestamp_col( + [lv.batch_source for lv in lvs_to_update if lv.batch_source is not None], + self.config, + ) + # New feature views may reference previously applied entities. entities = self._list_entities() provider = self._get_provider() @@ -752,25 +994,63 @@ def _make_inferences( odfvs_to_write = [ odfv for odfv in odfvs_to_update if odfv.write_to_online_store ] - # Update to include ODFVs with write to online store fvs_to_update_map = { view.name: view - for view in [*views_to_update, *sfvs_to_update, *odfvs_to_write] + for view in [ + *views_to_update, + *sfvs_to_update, + *odfvs_to_write, + *lvs_to_update, + ] } for feature_service in feature_services_to_update: feature_service.infer_features(fvs_to_update=fvs_to_update_map) + def _validate_materialize_version( + self, + version: Optional[str], + feature_views: Optional[List[str]], + ) -> Optional[int]: + """Validate and parse the version parameter for materialize calls. + + Returns the parsed version number, or None if no version was specified. + """ + if version is None: + return None + + if not feature_views or len(feature_views) != 1: + raise ValueError( + "--version requires --views with exactly one feature view." + ) + + if not self.config.registry.enable_online_feature_view_versioning: + raise ValueError( + "Version-aware materialization requires " + "'enable_online_feature_view_versioning: true' under 'registry' " + "in feature_store.yaml." + ) + + is_latest, version_number = parse_version(version) + if is_latest: + return None + return version_number + def _get_feature_views_to_materialize( self, feature_views: Optional[List[str]], + version: Optional[int] = None, ) -> List[Union[FeatureView, OnDemandFeatureView]]: """ Returns the list of feature views that should be materialized. If no feature views are specified, all feature views will be returned. + LabelViews are excluded because they receive data via ``push()`` and + are not supported by the batch materialization providers. Args: feature_views: List of names of feature views to materialize. + version: If set, load this specific version number from the registry + instead of the active definition. Requires exactly one feature view name. Raises: FeatureViewNotFoundException: One of the specified feature views could not be found. @@ -783,35 +1063,72 @@ def _get_feature_views_to_materialize( self.registry, self.project, hide_dummy_entity=False ) feature_views_to_materialize.extend( - [fv for fv in regular_feature_views if fv.online] + [fv for fv in regular_feature_views if fv.online and fv.enabled] ) stream_feature_views_to_materialize = self._list_stream_feature_views( hide_dummy_entity=False ) feature_views_to_materialize.extend( - [sfv for sfv in stream_feature_views_to_materialize if sfv.online] + [ + sfv + for sfv in stream_feature_views_to_materialize + if sfv.online and sfv.enabled + ] ) on_demand_feature_views_to_materialize = self.list_on_demand_feature_views() feature_views_to_materialize.extend( [ odfv for odfv in on_demand_feature_views_to_materialize - if odfv.write_to_online_store + if odfv.write_to_online_store and odfv.enabled ] ) else: for name in feature_views: feature_view: Union[FeatureView, OnDemandFeatureView] - try: - feature_view = self._get_feature_view(name, hide_dummy_entity=False) - except FeatureViewNotFoundException: + if version is not None: + feature_view = cast( + Union[FeatureView, OnDemandFeatureView], + self.registry.get_feature_view_by_version( + name, self.project, version + ), + ) + else: try: - feature_view = self._get_stream_feature_view( + feature_view = self._get_feature_view( name, hide_dummy_entity=False ) except FeatureViewNotFoundException: - feature_view = self.get_on_demand_feature_view(name) + try: + feature_view = self._get_stream_feature_view( + name, hide_dummy_entity=False + ) + except FeatureViewNotFoundException: + try: + feature_view = self.get_on_demand_feature_view(name) + except FeatureViewNotFoundException: + try: + label_view = self.registry.get_label_view( + name, self.project + ) + raise ValueError( + f"LabelView {label_view.name} cannot be materialized via " + f"materialize(). Use FeatureStore.push() to write labels." + ) + except FeatureViewNotFoundException: + raise + + if isinstance(feature_view, LabelView): + raise ValueError( + f"LabelView {feature_view.name} cannot be materialized via " + f"materialize(). Use FeatureStore.push() to write labels." + ) + if hasattr(feature_view, "enabled") and not feature_view.enabled: + raise ValueError( + f"FeatureView {feature_view.name} is disabled. " + f"Enable it before materializing." + ) if hasattr(feature_view, "online") and not feature_view.online: raise ValueError( f"FeatureView {feature_view.name} is not configured to be served online." @@ -872,6 +1189,7 @@ def plan( ... feature_views=[driver_hourly_stats_view], ... on_demand_feature_views=list(), ... stream_feature_views=list(), + ... label_views=list(), ... entities=[driver], ... feature_services=list(), ... permissions=list())) # register entity and feature view @@ -882,6 +1200,7 @@ def plan( desired_repo_contents.feature_views, desired_repo_contents.on_demand_feature_views, desired_repo_contents.stream_feature_views, + desired_repo_contents.label_views, ) _validate_data_sources(desired_repo_contents.data_sources) self._make_inferences( @@ -891,6 +1210,7 @@ def plan( desired_repo_contents.on_demand_feature_views, desired_repo_contents.stream_feature_views, desired_repo_contents.feature_services, + desired_repo_contents.label_views, ) # Compute the desired difference between the current objects in the registry and @@ -920,6 +1240,7 @@ def _apply_diffs( infra_diff: InfraDiff, new_infra: Infra, progress_ctx: Optional["ApplyProgressContext"] = None, + no_promote: bool = False, ): """Applies the given diffs to the metadata store and infrastructure. @@ -943,7 +1264,11 @@ def _apply_diffs( # Registry phase apply_diff_to_registry( - self.registry, registry_diff, self.project, commit=False + self.registry, + registry_diff, + self.project, + commit=False, + no_promote=no_promote, ) if progress_ctx: @@ -962,6 +1287,35 @@ def _apply_diffs( # Emit OpenLineage events for applied objects self._emit_openlineage_apply_diffs(registry_diff) + # Emit MLflow events for applied objects (Phase 7) + self._mlflow_log_apply_diffs(registry_diff) + + def _mlflow_log_apply_diffs(self, registry_diff: RegistryDiff): + """Log apply operation to MLflow ops experiment.""" + try: + if self.mlflow is None or not self.config.mlflow.log_operations: + return + from feast.diff.property_diff import TransitionType + + objects: List[Any] = [] + transition_types: Dict[str, str] = {} + for feast_object_diff in registry_diff.feast_object_diffs: + obj = ( + feast_object_diff.new_feast_object + or feast_object_diff.current_feast_object + ) + if obj is None: + continue + tt = feast_object_diff.transition_type + if tt == TransitionType.UNCHANGED: + continue + objects.append(obj) + transition_types[feast_object_diff.name] = tt.name + if objects: + self._mlflow_log_apply(objects, transition_types=transition_types) + except Exception as e: + _logger.debug("MLflow apply logging failed: %s", e) + def _emit_openlineage_apply_diffs(self, registry_diff: RegistryDiff): """Emit OpenLineage events for objects applied via diffs.""" if self.openlineage_emitter is None: @@ -986,6 +1340,7 @@ def apply( OnDemandFeatureView, BatchFeatureView, StreamFeatureView, + LabelView, FeatureService, ValidationReference, Permission, @@ -994,6 +1349,7 @@ def apply( objects_to_delete: Optional[List[FeastObject]] = None, partial: bool = True, skip_feature_view_validation: bool = False, + no_promote: bool = False, ): """Register objects to metadata store and update related infrastructure. @@ -1060,6 +1416,7 @@ def apply( ) ] sfvs_to_update = [ob for ob in objects if isinstance(ob, StreamFeatureView)] + lvs_to_update = [ob for ob in objects if isinstance(ob, LabelView)] odfvs_to_update = [ob for ob in objects if isinstance(ob, OnDemandFeatureView)] odfvs_with_writes_to_update = [ ob @@ -1105,6 +1462,12 @@ def apply( else: pass + for lv in lvs_to_update: + if lv.source is not None: + data_sources_set_to_update.add(lv.source) + if isinstance(lv.source, PushSource) and lv.source.batch_source: + data_sources_set_to_update.add(lv.source.batch_source) + for odfv in odfvs_to_update: for v in odfv.source_request_sources.values(): data_sources_set_to_update.add(v) @@ -1120,6 +1483,7 @@ def apply( views_to_update, odfvs_to_update, sfvs_to_update, + lvs_to_update, ) self._make_inferences( data_sources_to_update, @@ -1128,6 +1492,7 @@ def apply( odfvs_to_update, sfvs_to_update, services_to_update, + lvs_to_update, ) # Add all objects to the registry and update the provider's infrastructure. @@ -1135,10 +1500,15 @@ def apply( self.registry.apply_project(project, commit=False) for ds in data_sources_to_update: self.registry.apply_data_source(ds, project=self.project, commit=False) - for view in itertools.chain(views_to_update, odfvs_to_update, sfvs_to_update): - self.registry.apply_feature_view(view, project=self.project, commit=False) + for view in itertools.chain( + views_to_update, odfvs_to_update, sfvs_to_update, lvs_to_update + ): + self.registry.apply_feature_view( + view, project=self.project, commit=False, no_promote=no_promote + ) for ent in entities_to_update: self.registry.apply_entity(ent, project=self.project, commit=False) + for feature_service in services_to_update: self.registry.apply_feature_service( feature_service, project=self.project, commit=False @@ -1187,6 +1557,9 @@ def apply( permissions_to_delete = [ ob for ob in objects_to_delete if isinstance(ob, Permission) ] + lvs_to_delete = [ + ob for ob in objects_to_delete if isinstance(ob, LabelView) + ] for data_source in data_sources_to_delete: self.registry.delete_data_source( @@ -1208,6 +1581,10 @@ def apply( self.registry.delete_feature_view( sfv.name, project=self.project, commit=False ) + for lv in lvs_to_delete: + self.registry.delete_feature_view( + lv.name, project=self.project, commit=False + ) for service in services_to_delete: self.registry.delete_feature_service( service.name, project=self.project, commit=False @@ -1222,11 +1599,18 @@ def apply( ) tables_to_delete: List[FeatureView] = ( - views_to_delete + sfvs_to_delete if not partial else [] # type: ignore + views_to_delete + sfvs_to_delete + lvs_to_delete # type: ignore + if not partial + else [] ) tables_to_keep: List[ - Union[FeatureView, StreamFeatureView, OnDemandFeatureView] - ] = views_to_update + sfvs_to_update + odfvs_with_writes_to_update # type: ignore + Union[FeatureView, StreamFeatureView, OnDemandFeatureView, LabelView] + ] = ( + views_to_update + + sfvs_to_update + + odfvs_with_writes_to_update + + lvs_to_update + ) # type: ignore self._get_provider().update_infra( project=self.project, @@ -1253,6 +1637,25 @@ def apply( # Emit OpenLineage events for applied objects self._emit_openlineage_apply(objects) + # Emit MLflow events for applied objects (Phase 7) + self._mlflow_log_apply(objects) + + def _mlflow_log_apply( + self, + objects: List[Any], + transition_types: Optional[Dict[str, str]] = None, + ): + """Log applied objects to MLflow ops experiment.""" + try: + if self.mlflow is None or not self.config.mlflow.log_operations: + return + self.mlflow.log_apply( + changed_objects=objects, + transition_types=transition_types, + ) + except Exception as e: + _logger.debug("MLflow apply logging failed: %s", e) + def _emit_openlineage_apply(self, objects: List[Any]): """Emit OpenLineage events for applied objects.""" if self.openlineage_emitter is None: @@ -1264,14 +1667,13 @@ def _emit_openlineage_apply(self, objects: List[Any]): def teardown(self): """Tears down all local and cloud resources for the feature store.""" - tables: List[FeatureView] = [] - feature_views = self.list_feature_views() - - tables.extend(feature_views) + tables: List[BaseFeatureView] = [] + tables.extend(self.list_feature_views()) + tables.extend(self.list_label_views()) entities = self.list_entities() - self._get_provider().teardown_infra(self.project, tables, entities) + self._get_provider().teardown_infra(self.project, tables, entities) # type: ignore[arg-type] self.registry.teardown() def get_historical_features( @@ -1383,6 +1785,19 @@ def get_historical_features( feature_views = list(view for view, _ in fvs) on_demand_feature_views = list(view for view, _ in odfvs) + # ODFV source FV dependencies (e.g. driver_stats:conv_rate) are resolved + # by _group_feature_refs and included in `fvs`, but not in _feature_refs. + # Offline stores use feature_refs to map which features to fetch from each + # FV, so we must include these implicit dependency refs. + _feature_refs_for_provider = list(_feature_refs) + existing_refs = set(_feature_refs) + for view, feats in fvs: + for feat in feats: + ref = f"{view.projection.name_to_use()}:{feat}" + if ref not in existing_refs: + _feature_refs_for_provider.append(ref) + existing_refs.add(ref) + # Check that the right request data is present in the entity_df if type(entity_df) == pd.DataFrame: if self.config.coerce_tz_aware: @@ -1406,10 +1821,12 @@ def get_historical_features( if end_date is not None: kwargs["end_date"] = end_date + _retrieval_start = time.monotonic() + job = provider.get_historical_features( self.config, feature_views, - _feature_refs, + _feature_refs_for_provider, entity_df, self.registry, self.project, @@ -1417,6 +1834,40 @@ def get_historical_features( **kwargs, ) + # Auto-log to MLflow if configured + try: + if self.mlflow is not None and self.config.mlflow.auto_log: + _duration = time.monotonic() - _retrieval_start + if isinstance(entity_df, pd.DataFrame): + _entity_count = len(entity_df) + elif isinstance(entity_df, str): + _entity_count = -1 + else: + _entity_count = 0 + _fs = features if isinstance(features, FeatureService) else None + _fs_name = ( + features.name + if isinstance(features, FeatureService) + else self._resolve_feature_service_name(_feature_refs) + ) + self.mlflow.log_feature_retrieval( + feature_refs=_feature_refs, + entity_count=_entity_count, + duration_seconds=_duration, + retrieval_type="historical", + feature_service=_fs, + feature_service_name=_fs_name, + ) + + self._log_entity_df_metadata( + entity_df, start_date=start_date, end_date=end_date + ) + + if self.config.mlflow.auto_log_entity_df: + self._log_entity_df_artifact(entity_df) + except Exception as e: + _logger.debug("MLflow auto-log failed for historical retrieval: %s", e) + return job def create_saved_dataset( @@ -1633,6 +2084,7 @@ def materialize_incremental( end_date: datetime, feature_views: Optional[List[str]] = None, full_feature_names: bool = False, + version: Optional[str] = None, ) -> None: """ Materialize incremental new data from the offline store into the online store. @@ -1649,6 +2101,8 @@ def materialize_incremental( materialization for the specified feature views. full_feature_names (bool): If True, feature names will be prefixed with the corresponding feature view name. + version (str): Optional version to materialize (e.g., 'v2'). Requires feature_views + with exactly one entry and enable_online_feature_view_versioning to be enabled. Raises: Exception: A feature view being materialized does not have a TTL set. @@ -1664,8 +2118,9 @@ def materialize_incremental( ... """ + parsed_version = self._validate_materialize_version(version, feature_views) feature_views_to_materialize = self._get_feature_views_to_materialize( - feature_views + feature_views, version=parsed_version ) _print_materialization_log( None, @@ -1679,6 +2134,7 @@ def materialize_incremental( feature_views_to_materialize, None, end_date ) + _mat_start = time.monotonic() try: # TODO paging large loads for feature_view in feature_views_to_materialize: @@ -1739,6 +2195,25 @@ def tqdm_builder(length): start_date = utils.make_tzaware(start_date) end_date = utils.make_tzaware(end_date) or _utc_now() + # Transition state to MATERIALIZING before starting. + # Only enforce when the state machine is active (not STATE_UNSPECIFIED). + previous_state = getattr(feature_view, "state", None) + if ( + hasattr(feature_view, "state") + and feature_view.state != FeatureViewState.STATE_UNSPECIFIED + ): + if not feature_view.state.can_transition_to( + FeatureViewState.MATERIALIZING + ): + raise ValueError( + f"FeatureView {feature_view.name} cannot transition " + f"from {feature_view.state.name} to MATERIALIZING." + ) + feature_view.state = FeatureViewState.MATERIALIZING + self.registry.apply_feature_view( + feature_view, self.project, commit=True + ) + fv_start = time.monotonic() fv_success = True try: @@ -1753,6 +2228,16 @@ def tqdm_builder(length): ) except Exception: fv_success = False + # Roll back state to previous value on failure. + if ( + hasattr(feature_view, "state") + and previous_state is not None + and previous_state != FeatureViewState.STATE_UNSPECIFIED + ): + feature_view.state = previous_state + self.registry.apply_feature_view( + feature_view, self.project, commit=True + ) raise finally: _tracker = _get_track_materialization() @@ -1762,6 +2247,7 @@ def tqdm_builder(length): fv_success, time.monotonic() - fv_start, ) + if not isinstance(feature_view, OnDemandFeatureView): self.registry.apply_materialization( feature_view, @@ -1770,10 +2256,28 @@ def tqdm_builder(length): end_date, ) + materialized_fv_names = [ + fv.name + for fv in feature_views_to_materialize + if not isinstance(fv, OnDemandFeatureView) + ] + if materialized_fv_names: + self._precompute_affected_services(materialized_fv_names) + # Emit OpenLineage COMPLETE event self._emit_openlineage_materialize_complete( ol_run_id, feature_views_to_materialize ) + + # Emit MLflow event for materialization (Phase 7) + _mat_duration = time.monotonic() - _mat_start + self._mlflow_log_materialize( + feature_views_to_materialize, + None, + end_date, + _mat_duration, + incremental=True, + ) except Exception as e: # Emit OpenLineage FAIL event self._emit_openlineage_materialize_fail(ol_run_id, str(e)) @@ -1786,6 +2290,7 @@ def materialize( feature_views: Optional[List[str]] = None, disable_event_timestamp: bool = False, full_feature_names: bool = False, + version: Optional[str] = None, ) -> None: """ Materialize data from the offline store into the online store. @@ -1802,6 +2307,8 @@ def materialize( disable_event_timestamp (bool): If True, materializes all available data using current datetime as event timestamp instead of source event timestamps full_feature_names (bool): If True, feature names will be prefixed with the corresponding feature view name. + version (str): Optional version to materialize (e.g., 'v2'). Requires feature_views + with exactly one entry and enable_online_feature_view_versioning to be enabled. Examples: Materialize all features into the online store over the interval @@ -1821,8 +2328,9 @@ def materialize( f"The given start_date {start_date} is greater than the given end_date {end_date}." ) + parsed_version = self._validate_materialize_version(version, feature_views) feature_views_to_materialize = self._get_feature_views_to_materialize( - feature_views + feature_views, version=parsed_version ) _print_materialization_log( start_date, @@ -1836,6 +2344,7 @@ def materialize( feature_views_to_materialize, start_date, end_date ) + _mat_start = time.monotonic() try: # TODO paging large loads for feature_view in feature_views_to_materialize: @@ -1862,6 +2371,25 @@ def tqdm_builder(length): start_date = utils.make_tzaware(start_date) end_date = utils.make_tzaware(end_date) + # Transition state to MATERIALIZING before starting. + # Only enforce when the state machine is active (not STATE_UNSPECIFIED). + previous_state = getattr(feature_view, "state", None) + if ( + hasattr(feature_view, "state") + and feature_view.state != FeatureViewState.STATE_UNSPECIFIED + ): + if not feature_view.state.can_transition_to( + FeatureViewState.MATERIALIZING + ): + raise ValueError( + f"FeatureView {feature_view.name} cannot transition " + f"from {feature_view.state.name} to MATERIALIZING." + ) + feature_view.state = FeatureViewState.MATERIALIZING + self.registry.apply_feature_view( + feature_view, self.project, commit=True + ) + fv_start = time.monotonic() fv_success = True try: @@ -1877,6 +2405,16 @@ def tqdm_builder(length): ) except Exception: fv_success = False + # Roll back state to previous value on failure. + if ( + hasattr(feature_view, "state") + and previous_state is not None + and previous_state != FeatureViewState.STATE_UNSPECIFIED + ): + feature_view.state = previous_state + self.registry.apply_feature_view( + feature_view, self.project, commit=True + ) raise finally: _tracker = _get_track_materialization() @@ -1894,15 +2432,56 @@ def tqdm_builder(length): end_date, ) + materialized_fv_names = [ + fv.name + for fv in feature_views_to_materialize + if not isinstance(fv, OnDemandFeatureView) + ] + if materialized_fv_names: + self._precompute_affected_services(materialized_fv_names) + # Emit OpenLineage COMPLETE event self._emit_openlineage_materialize_complete( ol_run_id, feature_views_to_materialize ) + + # Emit MLflow event for materialization (Phase 7) + _mat_duration = time.monotonic() - _mat_start + self._mlflow_log_materialize( + feature_views_to_materialize, + start_date, + end_date, + _mat_duration, + incremental=False, + ) except Exception as e: # Emit OpenLineage FAIL event self._emit_openlineage_materialize_fail(ol_run_id, str(e)) raise + def _mlflow_log_materialize( + self, + feature_views: List[Any], + start_date: Optional[datetime], + end_date: datetime, + duration_seconds: float, + incremental: bool = False, + ): + """Log materialization to MLflow ops experiment.""" + try: + if self.mlflow is None or not self.config.mlflow.log_operations: + return + fv_names = [getattr(fv, "name", str(fv)) for fv in feature_views] + self.mlflow.log_materialize( + feature_view_names=fv_names, + start_date=start_date, + end_date=end_date, + duration_seconds=duration_seconds, + incremental=incremental, + ) + except Exception as e: + _logger.debug("MLflow materialize logging failed: %s", e) + def _emit_openlineage_materialize_start( self, feature_views: List[Any], @@ -1955,13 +2534,15 @@ def _emit_openlineage_materialize_fail( def _fvs_for_push_source_or_raise( self, push_source_name: str, allow_cache: bool - ) -> set[FeatureView]: + ) -> set[BaseFeatureView]: from feast.data_source import PushSource - all_fvs = self.list_feature_views(allow_cache=allow_cache) + all_fvs: list[Union[FeatureView, StreamFeatureView]] = list( + self.list_feature_views(allow_cache=allow_cache) + ) all_fvs += self.list_stream_feature_views(allow_cache=allow_cache) - fvs_with_push_sources = { + fvs_with_push_sources: set[BaseFeatureView] = { fv for fv in all_fvs if ( @@ -1971,11 +2552,249 @@ def _fvs_for_push_source_or_raise( ) } + for lv in self.list_label_views(allow_cache=allow_cache): + if ( + lv.source is not None + and isinstance(lv.source, PushSource) + and lv.source.name == push_source_name + ): + fvs_with_push_sources.add(lv) + if not fvs_with_push_sources: raise PushSourceNotFoundException(push_source_name) return fvs_with_push_sources + def precompute_feature_service( + self, + feature_service_name: Optional[str] = None, + batch_size: int = 1000, + ) -> int: + """Pre-compute feature vectors for one or all FeatureServices. + + For each FeatureService with ``precompute_online=True`` (or matching + *feature_service_name*), reads every entity's features from the online + store via :meth:`OnlineStore.online_read` and writes a single serialized + blob per entity via :meth:`OnlineStore.write_precomputed_vector`. + + Works with **all** online store backends (Redis, DynamoDB, PostgreSQL, etc.). + + Returns the total number of entity vectors written. + """ + from feast.protos.feast.core.PrecomputedFeatureVector_pb2 import ( + FeatureViewTimestamp, + PrecomputedFeatureVector, + ) + + provider = self._get_provider() + online_store = provider.online_store + + services = self.registry.list_feature_services(self.project) + if feature_service_name: + services = [s for s in services if s.name == feature_service_name] + + total_written = 0 + for svc in services: + if not svc.precompute_online and not feature_service_name: + continue + + fv_projections = svc.feature_view_projections + feature_views = [] + for proj in fv_projections: + fv = self.registry.get_any_feature_view( + proj.name, self.project, allow_cache=True + ) + feature_views.append((fv, proj)) + + if not feature_views: + continue + + feature_names: List[str] = [] + for _fv, proj in feature_views: + fv_name = proj.name_to_use() + for f in proj.features: + feature_names.append(f"{fv_name}__{f.name}") + + # Collect all unique entity key protos from the primary feature view. + # Use online_read to discover entities that exist in the store. + primary_fv = feature_views[0][0] + + # Read entity keys by scanning the primary FV's online data. + # We use get_online_features with the full FeatureService to read + # all features for each entity in a single call, then build vectors. + # + # For stores that support native scanning (like Redis), we try the + # native scan; for others, we use the materialized entity list. + entity_key_protos: List[EntityKey] = [] + try: + from feast.infra.online_stores.redis import RedisOnlineStore + + if isinstance(online_store, RedisOnlineStore): + from feast.infra.key_encoding_utils import ( + deserialize_entity_key, + ) + from feast.infra.online_stores.helpers import _redis_key_prefix + + join_keys = ( + list(primary_fv.join_keys) + if hasattr(primary_fv, "join_keys") + else [] + ) # type: ignore[union-attr] + client = online_store._get_client( # type: ignore[attr-defined] + self.config.online_store + ) + scan_prefix = _redis_key_prefix(join_keys) + project_bytes = self.config.project.encode("utf-8") + seen_keys: set = set() + raw_keys: List[bytes] = [] + for key in client.scan_iter( + b"".join([scan_prefix, b"*", project_bytes]) + ): + if key not in seen_keys: + seen_keys.add(key) + raw_keys.append(key) + proj_len = len(project_bytes) + for rk in raw_keys: + try: + ek = deserialize_entity_key( + rk[:-proj_len], + self.config.entity_key_serialization_version, + ) + if set(ek.join_keys) == set(join_keys): + entity_key_protos.append(ek) + except (ValueError, Exception): + continue + else: + raise NotImplementedError + except (ImportError, NotImplementedError): + _logger.warning( + "Entity scanning not supported for '%s' — " + "precompute requires a store that supports entity scanning", + type(online_store).__name__, + ) + continue + + if not entity_key_protos: + continue + + for batch_start in range(0, len(entity_key_protos), batch_size): + batch_keys = entity_key_protos[batch_start : batch_start + batch_size] + + # Read features for each FV via base class online_read. + fv_data: Dict[ + str, + List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]], + ] = {} + for fv_obj, proj in feature_views: + req_features = [f.name for f in proj.features] + assert isinstance(fv_obj, FeatureView) + rows = online_store.online_read( + config=self.config, + table=fv_obj, + entity_keys=batch_keys, + requested_features=req_features, + ) + fv_data[proj.name_to_use()] = rows + + for entity_idx, entity_key in enumerate(batch_keys): + values: List[ValueProto] = [] + fv_timestamps: list = [] + + for _fv, proj in feature_views: + fv_name = proj.name_to_use() + fv_row_ts, feat_dict = fv_data[fv_name][entity_idx] + + if fv_row_ts: + fv_ts = Timestamp() + fv_ts.FromDatetime(utils.make_tzaware(fv_row_ts)) + fv_timestamps.append( + FeatureViewTimestamp( + feature_view_name=fv_name, + event_timestamp=fv_ts, + ) + ) + + for f in proj.features: + if feat_dict and f.name in feat_dict: + values.append(feat_dict[f.name]) + else: + values.append(ValueProto()) + + now_ts = Timestamp() + now_ts.FromDatetime(datetime.now(tz=_timezone.utc)) + + vector = PrecomputedFeatureVector( + feature_names=feature_names, + values=values, + fv_timestamps=fv_timestamps, + precomputed_at=now_ts, + ) + + online_store.write_precomputed_vector( + config=self.config, + feature_service_name=svc.name, + project=self.config.project, + entity_key=entity_key, + vector_bytes=vector.SerializeToString(), + ) + total_written += 1 + + _logger.info( + "Pre-computed %d entity vectors for FeatureService '%s'", + total_written, + svc.name, + ) + + return total_written + + def _precompute_affected_services(self, materialized_fv_names: List[str]) -> None: + """Trigger precomputation for services affected by materialized FVs.""" + try: + services = self.registry.list_feature_services(self.project) + except Exception: + return + + for svc in services: + if not svc.precompute_online: + continue + svc_fv_names = {p.name for p in svc.feature_view_projections} + if svc_fv_names & set(materialized_fv_names): + try: + self.precompute_feature_service(svc.name) + except Exception: + _logger.warning( + "Failed to precompute vectors for service '%s'", + svc.name, + exc_info=True, + ) + + def _precompute_for_push(self, feature_view_name: str, df: "pd.DataFrame") -> None: + """Re-compute pre-computed vectors for entities affected by a push.""" + try: + services = self.registry.list_feature_services(self.project) + except Exception: + return + + affected = [ + svc + for svc in services + if svc.precompute_online + and any(p.name == feature_view_name for p in svc.feature_view_projections) + ] + + if not affected: + return + + for svc in affected: + try: + self.precompute_feature_service(svc.name) + except Exception: + _logger.warning( + "Failed to precompute vectors for service '%s' after push", + svc.name, + exc_info=True, + ) + def push( self, push_source_name: str, @@ -1994,6 +2813,7 @@ def push( to: Whether to push to online or offline store. Defaults to online store only. transform_on_write: Whether to transform the data before pushing. """ + pushed_fv_names = [] for fv in self._fvs_for_push_source_or_raise( push_source_name, allow_registry_cache ): @@ -2004,11 +2824,15 @@ def push( allow_registry_cache=allow_registry_cache, transform_on_write=transform_on_write, ) + pushed_fv_names.append(fv.name) if to == PushMode.OFFLINE or to == PushMode.ONLINE_AND_OFFLINE: self.write_to_offline_store( fv.name, df, allow_registry_cache=allow_registry_cache ) + if pushed_fv_names: + self._precompute_for_push(pushed_fv_names[0], df) + async def push_async( self, push_source_name: str, @@ -2097,76 +2921,104 @@ def _transform_on_demand_feature_view_df( Raises: Exception: For unsupported OnDemandFeatureView modes """ - if feature_view.mode == "python" and isinstance( - feature_view.feature_transformation, PythonTransformation - ): - input_dict = ( - df.to_dict(orient="records")[0] - if feature_view.singleton - else df.to_dict(orient="list") + _should_track = False + try: + from feast.metrics import _config as _metrics_config + + _should_track = _metrics_config.online_features and getattr( + feature_view, "track_metrics", False ) + except Exception: + pass - if feature_view.singleton: - transformed_rows = [] + if _should_track: + import time as _time - for i, row in df.iterrows(): - output = feature_view.feature_transformation.udf(row.to_dict()) - if i == 0: - transformed_rows = output - else: - for k in output: - if isinstance(output[k], list): - transformed_rows[k].extend(output[k]) - else: - transformed_rows[k].append(output[k]) + _t0 = _time.monotonic() - transformed_data = pd.DataFrame(transformed_rows) - else: - transformed_data = feature_view.feature_transformation.udf(input_dict) - - if feature_view.write_to_online_store: - entities = [ - self.get_entity(entity) for entity in (feature_view.entities or []) - ] - join_keys = [entity.join_key for entity in entities if entity] - join_keys = [k for k in join_keys if k in input_dict.keys()] - transformed_df = ( - pd.DataFrame(transformed_data) - if not isinstance(transformed_data, pd.DataFrame) - else transformed_data - ) - input_df = pd.DataFrame( - [input_dict] if feature_view.singleton else input_dict + try: + if feature_view.mode == "python" and isinstance( + feature_view.feature_transformation, PythonTransformation + ): + input_dict = ( + df.to_dict(orient="records")[0] + if feature_view.singleton + else df.to_dict(orient="list") ) - if input_df.shape[0] == transformed_df.shape[0]: + + if feature_view.singleton: + transformed_rows = [] + + for i, row in df.iterrows(): + output = feature_view.feature_transformation.udf(row.to_dict()) + if i == 0: + transformed_rows = output + else: + for k in output: + if isinstance(output[k], list): + transformed_rows[k].extend(output[k]) + else: + transformed_rows[k].append(output[k]) + + transformed_data = pd.DataFrame(transformed_rows) + else: + transformed_data = feature_view.feature_transformation.udf( + input_dict + ) + + if feature_view.write_to_online_store: + entities = [ + self.get_entity(entity) + for entity in (feature_view.entities or []) + ] + join_keys = [entity.join_key for entity in entities if entity] + join_keys = [k for k in join_keys if k in input_dict.keys()] + transformed_df = ( + pd.DataFrame(transformed_data) + if not isinstance(transformed_data, pd.DataFrame) + else transformed_data + ) + input_df = pd.DataFrame( + [input_dict] if feature_view.singleton else input_dict + ) + if input_df.shape[0] == transformed_df.shape[0]: + for k in input_dict: + if k not in transformed_data: + transformed_data[k] = input_dict[k] + transformed_df = pd.DataFrame(transformed_data) + else: + transformed_df = pd.merge( + transformed_df, + input_df, + how="left", + on=join_keys, + ) + else: + # overwrite any transformed features and update the dictionary for k in input_dict: if k not in transformed_data: transformed_data[k] = input_dict[k] - transformed_df = pd.DataFrame(transformed_data) - else: - transformed_df = pd.merge( - transformed_df, - input_df, - how="left", - on=join_keys, - ) - else: - # overwrite any transformed features and update the dictionary - for k in input_dict: - if k not in transformed_data: - transformed_data[k] = input_dict[k] - return pd.DataFrame(transformed_data) + return pd.DataFrame(transformed_data) - elif feature_view.mode == "pandas" and isinstance( - feature_view.feature_transformation, PandasTransformation - ): - transformed_df = feature_view.feature_transformation.udf(df) - for col in df.columns: - transformed_df[col] = df[col] - return transformed_df - else: - raise Exception("Unsupported OnDemandFeatureView mode") + elif feature_view.mode == "pandas" and isinstance( + feature_view.feature_transformation, PandasTransformation + ): + transformed_df = feature_view.feature_transformation.udf(df) + for col in df.columns: + transformed_df[col] = df[col] + return transformed_df + else: + raise Exception("Unsupported OnDemandFeatureView mode") + finally: + if _should_track: + from feast.metrics import track_write_transformation + + track_write_transformation( + feature_view.name, + feature_view.mode, + _time.monotonic() - _t0, + ) def _validate_vector_features(self, feature_view, df: pd.DataFrame) -> None: """ @@ -2420,9 +3272,14 @@ def write_to_offline_store( feature_view_name, allow_registry_cache=allow_registry_cache ) except FeatureViewNotFoundException: - feature_view = self.get_feature_view( - feature_view_name, allow_registry_cache=allow_registry_cache - ) + try: + feature_view = self.get_feature_view( + feature_view_name, allow_registry_cache=allow_registry_cache + ) + except FeatureViewNotFoundException: + feature_view = self.get_label_view( # type: ignore[assignment] + feature_view_name, allow_registry_cache=allow_registry_cache + ) provider = self._get_provider() # Get columns of the batch source and the input dataframe. @@ -2463,6 +3320,7 @@ def get_online_features( Mapping[str, Union[Sequence[Any], Sequence[Value], RepeatedValue]], ], full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: """ Retrieves the latest online feature data. @@ -2507,6 +3365,8 @@ def get_online_features( """ provider = self._get_provider() + _retrieval_start = time.monotonic() + response = provider.get_online_features( config=self.config, features=features, @@ -2514,8 +3374,34 @@ def get_online_features( registry=self.registry, project=self.project, full_feature_names=full_feature_names, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) + # Auto-log to MLflow if configured + try: + if self.mlflow is not None and self.config.mlflow.auto_log: + _duration = time.monotonic() - _retrieval_start + _feature_refs = utils._get_features( + self.registry, self.project, features, allow_cache=True + ) + _entity_count = self._count_entities(entity_rows) + _fs = features if isinstance(features, FeatureService) else None + _fs_name = ( + features.name + if isinstance(features, FeatureService) + else self._resolve_feature_service_name(_feature_refs) + ) + self.mlflow.log_feature_retrieval( + feature_refs=_feature_refs, + entity_count=_entity_count, + duration_seconds=_duration, + retrieval_type="online", + feature_service=_fs, + feature_service_name=_fs_name, + ) + except Exception as e: + _logger.debug("MLflow auto-log failed for online retrieval: %s", e) + return response async def get_online_features_async( @@ -2526,6 +3412,7 @@ async def get_online_features_async( Mapping[str, Union[Sequence[Any], Sequence[Value], RepeatedValue]], ], full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: """ [Alpha] Retrieves the latest online feature data asynchronously. @@ -2555,15 +3442,65 @@ async def get_online_features_async( """ provider = self._get_provider() - return await provider.get_online_features_async( + _retrieval_start = time.monotonic() + + response = await provider.get_online_features_async( config=self.config, features=features, entity_rows=entity_rows, registry=self.registry, project=self.project, full_feature_names=full_feature_names, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) + try: + if self.mlflow is not None and self.config.mlflow.auto_log: + _duration = time.monotonic() - _retrieval_start + _mlflow_client = self.mlflow + _registry = self.registry + _project = self.project + + def _log_sync(): + try: + _feature_refs = utils._get_features( + _registry, _project, features, allow_cache=True + ) + _entity_count = self._count_entities(entity_rows) + _fs = features if isinstance(features, FeatureService) else None + _fs_name = ( + features.name + if isinstance(features, FeatureService) + else self._resolve_feature_service_name(_feature_refs) + ) + _mlflow_client.log_feature_retrieval( + feature_refs=_feature_refs, + entity_count=_entity_count, + duration_seconds=_duration, + retrieval_type="online", + feature_service=_fs, + feature_service_name=_fs_name, + ) + except Exception as exc: + _logger.debug( + "MLflow auto-log failed for async online retrieval: %s", + exc, + ) + + def _on_done(fut): + if not fut.cancelled() and fut.exception() is not None: + _logger.debug( + "MLflow auto-log executor failed: %s", fut.exception() + ) + + loop = asyncio.get_running_loop() + fut = loop.run_in_executor(None, _log_sync) + fut.add_done_callback(_on_done) + except Exception as e: + _logger.debug("MLflow auto-log failed for online retrieval: %s", e) + + return response + def retrieve_online_documents( self, query: Union[str, List[float]], @@ -2597,13 +3534,15 @@ def retrieve_online_documents( ) feature_view_set = set() for _feature in features: - feature_view_name = _feature.split(":")[0] - feature_view = self.get_feature_view(feature_view_name) + fv_name, _, _ = utils._parse_feature_ref(_feature) + feature_view = self.get_feature_view(fv_name) feature_view_set.add(feature_view.name) if len(feature_view_set) > 1: raise ValueError("Document retrieval only supports a single feature view.") requested_features = [ - f.split(":")[1] for f in features if isinstance(f, str) and ":" in f + utils._parse_feature_ref(f)[2] + for f in features + if isinstance(f, str) and ":" in f ] requested_feature_view_name = list(feature_view_set)[0] for feature_view in available_feature_views: @@ -2662,7 +3601,10 @@ def _doc_feature(x): online_features_response=online_features_response, data=requested_features_data, ) - return OnlineResponse(online_features_response) + feature_types = { + f.name: f.dtype.to_value_type() for f in requested_feature_view.features + } + return OnlineResponse(online_features_response, feature_types=feature_types) def retrieve_online_documents_v2( self, @@ -2677,6 +3619,7 @@ def retrieve_online_documents_v2( text_weight: float = 0.5, image_weight: float = 0.5, combine_strategy: str = "weighted_sum", + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: """ Retrieves the top k closest document features. Note, embeddings are a subset of features. @@ -2798,18 +3741,20 @@ def retrieve_online_documents_v2( ) feature_view_set = set() for feature in features: - feature_view_name = feature.split(":")[0] - if feature_view_name in [fv.name for fv in available_odfv_views]: + fv_name, _, _ = utils._parse_feature_ref(feature) + if fv_name in [fv.name for fv in available_odfv_views]: feature_view: Union[OnDemandFeatureView, FeatureView] = ( - self.get_on_demand_feature_view(feature_view_name) + self.get_on_demand_feature_view(fv_name) ) else: - feature_view = self.get_feature_view(feature_view_name) + feature_view = self.get_feature_view(fv_name) feature_view_set.add(feature_view.name) if len(feature_view_set) > 1: raise ValueError("Document retrieval only supports a single feature view.") requested_features = [ - f.split(":")[1] for f in features if isinstance(f, str) and ":" in f + utils._parse_feature_ref(f)[2] + for f in features + if isinstance(f, str) and ":" in f ] if len(available_feature_views) == 0: available_feature_views.extend(available_odfv_views) # type: ignore[arg-type] @@ -2829,6 +3774,7 @@ def retrieve_online_documents_v2( top_k, distance_metric, query_string, + include_feature_view_version_metadata, ) def _retrieve_from_online_store( @@ -2893,6 +3839,7 @@ def _retrieve_from_online_store_v2( top_k: int, distance_metric: Optional[str], query_string: Optional[str], + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: """ Search and return document features from the online document store. @@ -2909,6 +3856,7 @@ def _retrieve_from_online_store_v2( top_k=top_k, distance_metric=distance_metric, query_string=query_string, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) entity_key_dict: Dict[str, List[ValueProto]] = {} @@ -2946,26 +3894,23 @@ def _retrieve_from_online_store_v2( online_features_response.metadata.feature_names.val.extend( features_to_request ) - return OnlineResponse(online_features_response) + feature_types = {f.name: f.dtype.to_value_type() for f in table.features} + return OnlineResponse(online_features_response, feature_types=feature_types) table_entity_values, idxs, output_len = utils._get_unique_entities_from_values( entity_key_dict, ) - feature_data = utils._convert_rows_to_protobuf( - requested_features=features_to_request, - read_rows=list(zip(datevals, list_of_feature_dicts)), - ) - online_features_response = GetOnlineFeaturesResponse(results=[]) utils._populate_response_from_feature_data( - feature_data=feature_data, + requested_features=features_to_request, + read_rows=list(zip(datevals, list_of_feature_dicts)), indexes=idxs, online_features_response=online_features_response, full_feature_names=False, - requested_features=features_to_request, table=table, output_len=output_len, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) utils._populate_result_rows_from_columnar( @@ -2973,7 +3918,8 @@ def _retrieve_from_online_store_v2( data=entity_key_dict, ) - return OnlineResponse(online_features_response) + feature_types = {f.name: f.dtype.to_value_type() for f in table.features} + return OnlineResponse(online_features_response, feature_types=feature_types) def serve( self, @@ -3022,8 +3968,6 @@ def serve_ui( self, host: str, port: int, - get_registry_dump: Callable, - registry_ttl_sec: int, root_path: str = "", tls_key_path: str = "", tls_cert_path: str = "", @@ -3039,9 +3983,7 @@ def serve_ui( self, host=host, port=port, - get_registry_dump=get_registry_dump, project_id=self.config.project, - registry_ttl_sec=registry_ttl_sec, root_path=root_path, tls_key_path=tls_key_path, tls_cert_path=tls_cert_path, @@ -3275,6 +4217,19 @@ def get_project(self, name: Optional[str]) -> Project: """ return self.registry.get_project(name or self.project) + def delete_project(self, name: str, commit: bool = True) -> None: + """ + Deletes a project from the registry. + + Args: + name: Name of the project to delete. + commit: Whether the change should be persisted immediately. + + Raises: + ProjectNotFoundException: The project could not be found. + """ + return self.registry.delete_project(name, commit=commit) + def list_saved_datasets( self, allow_cache: bool = False, tags: Optional[dict[str, str]] = None ) -> List[SavedDataset]: diff --git a/sdk/python/feast/feature_view.py b/sdk/python/feast/feature_view.py index 94e95da545f..a5d3c8d9537 100644 --- a/sdk/python/feast/feature_view.py +++ b/sdk/python/feast/feature_view.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import copy +import enum import warnings from datetime import datetime, timedelta from typing import Dict, List, Optional, Tuple, Type, Union @@ -44,9 +45,53 @@ from feast.transformation.mode import TransformationMode from feast.types import from_value_type from feast.value_type import ValueType +from feast.version_utils import normalize_version_string warnings.simplefilter("once", DeprecationWarning) + +class FeatureViewState(enum.IntEnum): + """Lifecycle state of a feature view. + + Maps to the ``FeatureViewState`` proto enum defined in + ``protos/feast/core/FeatureView.proto``. + """ + + STATE_UNSPECIFIED = 0 + CREATED = 1 + GENERATED = 2 + MATERIALIZING = 3 + AVAILABLE_ONLINE = 4 + + def can_transition_to(self, target: "FeatureViewState") -> bool: + """Return True if transitioning from this state to *target* is allowed.""" + allowed = _VALID_STATE_TRANSITIONS.get(self, set()) + return target in allowed + + @classmethod + def from_proto(cls, proto_val: int) -> "FeatureViewState": + try: + return cls(proto_val) + except ValueError: + return cls.STATE_UNSPECIFIED + + def to_proto(self) -> int: + return self.value + + +# Valid state transitions: maps each state to the set of states it can move to. +_VALID_STATE_TRANSITIONS: dict[FeatureViewState, set[FeatureViewState]] = { + FeatureViewState.STATE_UNSPECIFIED: {FeatureViewState.CREATED}, + FeatureViewState.CREATED: {FeatureViewState.GENERATED}, + FeatureViewState.GENERATED: {FeatureViewState.MATERIALIZING}, + FeatureViewState.MATERIALIZING: { + FeatureViewState.AVAILABLE_ONLINE, + FeatureViewState.GENERATED, + }, + FeatureViewState.AVAILABLE_ONLINE: {FeatureViewState.MATERIALIZING}, +} + + # DUMMY_ENTITY is a placeholder entity used in entityless FeatureViews DUMMY_ENTITY_ID = "__dummy_id" DUMMY_ENTITY_NAME = "__dummy" @@ -88,6 +133,8 @@ class FeatureView(BaseFeatureView): tags: A dictionary of key-value pairs to store arbitrary metadata. owner: The owner of the feature view, typically the email of the primary maintainer. + org: The organizational unit that owns this feature view (e.g. "ads", "search"). + Defaults to empty string. mode: The transformation mode for feature transformations. Only meaningful when transformations are applied. Choose from TransformationMode enum values (e.g., PYTHON, PANDAS, RAY, SQL, SPARK, SUBSTRAIT). @@ -106,9 +153,13 @@ class FeatureView(BaseFeatureView): description: str tags: Dict[str, str] owner: str + org: str materialization_intervals: List[Tuple[datetime, datetime]] mode: Optional[Union["TransformationMode", str]] enable_validation: bool + enabled: bool + state: FeatureViewState + _raw_feature_transformation_proto: Optional[Message] = None def __init__( self, @@ -124,8 +175,11 @@ def __init__( description: str = "", tags: Optional[Dict[str, str]] = None, owner: str = "", + org: str = "", mode: Optional[Union["TransformationMode", str]] = None, enable_validation: bool = False, + version: str = "latest", + enabled: bool = True, ): """ Creates a FeatureView object. @@ -150,15 +204,22 @@ def __init__( tags (optional): A dictionary of key-value pairs to store arbitrary metadata. owner (optional): The owner of the feature view, typically the email of the primary maintainer. + org (optional): The organizational unit that owns this feature view + (e.g. "ads", "search"). mode (optional): The transformation mode for feature transformations. Only meaningful when transformations are applied. Choose from TransformationMode enum values. enable_validation (optional): If True, enables schema validation during materialization to check that data conforms to the declared feature types. Default is False. + version (optional): Version string for definition management. Controls which historical + snapshot is active after ``feast apply``. Only one version can be active per feature + view name per project. For concurrent multi-version testing, use separate projects + or distinct feature view names. Default is "latest". Raises: ValueError: A field mapping conflicts with an Entity or a Feature. """ self.name = name + self.version = version self.enable_validation = enable_validation self.entities = [e.name for e in entities] if entities else [DUMMY_ENTITY_NAME] self.ttl = ttl @@ -271,10 +332,13 @@ def __init__( owner=owner, source=self.batch_source, ) + self.org = org self.online = online self.offline = offline self.mode = mode self.materialization_intervals = [] + self.enabled = enabled + self.state = FeatureViewState.STATE_UNSPECIFIED def __hash__(self): return super().__hash__() @@ -292,6 +356,11 @@ def __copy__(self): offline=self.offline, sink_source=self.batch_source if self.source_views else None, enable_validation=self.enable_validation, + version=self.version, + description=self.description, + owner=self.owner, + org=self.org, + enabled=self.enabled, ) # This is deliberately set outside of the FV initialization as we do not have the Entity objects. @@ -299,8 +368,31 @@ def __copy__(self): fv.features = copy.copy(self.features) fv.entity_columns = copy.copy(self.entity_columns) fv.projection = copy.copy(self.projection) + fv.state = self.state return fv + def _schema_or_udf_changed(self, other: "BaseFeatureView") -> bool: + """Check for FeatureView schema/UDF changes.""" + if super()._schema_or_udf_changed(other): + return True + + if not isinstance(other, FeatureView): + return True + + # Schema-related fields + if sorted(self.entities) != sorted(other.entities): + return True + if sorted(self.entity_columns) != sorted(other.entity_columns): + return True + if self.source_views != other.source_views: + return True + + # Skip UDF-related data source fields: batch_source, stream_source + # (treat as deployment configuration, not schema changes) + # Skip configuration: ttl, online, offline, enable_validation + # Skip metadata: materialization_intervals (excluded in current equality) + return False + def __eq__(self, other): if not isinstance(other, FeatureView): raise TypeError( @@ -321,6 +413,9 @@ def __eq__(self, other): or self.source_views != other.source_views or self.materialization_intervals != other.materialization_intervals or self.enable_validation != other.enable_validation + or normalize_version_string(self.version) + != normalize_version_string(other.version) + or self.org != other.org ): return False @@ -438,7 +533,9 @@ def to_proto_spec( ] feature_transformation_proto = None - if hasattr(self, "feature_transformation") and self.feature_transformation: + if getattr(self, "_raw_feature_transformation_proto", None) is not None: + feature_transformation_proto = self._raw_feature_transformation_proto + elif hasattr(self, "feature_transformation") and self.feature_transformation: feature_transformation_proto = transformation_to_proto( self.feature_transformation ) @@ -451,6 +548,7 @@ def to_proto_spec( description=self.description, tags=self.tags, owner=self.owner, + org=self.org, ttl=(ttl_duration if ttl_duration is not None else None), online=self.online, offline=self.offline, @@ -460,6 +558,8 @@ def to_proto_spec( feature_transformation=feature_transformation_proto, mode=mode_to_string(self.mode), enable_validation=self.enable_validation, + version=self.version, + disabled=not self.enabled, ) def to_proto_meta(self): @@ -473,6 +573,10 @@ def to_proto_meta(self): interval_proto.start_time.FromDatetime(interval[0]) interval_proto.end_time.FromDatetime(interval[1]) meta.materialization_intervals.append(interval_proto) + if self.current_version_number is not None: + meta.current_version_number = self.current_version_number + if self.state != FeatureViewState.STATE_UNSPECIFIED: + meta.state = self.state.to_proto() return meta def get_ttl_duration(self): @@ -483,14 +587,17 @@ def get_ttl_duration(self): return ttl_duration @classmethod - def from_proto(cls, feature_view_proto: FeatureViewProto) -> "FeatureView": - return cls._from_proto_internal(feature_view_proto, seen={}) + def from_proto( + cls, feature_view_proto: FeatureViewProto, skip_udf: bool = False + ) -> "FeatureView": + return cls._from_proto_internal(feature_view_proto, seen={}, skip_udf=skip_udf) @classmethod def _from_proto_internal( cls, feature_view_proto: FeatureViewProto, seen: Dict[str, Union[None, "FeatureView"]], + skip_udf: bool = False, ) -> "FeatureView": """ Creates a feature view from a protobuf representation of a feature view. @@ -524,7 +631,7 @@ def _from_proto_internal( ) source_views = [ FeatureView._from_proto_internal( - FeatureViewProto(spec=view_spec, meta=None), seen + FeatureViewProto(spec=view_spec, meta=None), seen, skip_udf=skip_udf ) for view_spec in feature_view_proto.spec.source_views ] @@ -544,22 +651,23 @@ def _from_proto_internal( ) transformation = None - if feature_transformation_proto.HasField("user_defined_function"): - udf_proto = feature_transformation_proto.user_defined_function - if udf_proto.mode: - try: - transformation_class = get_transformation_class_from_type( - udf_proto.mode - ) - transformation = transformation_class.from_proto(udf_proto) - except (ValueError, KeyError): + if not skip_udf: + if feature_transformation_proto.HasField("user_defined_function"): + udf_proto = feature_transformation_proto.user_defined_function + if udf_proto.mode: + try: + transformation_class = get_transformation_class_from_type( + udf_proto.mode + ) + transformation = transformation_class.from_proto(udf_proto) + except (ValueError, KeyError): + transformation = PythonTransformation.from_proto(udf_proto) + else: transformation = PythonTransformation.from_proto(udf_proto) - else: - transformation = PythonTransformation.from_proto(udf_proto) - elif feature_transformation_proto.HasField("substrait_transformation"): - transformation = SubstraitTransformation.from_proto( - feature_transformation_proto.substrait_transformation - ) + elif feature_transformation_proto.HasField("substrait_transformation"): + transformation = SubstraitTransformation.from_proto( + feature_transformation_proto.substrait_transformation + ) mode: Union[TransformationMode, str] if feature_view_proto.spec.mode: @@ -574,6 +682,7 @@ def _from_proto_internal( description=feature_view_proto.spec.description, tags=dict(feature_view_proto.spec.tags), owner=feature_view_proto.spec.owner, + org=feature_view_proto.spec.org, online=feature_view_proto.spec.online, offline=feature_view_proto.spec.offline, ttl=( @@ -584,8 +693,14 @@ def _from_proto_internal( source=source_views if source_views else batch_source, # type: ignore[arg-type] sink_source=batch_source if source_views else None, mode=mode, - feature_transformation=transformation, + feature_transformation=transformation + if not skip_udf + else feature_transformation_proto, # type: ignore[arg-type] ) + if skip_udf: + feature_view._raw_feature_transformation_proto = ( + feature_transformation_proto + ) else: mode_from_spec = ( feature_view_proto.spec.mode if feature_view_proto.spec.mode else None @@ -596,6 +711,7 @@ def _from_proto_internal( description=feature_view_proto.spec.description, tags=dict(feature_view_proto.spec.tags), owner=feature_view_proto.spec.owner, + org=feature_view_proto.spec.org, online=feature_view_proto.spec.online, offline=feature_view_proto.spec.offline, ttl=( @@ -632,6 +748,25 @@ def _from_proto_internal( # Restore enable_validation from proto field. feature_view.enable_validation = feature_view_proto.spec.enable_validation + # Restore enabled from proto's inverted 'disabled' field. + # Proto bool defaults to False, so old protos without this field + # will correctly default to enabled=True. + feature_view.enabled = not feature_view_proto.spec.disabled + + # Restore lifecycle state from meta. + feature_view.state = FeatureViewState.from_proto(feature_view_proto.meta.state) + + # Restore version fields. + spec_version = feature_view_proto.spec.version + feature_view.version = spec_version or "latest" + cvn = feature_view_proto.meta.current_version_number + if cvn > 0: + feature_view.current_version_number = cvn + elif cvn == 0 and spec_version and spec_version.lower() != "latest": + feature_view.current_version_number = 0 + else: + feature_view.current_version_number = None + # FeatureViewProjections are not saved in the FeatureView proto. # Create the default projection. feature_view.projection = FeatureViewProjection.from_feature_view_definition( diff --git a/sdk/python/feast/feature_view_projection.py b/sdk/python/feast/feature_view_projection.py index 530194ec6a8..a91c6498604 100644 --- a/sdk/python/feast/feature_view_projection.py +++ b/sdk/python/feast/feature_view_projection.py @@ -47,9 +47,14 @@ class FeatureViewProjection: date_partition_column: Optional[str] = None created_timestamp_column: Optional[str] = None batch_source: Optional[DataSource] = None + version_tag: Optional[int] = None + view_type: str = "featureView" def name_to_use(self): - return self.name_alias or self.name + base = self.name_alias or self.name + if self.version_tag is not None: + return f"{base}@v{self.version_tag}" + return base def to_proto(self) -> FeatureViewProjectionProto: batch_source = None @@ -66,10 +71,14 @@ def to_proto(self) -> FeatureViewProjectionProto: date_partition_column=self.date_partition_column or "", created_timestamp_column=self.created_timestamp_column or "", batch_source=batch_source, + view_type=getattr(self, "view_type", "") or "", ) for feature in self.features: feature_reference_proto.feature_columns.append(feature.to_proto()) + if self.version_tag is not None: + feature_reference_proto.version_tag = self.version_tag + return feature_reference_proto @staticmethod @@ -93,6 +102,11 @@ def from_proto(proto: FeatureViewProjectionProto) -> "FeatureViewProjection": for feature_column in proto.feature_columns: feature_view_projection.features.append(Field.from_proto(feature_column)) + if proto.HasField("version_tag"): + feature_view_projection.version_tag = proto.version_tag + + feature_view_projection.view_type = proto.view_type or "featureView" + return feature_view_projection @staticmethod diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index c61ed6a5c5e..3055bd70830 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -23,6 +23,7 @@ from feast.value_type import ValueType STRUCT_SCHEMA_TAG = "feast:struct_schema" +NESTED_COLLECTION_INNER_TYPE_TAG = "feast:nested_inner_type" @typechecked @@ -118,7 +119,7 @@ def __str__(self): def to_proto(self) -> FieldProto: """Converts a Field object to its protobuf representation.""" - from feast.types import Array + from feast.types import Array, Set value_type = self.dtype.to_value_type() vector_search_metric = self.vector_search_metric or "" @@ -128,9 +129,14 @@ def to_proto(self) -> FieldProto: tags[STRUCT_SCHEMA_TAG] = _serialize_struct_schema(self.dtype) elif isinstance(self.dtype, Array) and isinstance(self.dtype.base_type, Struct): tags[STRUCT_SCHEMA_TAG] = _serialize_struct_schema(self.dtype.base_type) + # Persist nested collection type info in tags + if isinstance(self.dtype, (Array, Set)) and isinstance( + self.dtype.base_type, (Array, Set) + ): + tags[NESTED_COLLECTION_INNER_TYPE_TAG] = _feast_type_to_str(self.dtype) return FieldProto( name=self.name, - value_type=value_type.value, + value_type=value_type.value, # type: ignore[arg-type] description=self.description, tags=tags, vector_index=self.vector_index, @@ -155,17 +161,24 @@ def from_proto(cls, field_proto: FieldProto): # Reconstruct Struct type from persisted schema in tags from feast.types import Array + internal_tags = {STRUCT_SCHEMA_TAG, NESTED_COLLECTION_INNER_TYPE_TAG} dtype: FeastType if value_type == ValueType.STRUCT and STRUCT_SCHEMA_TAG in tags: dtype = _deserialize_struct_schema(tags[STRUCT_SCHEMA_TAG]) - user_tags = {k: v for k, v in tags.items() if k != STRUCT_SCHEMA_TAG} + user_tags = {k: v for k, v in tags.items() if k not in internal_tags} elif value_type == ValueType.STRUCT_LIST and STRUCT_SCHEMA_TAG in tags: inner_struct = _deserialize_struct_schema(tags[STRUCT_SCHEMA_TAG]) dtype = Array(inner_struct) - user_tags = {k: v for k, v in tags.items() if k != STRUCT_SCHEMA_TAG} + user_tags = {k: v for k, v in tags.items() if k not in internal_tags} + elif ( + value_type in (ValueType.VALUE_LIST, ValueType.VALUE_SET) + and NESTED_COLLECTION_INNER_TYPE_TAG in tags + ): + dtype = _str_to_feast_type(tags[NESTED_COLLECTION_INNER_TYPE_TAG]) + user_tags = {k: v for k, v in tags.items() if k not in internal_tags} else: dtype = from_value_type(value_type=value_type) - user_tags = tags + user_tags = {k: v for k, v in tags.items() if k not in internal_tags} return cls( name=field_proto.name, @@ -198,6 +211,7 @@ def _feast_type_to_str(feast_type: FeastType) -> str: from feast.types import ( Array, PrimitiveFeastType, + Set, ) if isinstance(feast_type, PrimitiveFeastType): @@ -209,6 +223,8 @@ def _feast_type_to_str(feast_type: FeastType) -> str: return json.dumps({"__struct__": nested}) elif isinstance(feast_type, Array): return f"Array({_feast_type_to_str(feast_type.base_type)})" + elif isinstance(feast_type, Set): + return f"Set({_feast_type_to_str(feast_type.base_type)})" else: return str(feast_type) @@ -218,6 +234,7 @@ def _str_to_feast_type(type_str: str) -> FeastType: from feast.types import ( Array, PrimitiveFeastType, + Set, ) # Check if it's an Array type @@ -226,6 +243,12 @@ def _str_to_feast_type(type_str: str) -> FeastType: base_type = _str_to_feast_type(inner) return Array(base_type) + # Check if it's a Set type + if type_str.startswith("Set(") and type_str.endswith(")"): + inner = type_str[4:-1] + base_type = _str_to_feast_type(inner) + return Set(base_type) + # Check if it's a nested Struct (JSON encoded) if type_str.startswith("{"): try: @@ -243,9 +266,10 @@ def _str_to_feast_type(type_str: str) -> FeastType: try: return PrimitiveFeastType[type_str] except KeyError: - from feast.types import String - - return String + raise ValueError( + f"Unknown FeastType: {type_str!r}. " + f"Valid primitive types: {[t.name for t in PrimitiveFeastType]}" + ) def _serialize_struct_schema(struct_type: Struct) -> str: diff --git a/sdk/python/feast/infra/common/serde.py b/sdk/python/feast/infra/common/serde.py index 90e1be9234e..572b3db0bec 100644 --- a/sdk/python/feast/infra/common/serde.py +++ b/sdk/python/feast/infra/common/serde.py @@ -30,7 +30,8 @@ def unserialize(self): # unserialize proto = FeatureViewProto() proto.ParseFromString(self.feature_view_proto) - feature_view = FeatureView.from_proto(proto) + # skip_udf=True: the write node only needs schema / entity metadata. + feature_view = FeatureView.from_proto(proto, skip_udf=True) # load repo_config = dill.loads(self.repo_config_byte) diff --git a/sdk/python/feast/infra/compute_engines/backends/factory.py b/sdk/python/feast/infra/compute_engines/backends/factory.py index ffe969f3003..91ece19b329 100644 --- a/sdk/python/feast/infra/compute_engines/backends/factory.py +++ b/sdk/python/feast/infra/compute_engines/backends/factory.py @@ -24,9 +24,10 @@ def from_name(name: str) -> DataFrameBackend: @staticmethod def infer_from_entity_df(entity_df) -> Optional[DataFrameBackend]: if ( - not entity_df - or isinstance(entity_df, pyarrow.Table) + entity_df is None or isinstance(entity_df, pd.DataFrame) + or isinstance(entity_df, pyarrow.Table) + or (isinstance(entity_df, str) and not entity_df) ): return PandasBackend() diff --git a/sdk/python/feast/infra/compute_engines/backends/polars_backend.py b/sdk/python/feast/infra/compute_engines/backends/polars_backend.py index 92e348c3652..118b0b8eab7 100644 --- a/sdk/python/feast/infra/compute_engines/backends/polars_backend.py +++ b/sdk/python/feast/infra/compute_engines/backends/polars_backend.py @@ -7,6 +7,8 @@ class PolarsBackend(DataFrameBackend): + _POLARS_FUNC_MAP = {"nunique": "n_unique"} + def columns(self, df: pl.DataFrame) -> list[str]: return df.columns @@ -21,7 +23,7 @@ def join(self, left: pl.DataFrame, right: pl.DataFrame, on, how) -> pl.DataFrame def groupby_agg(self, df: pl.DataFrame, group_keys, agg_ops) -> pl.DataFrame: agg_exprs = [ - getattr(pl.col(col), func)().alias(alias) + getattr(pl.col(col), self._POLARS_FUNC_MAP.get(func, func))().alias(alias) for alias, (func, col) in agg_ops.items() ] return df.groupby(group_keys).agg(agg_exprs) diff --git a/sdk/python/feast/infra/compute_engines/dag/context.py b/sdk/python/feast/infra/compute_engines/dag/context.py index 46eda356223..38b9a788872 100644 --- a/sdk/python/feast/infra/compute_engines/dag/context.py +++ b/sdk/python/feast/infra/compute_engines/dag/context.py @@ -42,6 +42,18 @@ def created_timestamp_column(self) -> Optional[str]: """ return self._get_mapped_column(self.created_ts_col) + @property + def join_keys_columns(self) -> List[str]: + """ + Get the join keys, mapped through field_mapping to their post-rename + column names. Use this when looking up columns on a DataFrame that has + already had its source columns renamed (e.g. inside DAG nodes that + consume the output of a source-read node). + """ + if not self.field_mapping: + return list(self.join_keys) + return [self.field_mapping.get(key, key) for key in self.join_keys] + def _get_mapped_column(self, column: Optional[str]) -> Optional[str]: """ Helper method to get the mapped column name if it exists in field_mapping. diff --git a/sdk/python/feast/infra/compute_engines/dag/model.py b/sdk/python/feast/infra/compute_engines/dag/model.py index 5990eea6141..263c5029f4f 100644 --- a/sdk/python/feast/infra/compute_engines/dag/model.py +++ b/sdk/python/feast/infra/compute_engines/dag/model.py @@ -6,3 +6,4 @@ class DAGFormat(str, Enum): PANDAS = "pandas" ARROW = "arrow" RAY = "ray" + FLINK = "flink" diff --git a/sdk/python/feast/infra/compute_engines/feature_builder.py b/sdk/python/feast/infra/compute_engines/feature_builder.py index 8510b676c07..2a102bf9f2f 100644 --- a/sdk/python/feast/infra/compute_engines/feature_builder.py +++ b/sdk/python/feast/infra/compute_engines/feature_builder.py @@ -158,9 +158,17 @@ def get_column_info( # we need to read ALL source columns, not just the output feature columns. # This is specifically for transformations that create new columns or need raw data. mode = getattr(getattr(view, "feature_transformation", None), "mode", None) - if mode == "ray" or getattr(mode, "value", None) == "ray": - # Signal to read all columns by passing empty list for feature_cols - # The transformation will produce the output columns defined in the schema + if mode in ("ray", "pandas", "python", "flink") or getattr( + mode, "value", None + ) in ( + "ray", + "pandas", + "python", + "flink", + ): + # Signal to read all columns by passing empty list for feature_cols. + # "python" (BatchFeatureView) transformations need all raw source columns — the + # UDF computes output features from raw input, not from pre-existing feature cols. feature_cols = [] return ColumnInfo( diff --git a/sdk/python/feast/infra/compute_engines/flink/__init__.py b/sdk/python/feast/infra/compute_engines/flink/__init__.py new file mode 100644 index 00000000000..678bae5afc6 --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/__init__.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from feast.infra.compute_engines.flink.compute import ( + FlinkComputeEngine, + FlinkComputeEngineConfig, +) + +__all__ = [ + "FlinkComputeEngine", + "FlinkComputeEngineConfig", +] diff --git a/sdk/python/feast/infra/compute_engines/flink/compute.py b/sdk/python/feast/infra/compute_engines/flink/compute.py new file mode 100644 index 00000000000..b0cfc645a7a --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/compute.py @@ -0,0 +1,161 @@ +from __future__ import annotations + +import logging +from typing import Any, Dict, Literal, Optional, Sequence, Union + +from feast import ( + BatchFeatureView, + Entity, + FeatureView, + OnDemandFeatureView, + StreamFeatureView, +) +from feast.infra.common.materialization_job import ( + MaterializationJob, + MaterializationJobStatus, + MaterializationTask, +) +from feast.infra.common.retrieval_task import HistoricalRetrievalTask +from feast.infra.compute_engines.base import ComputeEngine +from feast.infra.compute_engines.flink.feature_builder import FlinkFeatureBuilder +from feast.infra.compute_engines.flink.job import ( + FlinkDAGRetrievalJob, + FlinkMaterializationJob, +) +from feast.infra.compute_engines.flink.utils import ( + cleanup_flink_temporary_views, + create_flink_table_environment, +) +from feast.infra.offline_stores.offline_store import OfflineStore, RetrievalJob +from feast.infra.online_stores.online_store import OnlineStore +from feast.infra.registry.base_registry import BaseRegistry +from feast.repo_config import FeastConfigBaseModel, RepoConfig + +logger = logging.getLogger(__name__) + + +class FlinkComputeEngineConfig(FeastConfigBaseModel): + """Configuration for the Apache Flink compute engine.""" + + type: Literal["flink.engine"] = "flink.engine" + """Flink compute engine type selector.""" + + execution_mode: Literal["batch", "streaming"] = "batch" + """PyFlink TableEnvironment execution mode.""" + + parallelism: Optional[int] = None + """Default Flink parallelism for jobs created by this engine.""" + + table_config: Optional[Dict[str, str]] = None + """Additional PyFlink table configuration entries.""" + + pandas_split_num: int = 1 + """Number of PyFlink Arrow source splits for pandas entity DataFrames.""" + + +class FlinkComputeEngine(ComputeEngine): + def __init__( + self, + *, + repo_config: RepoConfig, + offline_store: OfflineStore, + online_store: OnlineStore, + table_environment: Optional[Any] = None, + **kwargs, + ) -> None: + super().__init__( + repo_config=repo_config, + offline_store=offline_store, + online_store=online_store, + **kwargs, + ) + self.config = repo_config.batch_engine + assert isinstance(self.config, FlinkComputeEngineConfig) + self.table_env = table_environment or create_flink_table_environment( + self.config + ) + + def update( + self, + project: str, + views_to_delete: Sequence[ + Union[BatchFeatureView, StreamFeatureView, FeatureView] + ], + views_to_keep: Sequence[ + Union[BatchFeatureView, StreamFeatureView, FeatureView, OnDemandFeatureView] + ], + entities_to_delete: Sequence[Entity], + entities_to_keep: Sequence[Entity], + ) -> None: + """Flink compute engine does not provision Feast-managed infrastructure.""" + pass + + def teardown_infra( + self, + project: str, + fvs: Sequence[Union[BatchFeatureView, StreamFeatureView, FeatureView]], + entities: Sequence[Entity], + ) -> None: + """Flink compute engine does not tear down Feast-managed infrastructure.""" + pass + + def _materialize_one( + self, registry: BaseRegistry, task: MaterializationTask, **kwargs + ) -> MaterializationJob: + job_id = f"{task.feature_view.name}-{task.start_time}-{task.end_time}" + context = self.get_execution_context(registry, task) + + try: + builder = FlinkFeatureBuilder( + registry=registry, + table_env=self.table_env, + task=task, + split_num=self.config.pandas_split_num, + ) + plan = builder.build() + plan.execute(context) + return FlinkMaterializationJob( + job_id=job_id, + status=MaterializationJobStatus.SUCCEEDED, + ) + except Exception as exc: + logger.error("Flink materialization failed for %s: %s", job_id, exc) + return FlinkMaterializationJob( + job_id=job_id, + status=MaterializationJobStatus.ERROR, + error=exc, + ) + finally: + cleanup_flink_temporary_views(self.table_env) + + def get_historical_features( + self, registry: BaseRegistry, task: HistoricalRetrievalTask + ) -> RetrievalJob: + context = self.get_execution_context(registry, task) + try: + builder = FlinkFeatureBuilder( + registry=registry, + table_env=self.table_env, + task=task, + split_num=self.config.pandas_split_num, + ) + plan = builder.build() + return FlinkDAGRetrievalJob( + plan=plan, + context=context, + table_env=self.table_env, + full_feature_names=task.full_feature_name, + ) + except Exception as exc: + logger.error( + "Flink historical retrieval setup failed for %s: %s", + task.feature_view.name, + exc, + ) + return FlinkDAGRetrievalJob( + plan=None, + context=context, + table_env=self.table_env, + full_feature_names=task.full_feature_name, + error=exc, + ) diff --git a/sdk/python/feast/infra/compute_engines/flink/feature_builder.py b/sdk/python/feast/infra/compute_engines/flink/feature_builder.py new file mode 100644 index 00000000000..3fd276c92fe --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/feature_builder.py @@ -0,0 +1,214 @@ +from __future__ import annotations + +import logging +from typing import Any, Union + +import pandas as pd + +from feast.infra.common.materialization_job import MaterializationTask +from feast.infra.common.retrieval_task import HistoricalRetrievalTask +from feast.infra.compute_engines.dag.node import DAGNode +from feast.infra.compute_engines.feature_builder import FeatureBuilder +from feast.infra.compute_engines.flink.nodes import ( + FlinkAggregationNode, + FlinkDedupNode, + FlinkFilterNode, + FlinkJoinNode, + FlinkOutputNode, + FlinkSourceReadNode, + FlinkTransformationNode, + FlinkValidationNode, +) +from feast.infra.registry.base_registry import BaseRegistry +from feast.types import PrimitiveFeastType, from_feast_to_pyarrow_type + +logger = logging.getLogger(__name__) + + +class FlinkFeatureBuilder(FeatureBuilder): + def __init__( + self, + registry: BaseRegistry, + table_env: Any, + task: Union[MaterializationTask, HistoricalRetrievalTask], + split_num: int, + ) -> None: + super().__init__(registry, task.feature_view, task) + self.table_env = table_env + self.split_num = split_num + + def _should_join_entity_df(self) -> bool: + return isinstance(self.task, HistoricalRetrievalTask) and ( + isinstance(self.task.entity_df, pd.DataFrame) + or ( + isinstance(self.task.entity_df, str) + and bool(self.task.entity_df.strip()) + ) + ) + + def _build(self, view: Any, input_nodes: list[DAGNode] | None) -> DAGNode: + if view.data_source: + last_node: DAGNode = self.build_source_node(view) + + if self._should_transform(view): + last_node = self.build_transformation_node(view, [last_node]) + + if self._should_join_entity_df(): + last_node = self.build_join_node(view, [last_node]) + + elif input_nodes: + if self._should_transform(view): + last_node = self.build_transformation_node(view, input_nodes) + else: + last_node = self.build_join_node(view, input_nodes) + else: + raise ValueError(f"FeatureView {view.name} has no valid source or inputs") + + last_node = self.build_filter_node(view, last_node) + + if self._should_aggregate(view): + last_node = self.build_aggregation_node(view, last_node) + elif self._should_dedupe(view): + last_node = self.build_dedup_node(view, last_node) + + if self._should_validate(view): + last_node = self.build_validation_node(view, last_node) + + return last_node + + def build_source_node(self, view: Any) -> FlinkSourceReadNode: + source = view.batch_source + column_info = self.get_column_info(view) + node = FlinkSourceReadNode( + f"{view.name}:source", + source, + column_info, + self.table_env, + self.split_num, + self.task.start_time, + self.task.end_time, + ) + self.nodes.append(node) + return node + + def build_aggregation_node( + self, view: Any, input_node: DAGNode + ) -> FlinkAggregationNode: + column_info = self.get_column_info(view) + node = FlinkAggregationNode( + f"{view.name}:agg", + column_info.join_keys_columns, + view.aggregations, + self.table_env, + self.split_num, + inputs=[input_node], + ) + self.nodes.append(node) + return node + + def build_join_node(self, view: Any, input_nodes: list[DAGNode]) -> FlinkJoinNode: + column_info = self.get_column_info(view) + node = FlinkJoinNode( + f"{view.name}:join", + column_info, + self.table_env, + self.split_num, + inputs=input_nodes, + ) + self.nodes.append(node) + return node + + def build_filter_node(self, view: Any, input_node: DAGNode) -> FlinkFilterNode: + filter_expr = getattr(view, "filter", None) + ttl = getattr(view, "ttl", None) + column_info = self.get_column_info(view) + node = FlinkFilterNode( + f"{view.name}:filter", + column_info, + self.table_env, + self.split_num, + filter_expr, + ttl, + inputs=[input_node], + ) + self.nodes.append(node) + return node + + def build_dedup_node(self, view: Any, input_node: DAGNode) -> FlinkDedupNode: + column_info = self.get_column_info(view) + node = FlinkDedupNode( + f"{view.name}:dedup", + column_info, + self.table_env, + self.split_num, + inputs=[input_node], + ) + self.nodes.append(node) + return node + + def build_transformation_node( + self, view: Any, input_nodes: list[DAGNode] + ) -> FlinkTransformationNode: + transform_config = view.feature_transformation + transformation_fn = ( + transform_config.udf + if hasattr(transform_config, "udf") + else transform_config + ) + node = FlinkTransformationNode( + f"{view.name}:transform", + transformation_fn, + self.table_env, + self.split_num, + inputs=input_nodes, + ) + self.nodes.append(node) + return node + + def build_output_nodes(self, view: Any, input_node: DAGNode) -> FlinkOutputNode: + node = FlinkOutputNode( + f"{view.name}:output", + self.dag_root.view, + self.table_env, + self.split_num, + isinstance(self.task, MaterializationTask), + [input_node], + ) + self.nodes.append(node) + return node + + def build_validation_node( + self, view: Any, input_node: DAGNode + ) -> FlinkValidationNode: + expected_columns = {} + json_columns: set[str] = set() + if hasattr(view, "features"): + for feature in view.features: + try: + expected_columns[feature.name] = from_feast_to_pyarrow_type( + feature.dtype + ) + except (ValueError, KeyError): + logger.debug( + "Could not resolve PyArrow type for feature '%s' " + "(dtype=%s), skipping type check for this column.", + feature.name, + feature.dtype, + ) + expected_columns[feature.name] = None + if ( + isinstance(feature.dtype, PrimitiveFeastType) + and feature.dtype.name == "JSON" + ): + json_columns.add(feature.name) + + node = FlinkValidationNode( + f"{view.name}:validate", + expected_columns, + json_columns, + self.table_env, + self.split_num, + inputs=[input_node], + ) + self.nodes.append(node) + return node diff --git a/sdk/python/feast/infra/compute_engines/flink/job.py b/sdk/python/feast/infra/compute_engines/flink/job.py new file mode 100644 index 00000000000..45e80df5506 --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/job.py @@ -0,0 +1,124 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import List, Optional + +import pandas as pd +import pyarrow as pa + +from feast.infra.common.materialization_job import ( + MaterializationJob, + MaterializationJobStatus, +) +from feast.infra.compute_engines.dag.context import ExecutionContext +from feast.infra.compute_engines.dag.plan import ExecutionPlan +from feast.infra.compute_engines.flink.utils import ( + cleanup_flink_temporary_views, + flink_table_to_arrow, +) +from feast.infra.offline_stores.offline_store import RetrievalJob, RetrievalMetadata +from feast.on_demand_feature_view import OnDemandFeatureView +from feast.saved_dataset import SavedDatasetStorage + + +class FlinkDAGRetrievalJob(RetrievalJob): + def __init__( + self, + plan: Optional[ExecutionPlan], + context: ExecutionContext, + table_env: object, + full_feature_names: bool, + on_demand_feature_views: Optional[List[OnDemandFeatureView]] = None, + metadata: Optional[RetrievalMetadata] = None, + error: Optional[BaseException] = None, + ) -> None: + self._plan = plan + self._context = context + self._table_env = table_env + self._full_feature_names = full_feature_names + self._on_demand_feature_views = on_demand_feature_views or [] + self._metadata = metadata + self._error = error + self._arrow_table: Optional[pa.Table] = None + + def error(self) -> Optional[BaseException]: + return self._error + + def _ensure_executed(self) -> None: + if self._arrow_table is None: + if self._error is not None: + raise self._error + if self._plan is None: + raise RuntimeError("Execution plan is not set") + try: + result = self._plan.execute(self._context) + self._arrow_table = flink_table_to_arrow(result.data) + finally: + cleanup_flink_temporary_views(self._table_env) + + def _to_df_internal(self, timeout: Optional[int] = None) -> pd.DataFrame: + self._ensure_executed() + assert self._arrow_table is not None + return self._arrow_table.to_pandas() + + def _to_arrow_internal(self, timeout: Optional[int] = None) -> pa.Table: + self._ensure_executed() + assert self._arrow_table is not None + return self._arrow_table + + @property + def full_feature_names(self) -> bool: + return self._full_feature_names + + @property + def on_demand_feature_views(self) -> List[OnDemandFeatureView]: + return self._on_demand_feature_views + + @property + def metadata(self) -> Optional[RetrievalMetadata]: + return self._metadata + + def persist( + self, + storage: SavedDatasetStorage, + allow_overwrite: bool = False, + timeout: Optional[int] = None, + ) -> None: + raise NotImplementedError("Persisting Flink retrieval jobs is not supported.") + + def to_remote_storage(self) -> List[str]: + raise NotImplementedError( + "Remote storage is not supported in FlinkDAGRetrievalJob." + ) + + def to_sql(self) -> str: + raise NotImplementedError("SQL generation is not supported for Flink DAGs.") + + +@dataclass +class FlinkMaterializationJob(MaterializationJob): + def __init__( + self, + job_id: str, + status: MaterializationJobStatus, + error: Optional[BaseException] = None, + ) -> None: + super().__init__() + self._job_id = job_id + self._status = status + self._error = error + + def status(self) -> MaterializationJobStatus: + return self._status + + def error(self) -> Optional[BaseException]: + return self._error + + def should_be_retried(self) -> bool: + return False + + def job_id(self) -> str: + return self._job_id + + def url(self) -> Optional[str]: + return None diff --git a/sdk/python/feast/infra/compute_engines/flink/nodes.py b/sdk/python/feast/infra/compute_engines/flink/nodes.py new file mode 100644 index 00000000000..2bdb29cd8c4 --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/nodes.py @@ -0,0 +1,816 @@ +from __future__ import annotations + +import logging +import uuid +from datetime import datetime, timedelta +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Union + +import pandas as pd +import pyarrow as pa + +from feast import BatchFeatureView, FeatureView, StreamFeatureView +from feast.aggregation import Aggregation, aggregation_specs_to_agg_ops +from feast.data_source import DataSource +from feast.infra.compute_engines.dag.context import ColumnInfo, ExecutionContext +from feast.infra.compute_engines.dag.model import DAGFormat +from feast.infra.compute_engines.dag.node import DAGNode +from feast.infra.compute_engines.dag.value import DAGValue +from feast.infra.compute_engines.flink.utils import ( + flink_table_to_arrow_batches, + pandas_to_flink_table, + register_flink_temporary_view, +) +from feast.infra.compute_engines.utils import ( + ENTITY_ROW_ID, + ENTITY_TS_ALIAS, + create_offline_store_retrieval_job, + find_entity_timestamp_column, + infer_entity_timestamp_column, +) +from feast.utils import _convert_arrow_to_proto + +logger = logging.getLogger(__name__) + +DEDUP_ROW_NUMBER = "__feast_row_number" + + +def _quote_identifier(identifier: str) -> str: + return f"`{identifier.replace('`', '``')}`" + + +def _qualified_column(alias: str, column: str) -> str: + return f"{alias}.{_quote_identifier(column)}" + + +def _select_column(alias: str, column: str, output_name: Optional[str] = None) -> str: + expr = _qualified_column(alias, column) + if output_name and output_name != column: + return f"{expr} AS {_quote_identifier(output_name)}" + return expr + + +def _flink_interval_literals(value: timedelta) -> List[str]: + total_seconds = int(value.total_seconds()) + if total_seconds <= 0: + return ["INTERVAL '0' SECOND"] + + days, remainder = divmod(total_seconds, 24 * 60 * 60) + hours, remainder = divmod(remainder, 60 * 60) + minutes, seconds = divmod(remainder, 60) + parts: List[str] = [] + if days: + parts.append(f"INTERVAL '{days}' DAY") + if hours: + parts.append(f"INTERVAL '{hours}' HOUR") + if minutes: + parts.append(f"INTERVAL '{minutes}' MINUTE") + if seconds: + parts.append(f"INTERVAL '{seconds}' SECOND") + return parts + + +def _subtract_flink_intervals(timestamp_expr: str, value: timedelta) -> str: + result = timestamp_expr + for interval in _flink_interval_literals(value): + result = f"{result} - {interval}" + return result + + +def _get_columns_from_schema(table: Any) -> Optional[List[str]]: + if not hasattr(table, "get_schema"): + return None + schema = table.get_schema() + if hasattr(schema, "get_field_names"): + return list(schema.get_field_names()) + if hasattr(schema, "get_field_count") and hasattr(schema, "get_field_name"): + return [schema.get_field_name(i) for i in range(schema.get_field_count())] + return None + + +def _get_columns(value: DAGValue) -> List[str]: + metadata_columns = value.metadata.get("columns") if value.metadata else None + if metadata_columns: + return list(metadata_columns) + schema_columns = _get_columns_from_schema(value.data) + if schema_columns: + return schema_columns + raise ValueError( + "Could not infer columns for Flink DAG value from metadata or PyFlink schema." + ) + + +def _can_use_sql(table_env: Any) -> bool: + return hasattr(table_env, "create_temporary_view") and hasattr( + table_env, "sql_query" + ) + + +def _require_sql(table_env: Any, node_name: str) -> None: + if not _can_use_sql(table_env): + raise RuntimeError( + f"Flink node '{node_name}' requires a PyFlink TableEnvironment with " + "create_temporary_view() and sql_query()." + ) + + +def _register_table(table_env: Any, table: Any, prefix: str) -> str: + view_name = f"__feast_{prefix}_{uuid.uuid4().hex}" + table_env.create_temporary_view(view_name, table) + register_flink_temporary_view(table_env, view_name) + return view_name + + +def _sql_value( + table_env: Any, + query: str, + columns: Iterable[str], + metadata: Optional[dict] = None, +) -> DAGValue: + return DAGValue( + data=table_env.sql_query(query), + format=DAGFormat.FLINK, + metadata={**(metadata or {}), "columns": list(columns), "native_sql": query}, + ) + + +def _entity_timestamp_column_from_columns(columns: List[str]) -> str: + entity_ts_col = find_entity_timestamp_column(columns) + if entity_ts_col: + return entity_ts_col + raise ValueError( + "SQL-based entity_df for FlinkComputeEngine must select an " + "`event_timestamp` column." + ) + + +def _entity_value_from_dataframe( + table_env: Any, + entity_df: pd.DataFrame, + split_num: int, + join_keys: List[str], +) -> tuple[Any, List[str], str]: + entity_df = entity_df.copy() + if entity_df.empty: + for join_key in join_keys: + if join_key not in entity_df.columns: + entity_df[join_key] = pd.Series(dtype="object") + entity_ts_col = find_entity_timestamp_column(list(entity_df.columns)) + if entity_ts_col is None: + entity_ts_col = ENTITY_TS_ALIAS + entity_df[entity_ts_col] = pd.Series(dtype="datetime64[ns]") + else: + entity_schema = dict(zip(entity_df.columns, entity_df.dtypes)) + entity_ts_col = infer_entity_timestamp_column(entity_schema) + + entity_df[ENTITY_ROW_ID] = range(len(entity_df)) + if entity_ts_col != ENTITY_TS_ALIAS: + entity_df = entity_df.rename(columns={entity_ts_col: ENTITY_TS_ALIAS}) + return ( + pandas_to_flink_table(table_env, entity_df, split_num), + list(entity_df.columns), + entity_ts_col, + ) + + +def _entity_value_from_sql( + table_env: Any, + entity_sql: str, + join_keys: List[str], +) -> tuple[Any, List[str], str]: + _require_sql(table_env, "entity_df") + entity_table = table_env.sql_query(entity_sql) + entity_columns = _get_columns_from_schema(entity_table) + if entity_columns is None: + raise ValueError("Could not infer columns for SQL-based entity_df.") + + entity_ts_col = _entity_timestamp_column_from_columns(entity_columns) + entity_view = _register_table(table_env, entity_table, "entity_sql") + output_columns = [ + ENTITY_TS_ALIAS if column == entity_ts_col else column + for column in entity_columns + ] + select_exprs = [ + _select_column( + "entity_src", + column, + ENTITY_TS_ALIAS if column == entity_ts_col else column, + ) + for column in entity_columns + ] + order_columns = [ + column for column in [entity_ts_col, *join_keys] if column in entity_columns + ] + order_expr = ", ".join( + _qualified_column("entity_src", col) for col in order_columns + ) + if not order_expr: + order_expr = _qualified_column("entity_src", entity_columns[0]) + select_exprs.append( + f"ROW_NUMBER() OVER (ORDER BY {order_expr}) - 1 AS " + f"{_quote_identifier(ENTITY_ROW_ID)}" + ) + query = ( + f"SELECT {', '.join(select_exprs)} " + f"FROM {_quote_identifier(entity_view)} AS entity_src" + ) + output_columns.append(ENTITY_ROW_ID) + value = _sql_value( + table_env, + query, + output_columns, + metadata={"entity_timestamp_column": entity_ts_col}, + ) + return value.data, output_columns, entity_ts_col + + +def _entity_value_from_context( + table_env: Any, + context: ExecutionContext, + split_num: int, + join_keys: List[str], +) -> tuple[Any, List[str], str]: + if isinstance(context.entity_df, pd.DataFrame): + return _entity_value_from_dataframe( + table_env, context.entity_df, split_num, join_keys + ) + if isinstance(context.entity_df, str): + return _entity_value_from_sql(table_env, context.entity_df, join_keys) + raise TypeError( + "FlinkComputeEngine entity_df must be a pandas DataFrame, SQL string, or None." + ) + + +def _retrieval_job_to_flink_table( + retrieval_job: Any, + table_env: Any, + split_num: int, +) -> tuple[Any, List[str]]: + to_flink_table = getattr(retrieval_job, "to_flink_table", None) + if callable(to_flink_table): + flink_table = to_flink_table(table_env) + columns = _get_columns_from_schema(flink_table) + if columns is None: + raise ValueError( + "Could not infer columns for source Flink table returned by " + "RetrievalJob.to_flink_table(table_env)." + ) + return flink_table, columns + + if not hasattr(retrieval_job, "to_arrow"): + raise TypeError( + "FlinkComputeEngine source reads require a RetrievalJob with either " + "to_flink_table(table_env) or to_arrow()." + ) + + arrow_table = retrieval_job.to_arrow() + if not isinstance(arrow_table, pa.Table): + raise TypeError( + "RetrievalJob.to_arrow() must return a pyarrow.Table for " + "FlinkComputeEngine source reads." + ) + columns = list(arrow_table.column_names) + return pandas_to_flink_table(table_env, arrow_table.to_pandas(), split_num), columns + + +class FlinkSourceReadNode(DAGNode): + def __init__( + self, + name: str, + source: DataSource, + column_info: ColumnInfo, + table_env: Any, + split_num: int, + start_time: Optional[datetime] = None, + end_time: Optional[datetime] = None, + ) -> None: + super().__init__(name) + self.source = source + self.column_info = column_info + self.table_env = table_env + self.split_num = split_num + self.start_time = start_time + self.end_time = end_time + + def execute(self, context: ExecutionContext) -> DAGValue: + retrieval_job = create_offline_store_retrieval_job( + data_source=self.source, + column_info=self.column_info, + context=context, + start_time=self.start_time, + end_time=self.end_time, + ) + flink_table, columns = _retrieval_job_to_flink_table( + retrieval_job, self.table_env, self.split_num + ) + + if self.column_info.field_mapping: + view_name = _register_table(self.table_env, flink_table, "source_read") + select_exprs = [ + _select_column( + "src", + col, + self.column_info.field_mapping.get(col, col), + ) + for col in columns + ] + renamed_columns = [ + self.column_info.field_mapping.get(col, col) for col in columns + ] + query = ( + f"SELECT {', '.join(select_exprs)} " + f"FROM {_quote_identifier(view_name)} AS src" + ) + return _sql_value( + self.table_env, + query, + renamed_columns, + metadata={ + "source": "feature_view_batch_source", + "timestamp_field": self.column_info.timestamp_column, + "created_timestamp_column": ( + self.column_info.created_timestamp_column + ), + "start_date": self.start_time, + "end_date": self.end_time, + }, + ) + + return DAGValue( + data=flink_table, + format=DAGFormat.FLINK, + metadata={ + "source": "feature_view_batch_source", + "timestamp_field": self.column_info.timestamp_column, + "created_timestamp_column": (self.column_info.created_timestamp_column), + "start_date": self.start_time, + "end_date": self.end_time, + "columns": columns, + }, + ) + + +class FlinkJoinNode(DAGNode): + def __init__( + self, + name: str, + column_info: ColumnInfo, + table_env: Any, + split_num: int, + inputs: Optional[List[DAGNode]] = None, + how: str = "left", + ) -> None: + super().__init__(name, inputs=inputs or []) + self.column_info = column_info + self.table_env = table_env + self.split_num = split_num + self.how = how + + def execute(self, context: ExecutionContext) -> DAGValue: + input_values = self.get_input_values(context) + for value in input_values: + value.assert_format(DAGFormat.FLINK) + if not input_values: + raise RuntimeError(f"FlinkJoinNode '{self.name}' requires inputs") + + _require_sql(self.table_env, self.name) + return self._execute_sql_join(input_values, context) + + def _execute_sql_join( + self, input_values: List[DAGValue], context: ExecutionContext + ) -> DAGValue: + join_keys = self.column_info.join_keys_columns + view_names = [ + _register_table(self.table_env, value.data, f"join_{index}") + for index, value in enumerate(input_values) + ] + columns_by_input = [_get_columns(value) for value in input_values] + output_columns = list(columns_by_input[0]) + seen_columns = set(output_columns) + select_exprs = [_select_column("t0", column) for column in columns_by_input[0]] + + joins = [] + for index, view_name in enumerate(view_names[1:], start=1): + alias = f"t{index}" + on_clause = " AND ".join( + f"{_qualified_column('t0', key)} = {_qualified_column(alias, key)}" + for key in join_keys + ) + joins.append( + f"{self.how.upper()} JOIN {_quote_identifier(view_name)} AS {alias} " + f"ON {on_clause}" + ) + for column in columns_by_input[index]: + if column in join_keys or column in seen_columns: + continue + output_columns.append(column) + seen_columns.add(column) + select_exprs.append(_select_column(alias, column)) + + query = ( + f"SELECT {', '.join(select_exprs)} " + f"FROM {_quote_identifier(view_names[0])} AS t0 " + f"{' '.join(joins)}" + ) + joined_value = _sql_value( + self.table_env, + query, + output_columns, + metadata={"joined_on": join_keys, "join_type": self.how}, + ) + + if context.entity_df is None: + return joined_value + + entity_table, entity_columns, entity_ts_col = _entity_value_from_context( + self.table_env, context, self.split_num, join_keys + ) + entity_view = _register_table(self.table_env, entity_table, "entity") + feature_view = _register_table(self.table_env, joined_value.data, "features") + feature_columns = [ + column + for column in output_columns + if column not in join_keys and column not in entity_columns + ] + select_entity = [_select_column("e", column) for column in entity_columns] + select_features = [_select_column("f", column) for column in feature_columns] + on_clause = " AND ".join( + f"{_qualified_column('e', key)} = {_qualified_column('f', key)}" + for key in join_keys + ) + entity_join_query = ( + f"SELECT {', '.join(select_entity + select_features)} " + f"FROM {_quote_identifier(entity_view)} AS e " + f"LEFT JOIN {_quote_identifier(feature_view)} AS f ON {on_clause}" + ) + return _sql_value( + self.table_env, + entity_join_query, + entity_columns + feature_columns, + metadata={ + "joined_on": join_keys, + "join_type": "left", + "entity_timestamp_column": entity_ts_col, + }, + ) + + +class FlinkFilterNode(DAGNode): + def __init__( + self, + name: str, + column_info: ColumnInfo, + table_env: Any, + split_num: int, + filter_expr: Optional[str] = None, + ttl: Optional[timedelta] = None, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.column_info = column_info + self.table_env = table_env + self.split_num = split_num + self.filter_expr = filter_expr + self.ttl = ttl + + def execute(self, context: ExecutionContext) -> DAGValue: + input_value = self.get_single_input_value(context) + input_value.assert_format(DAGFormat.FLINK) + + _require_sql(self.table_env, self.name) + return self._execute_sql_filter(input_value) + + def _execute_sql_filter(self, input_value: DAGValue) -> DAGValue: + columns = _get_columns(input_value) + timestamp_column = self.column_info.timestamp_column + conditions = [] + + if ENTITY_TS_ALIAS in columns and timestamp_column in columns: + conditions.append( + f"{_quote_identifier(timestamp_column)} <= " + f"{_quote_identifier(ENTITY_TS_ALIAS)}" + ) + if self.ttl: + lower_bound = _subtract_flink_intervals( + _quote_identifier(ENTITY_TS_ALIAS), self.ttl + ) + conditions.append( + f"{_quote_identifier(timestamp_column)} >= {lower_bound}" + ) + + if self.filter_expr: + conditions.append(f"({self.filter_expr})") + + if not conditions: + return input_value + + view_name = _register_table(self.table_env, input_value.data, "filter") + query = ( + f"SELECT * FROM {_quote_identifier(view_name)} " + f"WHERE {' AND '.join(conditions)}" + ) + return _sql_value( + self.table_env, + query, + columns, + metadata={**(input_value.metadata or {}), "filter_applied": True}, + ) + + +class FlinkAggregationNode(DAGNode): + def __init__( + self, + name: str, + group_keys: List[str], + aggregations: List[Aggregation], + table_env: Any, + split_num: int, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.group_keys = group_keys + self.aggregations = aggregations + self.table_env = table_env + self.split_num = split_num + + def execute(self, context: ExecutionContext) -> DAGValue: + agg_ops = aggregation_specs_to_agg_ops( + self.aggregations, + time_window_unsupported_error_message=( + "Time window aggregation is not yet supported in the Flink compute " + "engine. Use non-windowed aggregations or pre-window upstream in Flink." + ), + ) + input_value = self.get_single_input_value(context) + input_value.assert_format(DAGFormat.FLINK) + + _require_sql(self.table_env, self.name) + return self._execute_sql_aggregation(input_value, agg_ops) + + def _execute_sql_aggregation( + self, input_value: DAGValue, agg_ops: Dict[str, tuple[str, str]] + ) -> DAGValue: + view_name = _register_table(self.table_env, input_value.data, "aggregate") + select_exprs = [_quote_identifier(key) for key in self.group_keys] + for alias, (function, column) in agg_ops.items(): + sql_function = { + "mean": "AVG", + "avg": "AVG", + "sum": "SUM", + "min": "MIN", + "max": "MAX", + "count": "COUNT", + "nunique": "COUNT_DISTINCT", + "std": "STDDEV_SAMP", + "var": "VAR_SAMP", + }.get(function, function.upper()) + if sql_function == "COUNT_DISTINCT": + expr = ( + f"COUNT(DISTINCT {_quote_identifier(column)}) " + f"AS {_quote_identifier(alias)}" + ) + else: + expr = ( + f"{sql_function}({_quote_identifier(column)}) " + f"AS {_quote_identifier(alias)}" + ) + select_exprs.append(expr) + + query = ( + f"SELECT {', '.join(select_exprs)} " + f"FROM {_quote_identifier(view_name)} " + f"GROUP BY {', '.join(_quote_identifier(key) for key in self.group_keys)}" + ) + return _sql_value( + self.table_env, + query, + [*self.group_keys, *agg_ops.keys()], + metadata={"aggregated": True}, + ) + + +class FlinkDedupNode(DAGNode): + def __init__( + self, + name: str, + column_info: ColumnInfo, + table_env: Any, + split_num: int, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.column_info = column_info + self.table_env = table_env + self.split_num = split_num + + def execute(self, context: ExecutionContext) -> DAGValue: + input_value = self.get_single_input_value(context) + input_value.assert_format(DAGFormat.FLINK) + + _require_sql(self.table_env, self.name) + return self._execute_sql_dedup(input_value) + + def _execute_sql_dedup(self, input_value: DAGValue) -> DAGValue: + columns = _get_columns(input_value) + dedup_keys = ( + [ENTITY_ROW_ID] + if ENTITY_ROW_ID in columns + else self.column_info.join_keys_columns + ) + dedup_keys = [key for key in dedup_keys if key in columns] + if not dedup_keys: + return input_value + + order_columns = [ + self.column_info.timestamp_column, + self.column_info.created_timestamp_column, + ] + order_exprs = [ + f"{_quote_identifier(column)} DESC" + for column in order_columns + if column and column in columns + ] + if not order_exprs: + order_exprs = [f"{_quote_identifier(dedup_keys[0])} ASC"] + + view_name = _register_table(self.table_env, input_value.data, "dedup") + select_columns = ", ".join(_quote_identifier(column) for column in columns) + query = ( + f"SELECT {select_columns} FROM (" + f"SELECT *, ROW_NUMBER() OVER (" + f"PARTITION BY {', '.join(_quote_identifier(key) for key in dedup_keys)} " + f"ORDER BY {', '.join(order_exprs)}" + f") AS {_quote_identifier(DEDUP_ROW_NUMBER)} " + f"FROM {_quote_identifier(view_name)}" + f") WHERE {_quote_identifier(DEDUP_ROW_NUMBER)} = 1" + ) + return _sql_value( + self.table_env, + query, + columns, + metadata={**(input_value.metadata or {}), "deduped": True}, + ) + + +class FlinkTransformationNode(DAGNode): + def __init__( + self, + name: str, + transformation_fn: Callable[..., Any], + table_env: Any, + split_num: int, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.transformation_fn = transformation_fn + self.table_env = table_env + self.split_num = split_num + + def execute(self, context: ExecutionContext) -> DAGValue: + input_values = self.get_input_values(context) + for value in input_values: + value.assert_format(DAGFormat.FLINK) + + input_tables = [value.data for value in input_values] + transformed = self.transformation_fn(*input_tables) + + columns = _get_columns_from_schema(transformed) + if columns is None: + raise TypeError( + "Flink transformations must return a PyFlink Table with a schema." + ) + + return DAGValue( + data=transformed, + format=DAGFormat.FLINK, + metadata={"transformed": True, "columns": columns or []}, + ) + + +class FlinkValidationNode(DAGNode): + def __init__( + self, + name: str, + expected_columns: dict[str, Optional[pa.DataType]], + json_columns: Optional[Set[str]], + table_env: Any, + split_num: int, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.expected_columns = expected_columns + self.json_columns = json_columns or set() + self.table_env = table_env + self.split_num = split_num + + def execute(self, context: ExecutionContext) -> DAGValue: + input_value = self.get_single_input_value(context) + input_value.assert_format(DAGFormat.FLINK) + + columns = _get_columns(input_value) + missing = set(self.expected_columns.keys()) - set(columns) + if missing: + raise ValueError( + f"[Validation: {self.name}] Missing expected columns: {missing}. " + f"Actual columns: {sorted(columns)}" + ) + if not self.json_columns: + return DAGValue( + data=input_value.data, + format=DAGFormat.FLINK, + metadata={**(input_value.metadata or {}), "validated": True}, + ) + + raise NotImplementedError( + "JSON value validation is not supported by FlinkComputeEngine without " + "collecting data out of Flink. Validate JSON upstream in Flink SQL or " + "disable JSON validation for this FeatureView." + ) + + +class FlinkOutputNode(DAGNode): + def __init__( + self, + name: str, + feature_view: Union[BatchFeatureView, FeatureView, StreamFeatureView], + table_env: Any, + split_num: int, + write_output: bool, + inputs: Optional[List[DAGNode]] = None, + ) -> None: + super().__init__(name, inputs=inputs) + self.feature_view = feature_view + self.table_env = table_env + self.split_num = split_num + self.write_output = write_output + + def execute(self, context: ExecutionContext) -> DAGValue: + input_value = self.get_single_input_value(context) + input_value.assert_format(DAGFormat.FLINK) + output_value = self._drop_internal_columns(input_value) + output_table = output_value.data + if not self.write_output: + return output_value + + columns = _get_columns(output_value) + batch_size = context.repo_config.materialization_config.online_write_batch_size + if self.feature_view.online: + join_key_to_value_type = { + entity.name: entity.dtype.to_value_type() + for entity in self.feature_view.entity_columns + } + else: + join_key_to_value_type = {} + + for output_arrow in flink_table_to_arrow_batches( + output_table, + columns, + batch_size, + ): + if output_arrow.num_rows == 0: + continue + + if self.feature_view.online: + arrow_batches = ( + [output_arrow] + if batch_size is None + else output_arrow.to_batches(max_chunksize=batch_size) + ) + for batch in arrow_batches: + rows_to_write = _convert_arrow_to_proto( + batch, self.feature_view, join_key_to_value_type + ) + context.online_store.online_write_batch( + config=context.repo_config, + table=self.feature_view, + data=rows_to_write, + progress=lambda x: None, + ) + + if self.feature_view.offline: + context.offline_store.offline_write_batch( + config=context.repo_config, + feature_view=self.feature_view, + table=output_arrow, + progress=lambda x: None, + ) + + return output_value + + def _drop_internal_columns(self, input_value: DAGValue) -> DAGValue: + columns = _get_columns(input_value) + output_columns = [column for column in columns if column != ENTITY_ROW_ID] + if output_columns == columns: + return input_value + + _require_sql(self.table_env, self.name) + view_name = _register_table(self.table_env, input_value.data, "output") + query = ( + f"SELECT {', '.join(_quote_identifier(column) for column in output_columns)} " + f"FROM {_quote_identifier(view_name)}" + ) + return _sql_value( + self.table_env, + query, + output_columns, + metadata={**(input_value.metadata or {}), "output_cleaned": True}, + ) diff --git a/sdk/python/feast/infra/compute_engines/flink/utils.py b/sdk/python/feast/infra/compute_engines/flink/utils.py new file mode 100644 index 00000000000..f271e8bb113 --- /dev/null +++ b/sdk/python/feast/infra/compute_engines/flink/utils.py @@ -0,0 +1,218 @@ +from __future__ import annotations + +import logging +from datetime import date, datetime +from decimal import Decimal +from typing import TYPE_CHECKING, Any, Iterator, Optional + +import pandas as pd +import pyarrow as pa + +if TYPE_CHECKING: + from feast.infra.compute_engines.flink.compute import FlinkComputeEngineConfig + +logger = logging.getLogger(__name__) + +DEFAULT_FLINK_RESULT_BATCH_SIZE = 10_000 +_TEMP_VIEW_REGISTRY: dict[int, set[str]] = {} + + +def create_flink_table_environment(config: FlinkComputeEngineConfig) -> Any: + """Create a PyFlink TableEnvironment from Feast engine config.""" + try: + from pyflink.common import Configuration + from pyflink.table import EnvironmentSettings, TableEnvironment + except ImportError as exc: + raise ImportError( + "FlinkComputeEngine requires PyFlink. Install the `flink` extra with " + "uv from a Feast source checkout, or otherwise make the `pyflink` " + "package available to Feast." + ) from exc + + flink_conf = Configuration() + for key, value in (config.table_config or {}).items(): + flink_conf.set_string(key, value) + if config.parallelism is not None: + flink_conf.set_string("parallelism.default", str(config.parallelism)) + + builder = EnvironmentSettings.new_instance().with_configuration(flink_conf) + if config.execution_mode == "streaming": + builder = builder.in_streaming_mode() + else: + builder = builder.in_batch_mode() + return TableEnvironment.create(builder.build()) + + +def pandas_to_flink_table(table_env: Any, df: pd.DataFrame, split_num: int = 1) -> Any: + """Convert a pandas DataFrame to a PyFlink table.""" + schema = _build_pandas_flink_schema(df) + kwargs: dict[str, Any] = {"splits_num": split_num} + if schema is not None: + kwargs["schema"] = schema + return table_env.from_pandas(df, **kwargs) + + +def flink_table_to_pandas(table: Any) -> pd.DataFrame: + """Collect a PyFlink table into pandas.""" + if hasattr(table, "to_pandas"): + return table.to_pandas() + raise TypeError(f"Expected a PyFlink table, got {type(table)}") + + +def flink_table_to_arrow(table: Any) -> pa.Table: + """Collect a PyFlink table into Arrow.""" + value = flink_table_to_pandas(table) + return pa.Table.from_pandas(value) + + +def flink_table_to_arrow_batches( + table: Any, + columns: list[str], + batch_size: Optional[int], +) -> Iterator[pa.Table]: + """Stream a PyFlink table into Arrow tables without collecting it all first.""" + effective_batch_size = batch_size or DEFAULT_FLINK_RESULT_BATCH_SIZE + if effective_batch_size <= 0: + raise ValueError("Flink result batch size must be positive.") + + if hasattr(table, "execute"): + rows: list[dict[str, Any]] = [] + row_iterator = table.execute().collect() + try: + for row in row_iterator: + rows.append(_row_to_dict(row, columns)) + if len(rows) >= effective_batch_size: + yield _rows_to_arrow(rows, columns) + rows = [] + if rows: + yield _rows_to_arrow(rows, columns) + finally: + close = getattr(row_iterator, "close", None) + if callable(close): + close() + return + + if hasattr(table, "to_pandas"): + # Used by unit-test fakes and other table-like objects. Real PyFlink tables use + # the execute().collect() path above. + df = table.to_pandas() + for start in range(0, len(df), effective_batch_size): + yield pa.Table.from_pandas( + df.iloc[start : start + effective_batch_size], + preserve_index=False, + ) + return + + raise TypeError(f"Expected a PyFlink table, got {type(table)}") + + +def register_flink_temporary_view(table_env: Any, view_name: str) -> None: + """Track Feast-created temporary views so long-lived table envs can clean up.""" + views = _temporary_views_for_env(table_env) + views.add(view_name) + + +def cleanup_flink_temporary_views(table_env: Any) -> None: + """Drop Feast-created temporary views from a PyFlink TableEnvironment.""" + views = _temporary_views_for_env(table_env) + if not views: + return + + drop_view = getattr(table_env, "drop_temporary_view", None) + if not callable(drop_view): + return + + for view_name in list(views): + try: + drop_view(view_name) + except Exception as exc: + logger.debug("Failed to drop Flink temporary view %s: %s", view_name, exc) + finally: + views.discard(view_name) + if not views: + _TEMP_VIEW_REGISTRY.pop(id(table_env), None) + + +def _build_pandas_flink_schema(df: pd.DataFrame) -> Any: + try: + from pyflink.table import Schema + except ImportError: + return None + + builder = Schema.new_builder() + for column in df.columns: + builder.column(str(column), _pandas_dtype_to_flink_type(df[column])) + return builder.build() + + +def _pandas_dtype_to_flink_type(series: pd.Series) -> Any: + from pyflink.table import DataTypes + + dtype = series.dtype + if pd.api.types.is_bool_dtype(dtype): + return DataTypes.BOOLEAN() + if pd.api.types.is_integer_dtype(dtype): + dtype_name = str(dtype).lower() + if dtype_name.endswith("int8"): + return DataTypes.TINYINT() + if dtype_name.endswith("int16"): + return DataTypes.SMALLINT() + if dtype_name.endswith("int32"): + return DataTypes.INT() + return DataTypes.BIGINT() + if pd.api.types.is_float_dtype(dtype): + return DataTypes.FLOAT() if str(dtype) == "float32" else DataTypes.DOUBLE() + if pd.api.types.is_datetime64_any_dtype(dtype): + if getattr(dtype, "tz", None) is not None: + return DataTypes.TIMESTAMP_LTZ(3) + return DataTypes.TIMESTAMP(3) + if pd.api.types.is_timedelta64_dtype(dtype): + return DataTypes.BIGINT() + + sample = _first_non_null_value(series) + if isinstance(sample, (bytes, bytearray)): + return DataTypes.BYTES() + if isinstance(sample, date) and not isinstance(sample, datetime): + return DataTypes.DATE() + if isinstance(sample, Decimal): + return DataTypes.DECIMAL(38, 18) + return DataTypes.STRING() + + +def _first_non_null_value(series: pd.Series) -> Any: + for value in series: + if pd.notna(value): + return value + return None + + +def _row_to_dict(row: Any, columns: list[str]) -> dict[str, Any]: + if isinstance(row, dict): + return {column: row.get(column) for column in columns} + + as_dict = getattr(row, "as_dict", None) + if callable(as_dict): + row_dict = as_dict() + if row_dict: + return {column: row_dict.get(column) for column in columns} + + values = list(row) + return dict(zip(columns, values)) + + +def _rows_to_arrow(rows: list[dict[str, Any]], columns: list[str]) -> pa.Table: + df = pd.DataFrame.from_records(rows, columns=columns) + return pa.Table.from_pandas(df, preserve_index=False) + + +def _temporary_views_for_env(table_env: Any) -> set[str]: + views = getattr(table_env, "_feast_temporary_views", None) + if isinstance(views, set): + return views + + views = _TEMP_VIEW_REGISTRY.setdefault(id(table_env), set()) + try: + setattr(table_env, "_feast_temporary_views", views) + except Exception: + pass + return views diff --git a/sdk/python/feast/infra/compute_engines/local/nodes.py b/sdk/python/feast/infra/compute_engines/local/nodes.py index db65761a5e2..9d3e1a48881 100644 --- a/sdk/python/feast/infra/compute_engines/local/nodes.py +++ b/sdk/python/feast/infra/compute_engines/local/nodes.py @@ -14,17 +14,14 @@ from feast.infra.compute_engines.local.arrow_table_value import ArrowTableValue from feast.infra.compute_engines.local.local_node import LocalNode from feast.infra.compute_engines.utils import ( + ENTITY_TS_ALIAS, create_offline_store_retrieval_job, -) -from feast.infra.offline_stores.offline_utils import ( - infer_event_timestamp_from_entity_df, + infer_entity_timestamp_column, ) from feast.utils import _convert_arrow_to_proto logger = logging.getLogger(__name__) -ENTITY_TS_ALIAS = "__entity_event_timestamp" - class LocalSourceReadNode(LocalNode): def __init__( @@ -79,6 +76,10 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: for val in input_values: val.assert_format(DAGFormat.ARROW) + # The upstream source-read node has already renamed columns via + # field_mapping, so use the mapped join keys for joining (see #5942). + join_keys = self.column_info.join_keys_columns + # Convert all upstream ArrowTables to backend DataFrames joined_df = self.backend.from_arrow(input_values[0].data) for val in input_values[1:]: @@ -86,7 +87,7 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: joined_df = self.backend.join( joined_df, next_df, - on=self.column_info.join_keys, + on=join_keys, how=self.how, ) @@ -95,7 +96,7 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: entity_df = self.backend.from_arrow(pa.Table.from_pandas(context.entity_df)) entity_schema = dict(zip(entity_df.columns, entity_df.dtypes)) - entity_ts_col = infer_event_timestamp_from_entity_df(entity_schema) + entity_ts_col = infer_entity_timestamp_column(entity_schema) if entity_ts_col != ENTITY_TS_ALIAS: entity_df = self.backend.rename_columns( @@ -105,7 +106,7 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: joined_df = self.backend.join( entity_df, joined_df, - on=self.column_info.join_keys, + on=join_keys, how="left", ) @@ -193,8 +194,10 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: # Extract join_keys, timestamp, and created_ts from context - # Dedup strategy: sort and drop_duplicates - dedup_keys = self.column_info.join_keys + # Dedup strategy: sort and drop_duplicates. Use the mapped join key + # names so we look up the columns that the source-read node has + # already renamed (see issue #5942). + dedup_keys = self.column_info.join_keys_columns if dedup_keys: sort_keys = [self.column_info.timestamp_column] if ( @@ -361,10 +364,11 @@ def __init__( def execute(self, context: ExecutionContext) -> ArrowTableValue: input_table = self.get_single_table(context).data - context.node_outputs[self.name] = input_table + output = ArrowTableValue(data=input_table) + context.node_outputs[self.name] = output if input_table.num_rows == 0: - return input_table + return output if self.feature_view.online: online_store = context.online_store @@ -374,16 +378,25 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: for entity in self.feature_view.entity_columns } - rows_to_write = _convert_arrow_to_proto( - input_table, self.feature_view, join_key_to_value_type + batch_size = ( + context.repo_config.materialization_config.online_write_batch_size ) - - online_store.online_write_batch( - config=context.repo_config, - table=self.feature_view, - data=rows_to_write, - progress=lambda x: None, + # Single batch if None (backward compatible), otherwise use configured batch_size + batches = ( + [input_table] + if batch_size is None + else input_table.to_batches(max_chunksize=batch_size) ) + for batch in batches: + rows_to_write = _convert_arrow_to_proto( + batch, self.feature_view, join_key_to_value_type + ) + online_store.online_write_batch( + config=context.repo_config, + table=self.feature_view, + data=rows_to_write, + progress=lambda x: None, + ) if self.feature_view.offline: offline_store = context.offline_store @@ -394,4 +407,4 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue: progress=lambda x: None, ) - return input_table + return output diff --git a/sdk/python/feast/infra/compute_engines/ray/compute.py b/sdk/python/feast/infra/compute_engines/ray/compute.py index fa8f9747f3b..fb870f9c308 100644 --- a/sdk/python/feast/infra/compute_engines/ray/compute.py +++ b/sdk/python/feast/infra/compute_engines/ray/compute.py @@ -22,7 +22,10 @@ RayDAGRetrievalJob, RayMaterializationJob, ) -from feast.infra.compute_engines.ray.utils import write_to_online_store +from feast.infra.compute_engines.ray.utils import ( + write_to_online_store, + write_to_online_store_from_ray_ds, +) from feast.infra.offline_stores.offline_store import RetrievalJob from feast.infra.ray_initializer import ( ensure_ray_initialized, @@ -172,43 +175,93 @@ def _materialize_from_offline_store( end_date=end_date, ) - # Convert to Arrow Table and write to online/offline stores - arrow_table = retrieval_job.to_arrow() - - # Write to online store if enabled - write_to_online_store( - arrow_table=arrow_table, - feature_view=feature_view, - online_store=self.online_store, - repo_config=self.repo_config, + # Prefer the distributed Ray path: keep data on the cluster and + # write each partition in parallel. Fall back to the Arrow driver + # path for non-Ray retrieval jobs (e.g. Dask, DuckDB offline stores). + from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( + RayRetrievalJob, ) - # Write to offline store if enabled (this handles sink_source automatically for derived views) - if getattr(feature_view, "offline", False): - self.offline_store.offline_write_batch( - config=self.repo_config, + if isinstance(retrieval_job, RayRetrievalJob): + ray_ds = retrieval_job.to_ray_dataset() + + needs_offline = getattr(feature_view, "offline", False) + sink_source = getattr(feature_view, "sink_source", None) + + # Materialise the lazy pipeline ONCE into Ray object-store memory + # when more than one write target will consume it. + # Without this, each use of ray_ds (online write via map_batches, + # to_arrow_refs for offline_write_batch, write_parquet for + # sink_source) independently re-executes the full source-read + # pipeline, producing up to three separate data snapshots that can + # diverge when the source changes between executions. + if needs_offline or sink_source is not None: + ray_ds = ray_ds.materialize() + + # Distributed online store write — each Ray worker writes its shard + write_to_online_store_from_ray_ds( + ray_ds=ray_ds, feature_view=feature_view, - table=arrow_table, - progress=lambda x: None, + online_store=self.online_store, + repo_config=self.repo_config, ) - # For derived views, also ensure data is written to sink_source if it exists - # This is critical for feature view chaining to work properly - sink_source = getattr(feature_view, "sink_source", None) - if sink_source is not None: - logger.debug( - f"Writing derived view {feature_view.name} to sink_source: {sink_source.path}" + # offline_write_batch and sink_source are independent — both can + # apply when a feature view has offline=True AND a sink_source. + if needs_offline: + import pyarrow as pa + import ray as _ray + + arrow_table = pa.concat_tables(_ray.get(ray_ds.to_arrow_refs())) + self.offline_store.offline_write_batch( + config=self.repo_config, + feature_view=feature_view, + table=arrow_table, + progress=lambda x: None, + ) + + if sink_source is not None: + logger.debug( + f"Writing derived view {feature_view.name} to sink_source: {sink_source.path}" + ) + try: + ray_ds.write_parquet(sink_source.path) + except Exception as e: + logger.error( + f"Failed to write to sink_source {sink_source.path}: {e}" + ) + else: + # Non-Ray offline store: collect on driver and write sequentially + arrow_table = retrieval_job.to_arrow() + + write_to_online_store( + arrow_table=arrow_table, + feature_view=feature_view, + online_store=self.online_store, + repo_config=self.repo_config, ) - # Write to sink_source using Ray data - try: - ray_wrapper = get_ray_wrapper() - ray_dataset = ray_wrapper.from_arrow(arrow_table) - ray_dataset.write_parquet(sink_source.path) - except Exception as e: - logger.error( - f"Failed to write to sink_source {sink_source.path}: {e}" + if getattr(feature_view, "offline", False): + self.offline_store.offline_write_batch( + config=self.repo_config, + feature_view=feature_view, + table=arrow_table, + progress=lambda x: None, + ) + + sink_source = getattr(feature_view, "sink_source", None) + if sink_source is not None: + logger.debug( + f"Writing derived view {feature_view.name} to sink_source: {sink_source.path}" ) + try: + ray_wrapper = get_ray_wrapper() + ray_dataset = ray_wrapper.from_arrow(arrow_table) + ray_dataset.write_parquet(sink_source.path) + except Exception as e: + logger.error( + f"Failed to write to sink_source {sink_source.path}: {e}" + ) return RayMaterializationJob( job_id=job_id, status=MaterializationJobStatus.SUCCEEDED, diff --git a/sdk/python/feast/infra/compute_engines/ray/config.py b/sdk/python/feast/infra/compute_engines/ray/config.py index bb6b63a05c5..3e231f576ad 100644 --- a/sdk/python/feast/infra/compute_engines/ray/config.py +++ b/sdk/python/feast/infra/compute_engines/ray/config.py @@ -41,11 +41,69 @@ class RayComputeEngineConfig(FeastConfigBaseModel): # Additional configuration options max_workers: Optional[int] = None - """Maximum number of Ray workers. If None, uses all available cores.""" + """Maximum number of Ray workers for transformation and join nodes. + If None, Ray uses all available cores.""" + + write_concurrency: Optional[int] = None + """Concurrency for the RayWriteNode's map_batches call (online-store writes). + If None, falls back to max_workers, then 1 (safe default + for single-file stores). + + Example - SQLite online store (default for local deployments): + write_concurrency: 1 + + Example - Redis / DynamoDB online store (supports parallel writes): + write_concurrency: 8 + """ enable_optimization: bool = True """Enable automatic performance optimizations.""" + # Worker task resource configuration + num_gpus: Optional[float] = None + """Number of GPUs to request per worker task. Requires GPU nodes in the + Ray cluster. Fractional values (e.g. 0.5) are supported by Ray for GPU + sharing. Supported in all modes: local, remote, and KubeRay.""" + + gpu_batch_format: str = "pandas" + """Batch format for map_batches when num_gpus is set. Use 'numpy' or + 'pyarrow' for GPU-native libraries (e.g. cuDF, PyTorch). Defaults to + 'pandas'.""" + + worker_task_options: Optional[Dict[str, Any]] = None + """Arbitrary Ray task options passed verbatim to @ray.remote .options() + and map_batches for every worker task Feast dispatches. This is the + escape hatch for any Ray or CodeFlare SDK scheduling parameter not + covered by the dedicated fields above. + + Pairs with ray_conf (which configures ray.init) — worker_task_options + targets the individual worker tasks rather than the cluster connection. + + Common keys (see https://docs.ray.io/en/latest/ray-core/api/doc/ray.remote_function.RemoteFunction.options.html): + num_cpus (float) – CPUs per task (default: 1) + memory (int) – Heap memory in bytes (e.g. 8 * 1024**3 for 8 GB) + accelerator_type (str) – Specific GPU model, e.g. 'A100', 'T4', 'V100'. + Pins tasks to nodes advertising that type. Useful + on KubeRay clusters with mixed GPU pools. + resources (dict) – Custom/extended resource labels, e.g. + {'intel.com/gpu': 1} for Kubernetes extended resources. + runtime_env (dict) – Per-task runtime environment (pip, conda, env_vars, + working_dir, …). For KubeRay use this to install + extra packages on workers without rebuilding images. + max_retries (int) – Task retry count on worker failure (default: 3). + scheduling_strategy (str) – 'DEFAULT', 'SPREAD', or a placement group strategy. + + Example: + worker_task_options: + num_cpus: 4 + memory: 8589934592 # 8 GB + accelerator_type: "A100" + max_retries: 5 + runtime_env: + pip: ["cudf-cu12==24.10.0"] + env_vars: {CUDA_VISIBLE_DEVICES: "0"} + """ + @property def window_size_timedelta(self) -> timedelta: """Convert window size string to timedelta.""" diff --git a/sdk/python/feast/infra/compute_engines/ray/feature_builder.py b/sdk/python/feast/infra/compute_engines/ray/feature_builder.py index a9830162c1e..f0a26df263b 100644 --- a/sdk/python/feast/infra/compute_engines/ray/feature_builder.py +++ b/sdk/python/feast/infra/compute_engines/ray/feature_builder.py @@ -136,6 +136,7 @@ def build_dedup_node(self, view, input_node): name="dedup", column_info=column_info, config=self.config, + is_materialization=self.is_materialization, ) node.add_input(input_node) diff --git a/sdk/python/feast/infra/compute_engines/ray/nodes.py b/sdk/python/feast/infra/compute_engines/ray/nodes.py index c4eaa54d26a..edc6dafd5cd 100644 --- a/sdk/python/feast/infra/compute_engines/ray/nodes.py +++ b/sdk/python/feast/infra/compute_engines/ray/nodes.py @@ -1,7 +1,7 @@ import json import logging from datetime import datetime, timedelta, timezone -from typing import Dict, List, Optional, Set, Union +from typing import Any, Dict, List, Optional, Set, Union import dill import pandas as pd @@ -23,7 +23,10 @@ safe_batch_processor, write_to_online_store, ) -from feast.infra.compute_engines.utils import create_offline_store_retrieval_job +from feast.infra.compute_engines.utils import ( + ENTITY_TS_ALIAS, + create_offline_store_retrieval_job, +) from feast.infra.ray_initializer import get_ray_wrapper from feast.infra.ray_shared_utils import ( apply_field_mapping, @@ -33,9 +36,6 @@ logger = logging.getLogger(__name__) -# Entity timestamp alias for historical feature retrieval -ENTITY_TS_ALIAS = "__entity_event_timestamp" - class RayReadNode(DAGNode): """ @@ -477,6 +477,8 @@ def _execute_standard_aggregation(self, dataset: Dataset) -> DAGValue: agg_dict[feature_name] = (agg.column, "std") elif agg.function == "var": agg_dict[feature_name] = (agg.column, "var") + elif agg.function == "count_distinct": + agg_dict[feature_name] = (agg.column, "nunique") else: raise ValueError(f"Unknown aggregation function: {agg.function}.") @@ -531,6 +533,8 @@ def _fallback_pandas_aggregation(self, dataset: Dataset, agg_dict: dict) -> Data result = grouped[column].std() elif function == "var": result = grouped[column].var() + elif function == "nunique": + result = grouped[column].nunique() else: raise ValueError(f"Unknown aggregation function: {function}.") @@ -555,6 +559,20 @@ def _fallback_pandas_aggregation(self, dataset: Dataset, agg_dict: dict) -> Data class RayDedupNode(DAGNode): """ Ray node for deduplicating records. + + Two dedup strategies are provided: + + * **Materialization** (``is_materialization=True``): per-block + ``drop_duplicates``. This is streaming-friendly because it never needs + to see all blocks at once. Any cross-block duplicates are resolved by + the online store, which does an UPSERT and therefore naturally keeps the + last-written value. This avoids the ``groupby().map_groups()`` full + shuffle that would otherwise block until every single block was produced. + + * **Historical retrieval** (``is_materialization=False``): global + ``groupby().map_groups()``. Correctness is required here because the + entity-timestamp join must return exactly one feature row per + (entity, query-timestamp) pair. """ def __init__( @@ -562,10 +580,12 @@ def __init__( name: str, column_info, config: RayComputeEngineConfig, + is_materialization: bool = False, ): super().__init__(name) self.column_info = column_info self.config = config + self.is_materialization = is_materialization def execute(self, context: ExecutionContext) -> DAGValue: """Execute the deduplication operation.""" @@ -573,39 +593,59 @@ def execute(self, context: ExecutionContext) -> DAGValue: input_value.assert_format(DAGFormat.RAY) dataset: Dataset = input_value.data - @safe_batch_processor - def deduplicate_batch(batch: pd.DataFrame) -> pd.DataFrame: - """Remove duplicates from the batch.""" - # Get deduplication keys - join_keys = self.column_info.join_keys - timestamp_col = self.column_info.timestamp_column - - if join_keys: - # Sort by join keys and timestamp (most recent first) - sort_columns = join_keys + [timestamp_col] - available_columns = [ - col for col in sort_columns if col in batch.columns - ] + join_keys = self.column_info.join_keys + timestamp_col = self.column_info.timestamp_column - if available_columns: - # Sort and deduplicate - sorted_batch = batch.sort_values( - available_columns, - ascending=[True] * len(join_keys) - + [False], # Recent timestamps first - ) + if join_keys: + if self.is_materialization: + # Per-block dedup: streaming-safe, no full shuffle required. + # Cross-block duplicates are handled by the online-store UPSERT. + # + # IMPORTANT: do NOT call dataset.schema() here. For streaming + # datasets backed by slow map_batches actors, .schema() triggers + # eager block execution to + # infer the output type. Those blocks are consumed and LOST — + # they never reach the write stage. We therefore defer the + # column-existence check to inside _dedup_block, which runs in + # a worker per block without interfering with streaming. + _join_keys = list(join_keys) + _ts_col = timestamp_col + + def _dedup_block(block: pd.DataFrame) -> pd.DataFrame: + available = [k for k in _join_keys if k in block.columns] + if not available: + return block + if _ts_col and _ts_col in block.columns: + block = block.sort_values(_ts_col, ascending=False) + return block.drop_duplicates(subset=available) + + dataset = dataset.map_batches(_dedup_block, batch_format="pandas") + else: + # Global dedup via groupby: required for historical retrieval + # where the entity–timestamp join must return exactly one row + # per (entity, query-timestamp) pair. + # NOTE: groupby().map_groups() is a full shuffle and blocks + # until ALL upstream blocks are produced. Use only when + # correctness across partition boundaries is mandatory. + available_join_keys = [ + k for k in join_keys if k in dataset.schema().names + ] + available_ts_col = ( + timestamp_col if timestamp_col in dataset.schema().names else None + ) - # Keep first occurrence (most recent) for each join key combination - deduped_batch = sorted_batch.drop_duplicates( - subset=join_keys, - keep="first", - ) + if available_join_keys: - return deduped_batch + def _keep_latest_in_group(group: pd.DataFrame) -> pd.DataFrame: + if available_ts_col and available_ts_col in group.columns: + group = group.sort_values(available_ts_col, ascending=False) + return group.head(1) - return batch + dataset = dataset.groupby(available_join_keys).map_groups( + _keep_latest_in_group, batch_format="pandas" + ) - deduped_dataset = dataset.map_batches(deduplicate_batch, batch_format="pandas") + deduped_dataset = dataset return DAGValue( data=deduped_dataset, @@ -684,10 +724,36 @@ def apply_transformation_with_serialized_udf( return transformed_batch + num_gpus = getattr(self.config, "num_gpus", None) or None + task_options: Dict[str, Any] = dict( + getattr(self.config, "worker_task_options", None) or {} + ) + if num_gpus: + task_options["num_gpus"] = num_gpus + batch_format = ( + getattr(self.config, "gpu_batch_format", "pandas") + if num_gpus + else "pandas" + ) + # Only the scheduling-relevant subset flows into map_batches + _MAP_BATCHES_RESOURCE_KEYS = { + "num_gpus", + "num_cpus", + "accelerator_type", + "resources", + } + map_kwargs: Dict[str, Any] = { + "batch_format": batch_format, + "concurrency": self.config.max_workers or 12, + **{ + k: v + for k, v in task_options.items() + if k in _MAP_BATCHES_RESOURCE_KEYS + }, + } transformed_dataset = dataset.map_batches( apply_transformation_with_serialized_udf, - batch_format="pandas", - concurrency=self.config.max_workers or 12, + **map_kwargs, ) return DAGValue( @@ -826,10 +892,19 @@ def write_batch_with_serialized_artifacts(batch: pd.DataFrame) -> pd.DataFrame: return batch + # Resolve write concurrency from config. + # write_concurrency takes precedence; falls back to max_workers, then 1. + if self.config is not None and self.config.write_concurrency is not None: + _write_concurrency = self.config.write_concurrency + elif self.config is not None and self.config.max_workers is not None: + _write_concurrency = self.config.max_workers + else: + _write_concurrency = 1 + written_dataset = dataset.map_batches( write_batch_with_serialized_artifacts, batch_format="pandas", - concurrency=self.config.max_workers if self.config else 12, + concurrency=_write_concurrency, ) written_dataset = written_dataset.materialize() diff --git a/sdk/python/feast/infra/compute_engines/ray/utils.py b/sdk/python/feast/infra/compute_engines/ray/utils.py index 94ebbe2c643..9727f010ca4 100644 --- a/sdk/python/feast/infra/compute_engines/ray/utils.py +++ b/sdk/python/feast/infra/compute_engines/ray/utils.py @@ -3,8 +3,9 @@ """ import logging -from typing import Callable, Dict, Union +from typing import TYPE_CHECKING, Any, Callable, Dict, Union +import numpy as np import pandas as pd import pyarrow as pa @@ -16,6 +17,9 @@ from feast.utils import _convert_arrow_to_proto from feast.value_type import ValueType +if TYPE_CHECKING: + import ray.data + logger = logging.getLogger(__name__) @@ -45,10 +49,107 @@ def write_to_online_store( for entity in feature_view.entity_columns } - rows_to_write = _convert_arrow_to_proto( - arrow_table, feature_view, join_key_to_value_type + batch_size = repo_config.materialization_config.online_write_batch_size + # Single batch if None (backward compatible), otherwise use configured batch_size + batches = ( + [arrow_table] + if batch_size is None + else arrow_table.to_batches(max_chunksize=batch_size) ) + total_rows = 0 + for batch in batches: + rows_to_write = _convert_arrow_to_proto( + batch, feature_view, join_key_to_value_type + ) + + if rows_to_write: + online_store.online_write_batch( + config=repo_config, + table=feature_view, + data=rows_to_write, + progress=lambda x: None, + ) + total_rows += len(rows_to_write) + + if total_rows > 0: + logger.debug( + f"Successfully wrote {total_rows} rows to online store for {feature_view.name}" + ) + else: + logger.warning(f"No rows to write for {feature_view.name}") + + except Exception as e: + logger.error(f"Failed to write to online store for {feature_view.name}: {e}") + + +# Ray Data batch type: pandas DataFrame, numpy dict, or pyarrow Table +BatchType = Union[pd.DataFrame, Dict[str, np.ndarray], pa.Table] + + +def _is_empty_batch(batch: BatchType) -> bool: + """Return True if the batch contains no rows, regardless of Ray Data batch format. + + Ray Data delivers batches in three formats depending on the batch_format + argument passed to map_batches: + - "pandas" → pd.DataFrame (.empty attribute) + - "numpy" → Dict[str, np.ndarray] (check length of first array) + - "pyarrow" → pa.Table (.num_rows attribute) + """ + if isinstance(batch, pd.DataFrame): + return batch.empty + if isinstance(batch, dict): + if not batch: + return True + first = next(iter(batch.values())) + return len(first) == 0 + if isinstance(batch, pa.Table): + return batch.num_rows == 0 + return False + + +def write_to_online_store_from_ray_ds( + ray_ds: "ray.data.Dataset", + feature_view: Union[BatchFeatureView, StreamFeatureView, FeatureView], + online_store: OnlineStore, + repo_config: RepoConfig, +) -> None: + """Write a Ray Dataset to the online store in a distributed fashion. + + Instead of collecting the entire dataset onto the driver (as + :func:`write_to_online_store` does via ``to_arrow()``), this function uses + ``ray_ds.map_batches`` so that each Ray worker writes its own partition + independently. This avoids driver memory pressure for large datasets and + fully exploits the parallelism of the Ray cluster. + + The ``online_store`` and ``repo_config`` objects must be serialisable + (picklable) because Ray ships them to remote workers. All built-in Feast + online stores satisfy this requirement. + + Args: + ray_ds: The Ray Dataset produced by + :meth:`RayRetrievalJob.to_ray_dataset`. + feature_view: Feature view being materialised. + online_store: Online store instance to write to. + repo_config: Repository configuration forwarded to the online store. + """ + if not getattr(feature_view, "online", False): + return + + join_key_to_value_type: Dict[str, ValueType] = {} + if hasattr(feature_view, "entity_columns") and feature_view.entity_columns: + join_key_to_value_type = { + entity.name: entity.dtype.to_value_type() + for entity in feature_view.entity_columns + } + + batch_size = repo_config.materialization_config.online_write_batch_size + + def _write_batch(batch: pa.Table) -> pa.Table: + """Write a single Arrow batch to the online store and pass it through.""" + rows_to_write = _convert_arrow_to_proto( + batch, feature_view, join_key_to_value_type + ) if rows_to_write: online_store.online_write_batch( config=repo_config, @@ -56,32 +157,52 @@ def write_to_online_store( data=rows_to_write, progress=lambda x: None, ) - logger.debug( - f"Successfully wrote {len(rows_to_write)} rows to online store for {feature_view.name}" - ) - else: - logger.warning(f"No rows to write for {feature_view.name}") + return batch + + # Ray's map_batches requires a positive integer or "default" for batch_size; + # None is not accepted. When no explicit batch size is configured, omit the + # argument entirely so Ray uses its own default partitioning heuristic. + map_batches_kwargs: dict[str, Any] = { + "batch_format": "pyarrow", + "zero_copy_batch": True, + } + if batch_size is not None: + map_batches_kwargs["batch_size"] = batch_size + try: + ray_ds.map_batches(_write_batch, **map_batches_kwargs).materialize() + logger.debug( + f"Distributed online store write completed for {feature_view.name}" + ) except Exception as e: - logger.error(f"Failed to write to online store for {feature_view.name}: {e}") + logger.error( + f"Distributed write to online store failed for {feature_view.name}: {e}" + ) def safe_batch_processor( - func: Callable[[pd.DataFrame], pd.DataFrame], -) -> Callable[[pd.DataFrame], pd.DataFrame]: + func: Callable[[BatchType], BatchType], +) -> Callable[[BatchType], BatchType]: """ - Decorator for batch processing functions that handles empty batches and errors gracefully. + Decorator for batch processing functions that handles empty batches and + exceptions gracefully across all Ray Data batch formats. + + Ray Data can deliver batches as a pandas DataFrame (batch_format="pandas"), + a Dict[str, np.ndarray] (batch_format="numpy"), or a pa.Table + (batch_format="pyarrow"). The decorator handles all three so that callers + using gpu_batch_format="numpy" or "pyarrow" do not crash on the empty-batch + check. Args: - func: Function that processes a pandas DataFrame batch + func: Batch processing function. Receives and returns the same batch + type that Ray Data passes (pandas, numpy dict, or pyarrow Table). Returns: - Wrapped function that handles empty batches and exceptions + Wrapped function that skips empty batches and swallows exceptions. """ - def wrapper(batch: pd.DataFrame) -> pd.DataFrame: - # Handle empty batches - if batch.empty: + def wrapper(batch: BatchType) -> BatchType: + if _is_empty_batch(batch): return batch try: diff --git a/sdk/python/feast/infra/compute_engines/spark/nodes.py b/sdk/python/feast/infra/compute_engines/spark/nodes.py index d44764e7b9b..92964b72bc9 100644 --- a/sdk/python/feast/infra/compute_engines/spark/nodes.py +++ b/sdk/python/feast/infra/compute_engines/spark/nodes.py @@ -34,7 +34,9 @@ from feast.infra.compute_engines.dag.value import DAGValue from feast.infra.compute_engines.spark.utils import map_in_arrow from feast.infra.compute_engines.utils import ( + ENTITY_TS_ALIAS, create_offline_store_retrieval_job, + infer_entity_timestamp_column, ) from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( SparkRetrievalJob, @@ -43,9 +45,6 @@ from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import ( SparkSource, ) -from feast.infra.offline_stores.offline_utils import ( - infer_event_timestamp_from_entity_df, -) logger = logging.getLogger(__name__) @@ -144,9 +143,6 @@ def _spark_types_compatible(expected: SparkDataType, actual: SparkDataType) -> b return False -ENTITY_TS_ALIAS = "__entity_event_timestamp" - - # Rename entity_df event_timestamp_col to match feature_df def rename_entity_ts_column( spark_session: SparkSession, entity_df: DataFrame @@ -159,9 +155,7 @@ def rename_entity_ts_column( spark_session=spark_session, entity_df=entity_df, ) - event_timestamp_col = infer_event_timestamp_from_entity_df( - entity_schema=entity_schema, - ) + event_timestamp_col = infer_entity_timestamp_column(entity_schema) if not isinstance(entity_df, DataFrame): entity_df = spark_session.createDataFrame(entity_df) entity_df = entity_df.withColumnRenamed(event_timestamp_col, ENTITY_TS_ALIAS) @@ -371,8 +365,11 @@ def _execute_standard_aggregation(self, input_df: DataFrame) -> DAGValue: """Execute standard Spark aggregation (existing logic).""" agg_exprs = [] for agg in self.aggregations: - func = getattr(F, agg.function) - expr = func(agg.column).alias(agg.resolved_name(agg.time_window)) + if agg.function == "count_distinct": + func_expr = F.countDistinct(agg.column) + else: + func_expr = getattr(F, agg.function)(agg.column) + expr = func_expr.alias(agg.resolved_name(agg.time_window)) agg_exprs.append(expr) if any(agg.time_window for agg in self.aggregations): diff --git a/sdk/python/feast/infra/compute_engines/spark/utils.py b/sdk/python/feast/infra/compute_engines/spark/utils.py index 4e429f8e075..8c84c9f17a6 100644 --- a/sdk/python/feast/infra/compute_engines/spark/utils.py +++ b/sdk/python/feast/infra/compute_engines/spark/utils.py @@ -1,3 +1,5 @@ +import logging +import os from typing import Dict, Iterable, Literal, Optional import pandas as pd @@ -9,6 +11,102 @@ from feast.infra.common.serde import SerializedArtifacts from feast.utils import _convert_arrow_to_proto, _run_pyarrow_field_mapping +try: + import boto3 + from botocore.client import Config as BotoConfig +except ImportError: + boto3 = None # type: ignore[assignment] + BotoConfig = None # type: ignore[assignment,misc] + +logger = logging.getLogger(__name__) + + +def _ensure_s3a_event_log_dir(spark_config: Dict[str, str]) -> None: + """Pre-create the S3A event log prefix before SparkContext initialisation. + + Spark's EventLogFileWriter.requireLogBaseDirAsDirectory() is called inside + SparkContext.__init__ and crashes if the S3A path doesn't exist yet (S3 has no + real directories, so an empty prefix returns a 404). This function writes a + zero-byte placeholder so the prefix exists before SparkContext is built. + + This is only attempted when: + - spark.eventLog.enabled == "true" + - spark.eventLog.dir starts with "s3a://" + Failures are non-fatal: Spark will surface its own error if the dir is still missing. + """ + if spark_config.get("spark.eventLog.enabled", "false").lower() != "true": + return + event_dir = spark_config.get("spark.eventLog.dir", "") + if not event_dir.startswith("s3a://"): + return + + path = event_dir[len("s3a://") :] + bucket, _, prefix = path.partition("/") + prefix = prefix.rstrip("/") + prefix = (prefix + "/") if prefix else prefix + placeholder_key = prefix + ".keep" + + endpoint = spark_config.get( + "spark.hadoop.fs.s3a.endpoint", + os.environ.get("AWS_ENDPOINT_URL", ""), + ) + access_key = spark_config.get( + "spark.hadoop.fs.s3a.access.key", + os.environ.get("AWS_ACCESS_KEY_ID", ""), + ) + secret_key = spark_config.get( + "spark.hadoop.fs.s3a.secret.key", + os.environ.get("AWS_SECRET_ACCESS_KEY", ""), + ) + session_token = ( + spark_config.get( + "spark.hadoop.fs.s3a.session.token", + os.environ.get("AWS_SESSION_TOKEN", ""), + ) + or None + ) + + try: + if boto3 is None: + raise ImportError("boto3 is not installed") + + addressing_style = ( + "path" + if spark_config.get( + "spark.hadoop.fs.s3a.path.style.access", "false" + ).lower() + == "true" + else "auto" + ) + + s3 = boto3.client( + "s3", + endpoint_url=endpoint if endpoint else None, + aws_access_key_id=access_key or None, + aws_secret_access_key=secret_key or None, + aws_session_token=session_token, + config=BotoConfig( + signature_version="s3v4", + s3={"addressing_style": addressing_style}, + ), + ) + resp = s3.list_objects_v2(Bucket=bucket, Prefix=prefix, MaxKeys=1) + if resp.get("KeyCount", 0) == 0: + s3.put_object(Bucket=bucket, Key=placeholder_key, Body=b"") + logger.debug( + "Created S3A event log dir placeholder: s3a://%s/%s", + bucket, + placeholder_key, + ) + except Exception as exc: + logger.warning( + "Could not pre-create S3A event log dir s3a://%s/%s — " + "SparkContext may fail if the path still doesn't exist: %s", + bucket, + prefix, + exc, + ) + def get_or_create_new_spark_session( spark_config: Optional[Dict[str, str]] = None, @@ -17,6 +115,7 @@ def get_or_create_new_spark_session( if not spark_session: spark_builder = SparkSession.builder if spark_config: + _ensure_s3a_event_log_dir(spark_config) spark_builder = spark_builder.config( conf=SparkConf().setAll([(k, v) for k, v in spark_config.items()]) ) @@ -47,16 +146,24 @@ def map_in_arrow( for entity in feature_view.entity_columns } - rows_to_write = _convert_arrow_to_proto( - table, feature_view, join_key_to_value_type - ) - - online_store.online_write_batch( - config=repo_config, - table=feature_view, - data=rows_to_write, - progress=lambda x: None, + batch_size = repo_config.materialization_config.online_write_batch_size + # Single batch if None (backward compatible), otherwise use configured batch_size + sub_batches = ( + [table] + if batch_size is None + else table.to_batches(max_chunksize=batch_size) ) + for sub_batch in sub_batches: + rows_to_write = _convert_arrow_to_proto( + sub_batch, feature_view, join_key_to_value_type + ) + + online_store.online_write_batch( + config=repo_config, + table=feature_view, + data=rows_to_write, + progress=lambda x: None, + ) if mode == "offline": offline_store.offline_write_batch( config=repo_config, @@ -95,15 +202,23 @@ def map_in_pandas(iterator, serialized_artifacts: SerializedArtifacts): for entity in feature_view.entity_columns } - rows_to_write = _convert_arrow_to_proto( - table, feature_view, join_key_to_value_type - ) - online_store.online_write_batch( - repo_config, - feature_view, - rows_to_write, - lambda x: None, + batch_size = repo_config.materialization_config.online_write_batch_size + # Single batch if None (backward compatible), otherwise use configured batch_size + sub_batches = ( + [table] + if batch_size is None + else table.to_batches(max_chunksize=batch_size) ) + for sub_batch in sub_batches: + rows_to_write = _convert_arrow_to_proto( + sub_batch, feature_view, join_key_to_value_type + ) + online_store.online_write_batch( + repo_config, + feature_view, + rows_to_write, + lambda x: None, + ) yield pd.DataFrame( [pd.Series(range(1, 2))] diff --git a/sdk/python/feast/infra/compute_engines/utils.py b/sdk/python/feast/infra/compute_engines/utils.py index d2c49305376..c36f4d19f07 100644 --- a/sdk/python/feast/infra/compute_engines/utils.py +++ b/sdk/python/feast/infra/compute_engines/utils.py @@ -1,9 +1,32 @@ from datetime import datetime -from typing import Optional +from typing import Any, Mapping, Optional, Sequence from feast.data_source import DataSource from feast.infra.compute_engines.dag.context import ColumnInfo, ExecutionContext from feast.infra.offline_stores.offline_store import RetrievalJob +from feast.infra.offline_stores.offline_utils import ( + DEFAULT_ENTITY_DF_EVENT_TIMESTAMP_COL, + infer_event_timestamp_from_entity_df, +) + +ENTITY_TS_ALIAS = "__entity_event_timestamp" +ENTITY_ROW_ID = "__feast_entity_row_id" + + +def infer_entity_timestamp_column(entity_schema: Mapping[str, Any]) -> str: + """Resolve the entity timestamp column used for point-in-time joins.""" + if ENTITY_TS_ALIAS in entity_schema: + return ENTITY_TS_ALIAS + return infer_event_timestamp_from_entity_df(dict(entity_schema)) + + +def find_entity_timestamp_column(columns: Sequence[str]) -> Optional[str]: + """Find the timestamp column in an entity DataFrame schema, if present.""" + if ENTITY_TS_ALIAS in columns: + return ENTITY_TS_ALIAS + if DEFAULT_ENTITY_DF_EVENT_TIMESTAMP_COL in columns: + return DEFAULT_ENTITY_DF_EVENT_TIMESTAMP_COL + return None def create_offline_store_retrieval_job( diff --git a/sdk/python/feast/infra/contrib/grpc_server.py b/sdk/python/feast/infra/contrib/grpc_server.py index b6ed6cb25d4..4c042051225 100644 --- a/sdk/python/feast/infra/contrib/grpc_server.py +++ b/sdk/python/feast/infra/contrib/grpc_server.py @@ -1,11 +1,11 @@ import logging import threading +from collections.abc import Mapping from concurrent import futures from typing import Optional, Union import grpc import pandas as pd -from grpc_health.v1 import health, health_pb2_grpc from feast.data_source import PushMode from feast.errors import FeatureServiceNotFoundException, PushSourceNotFoundException @@ -34,6 +34,20 @@ def parse(features): return pd.DataFrame.from_dict(df) +def parse_typed(typed_features): + df = {} + for key, value in typed_features.items(): + val_case = value.WhichOneof("val") + if val_case is None or val_case == "null_val": + df[key] = [None] + else: + raw = getattr(value, val_case) + if hasattr(raw, "val"): + raw = dict(raw.val) if isinstance(raw.val, Mapping) else list(raw.val) + df[key] = [raw] + return pd.DataFrame.from_dict(df) + + class GrpcFeatureServer(GrpcFeatureServerServicer): fs: FeatureStore @@ -49,7 +63,17 @@ def __init__(self, fs: FeatureStore, registry_ttl_sec: int = 5): def Push(self, request, context): try: - df = parse(request.features) + if request.features and request.typed_features: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details( + "Only one of features or typed_features may be set, not both" + ) + return PushResponse(status=False) + df = ( + parse_typed(request.typed_features) + if request.typed_features + else parse(request.features) + ) if request.to == "offline": to = PushMode.OFFLINE elif request.to == "online": @@ -62,7 +86,7 @@ def Push(self, request, context): f"'online_and_offline']." ) self.fs.push( - push_source_name=request.push_source_name, + push_source_name=request.stream_feature_view, df=df, allow_registry_cache=request.allow_registry_cache, to=to, @@ -84,7 +108,17 @@ def WriteToOnlineStore(self, request, context): "write_to_online_store is deprecated. Please consider using Push instead" ) try: - df = parse(request.features) + if request.features and request.typed_features: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details( + "Only one of features or typed_features may be set, not both" + ) + return WriteToOnlineStoreResponse(status=False) + df = ( + parse_typed(request.typed_features) + if request.typed_features + else parse(request.features) + ) self.fs.write_to_online_store( feature_view_name=request.feature_view_name, df=df, @@ -94,7 +128,7 @@ def WriteToOnlineStore(self, request, context): logger.exception(str(e)) context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - return PushResponse(status=False) + return WriteToOnlineStoreResponse(status=False) return WriteToOnlineStoreResponse(status=True) def GetOnlineFeatures(self, request: GetOnlineFeaturesRequest, context): @@ -136,6 +170,8 @@ def get_grpc_server( max_workers: int, registry_ttl_sec: int, ): + from grpc_health.v1 import health, health_pb2_grpc + logger.info(f"Initializing gRPC server on {address}") server = grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers)) add_GrpcFeatureServerServicer_to_server( diff --git a/sdk/python/feast/infra/feature_servers/base_config.py b/sdk/python/feast/infra/feature_servers/base_config.py index d6b650ced15..14ad2fe505e 100644 --- a/sdk/python/feast/infra/feature_servers/base_config.py +++ b/sdk/python/feast/infra/feature_servers/base_config.py @@ -62,7 +62,12 @@ class MetricsConfig(FeastConfigBaseModel): online_features: StrictBool = True """Emit online feature retrieval metrics (feast_online_features_request_total, - feast_online_features_entity_count).""" + feast_online_features_entity_count, + feast_feature_server_online_store_read_duration_seconds, + feast_feature_server_transformation_duration_seconds, + feast_feature_server_write_transformation_duration_seconds). + ODFV transformation metrics additionally require track_metrics=True + on the OnDemandFeatureView definition.""" push: StrictBool = True """Emit push/write request counters @@ -70,13 +75,24 @@ class MetricsConfig(FeastConfigBaseModel): materialization: StrictBool = True """Emit materialization success/failure counters and duration histograms - (feast_materialization_total, + (feast_materialization_result_total, feast_materialization_duration_seconds).""" freshness: StrictBool = True """Emit per-feature-view freshness gauges (feast_feature_freshness_seconds).""" + offline_features: StrictBool = True + """Emit offline store retrieval metrics + (feast_offline_store_request_total, + feast_offline_store_request_latency_seconds, + feast_offline_store_row_count).""" + + audit_logging: StrictBool = False + """Emit structured JSON audit log entries for online and offline + feature requests via the ``feast.audit`` logger. Captures requestor + identity, entity keys, feature views, row counts, and latency.""" + class BaseFeatureServerConfig(FeastConfigBaseModel): """Base Feature Server config that should be extended""" diff --git a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile index 311f2ea6413..6eb4cc96418 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile +++ b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile @@ -1,4 +1,8 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest + +USER 0 +RUN microdnf install -y git gcc libpq-devel python3.12-devel && microdnf clean all +USER 1001 COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv ENV UV_CACHE_DIR=/tmp/uv-cache diff --git a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev index fc416727ee2..faf49c20903 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev +++ b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile.dev @@ -1,14 +1,15 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest USER 0 +RUN microdnf install -y npm git gcc libpq-devel python3.12-devel && microdnf clean all RUN npm install -g yarn yalc && rm -rf .npm -USER default +USER 1001 -COPY --chown=default .git ${APP_ROOT}/src/.git -COPY --chown=default pyproject.toml README.md Makefile ${APP_ROOT}/src/ -COPY --chown=default protos ${APP_ROOT}/src/protos -COPY --chown=default ui ${APP_ROOT}/src/ui -COPY --chown=default sdk/python ${APP_ROOT}/src/sdk/python +COPY --chown=1001:0 .git ${APP_ROOT}/src/.git +COPY --chown=1001:0 pyproject.toml README.md Makefile ${APP_ROOT}/src/ +COPY --chown=1001:0 protos ${APP_ROOT}/src/protos +COPY --chown=1001:0 ui ${APP_ROOT}/src/ui +COPY --chown=1001:0 sdk/python ${APP_ROOT}/src/sdk/python WORKDIR ${APP_ROOT}/src/ui RUN npm install && \ diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary index d37c4a1d06f..55e3f50c17c 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary @@ -2,11 +2,11 @@ FROM yarn-builder:latest # This section only necessary when building from local feast source ... e.g. ".[minimal]" ######################## -COPY --chown=default .git ${APP_ROOT}/src/.git -COPY --chown=default pyproject.toml README.md Makefile ${APP_ROOT}/src/ -COPY --chown=default protos ${APP_ROOT}/src/protos -COPY --chown=default ui ${APP_ROOT}/src/ui -COPY --chown=default sdk/python ${APP_ROOT}/src/sdk/python +COPY --chown=1001:0 .git ${APP_ROOT}/src/.git +COPY --chown=1001:0 pyproject.toml README.md Makefile ${APP_ROOT}/src/ +COPY --chown=1001:0 protos ${APP_ROOT}/src/protos +COPY --chown=1001:0 ui ${APP_ROOT}/src/ui +COPY --chown=1001:0 sdk/python ${APP_ROOT}/src/sdk/python WORKDIR ${APP_ROOT}/src/ui ENV NPM_TOKEN= diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary.release b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary.release index 0fb4f88999b..546188a0bff 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary.release +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.binary.release @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest COPY requirements.txt requirements.txt RUN source /tmp/hermeto.env && \ diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yarn b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yarn index 805f4b3e225..124134a4f0d 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yarn +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yarn @@ -1,5 +1,6 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest USER 0 +RUN microdnf install -y npm git && microdnf clean all RUN npm install -g yarn yalc && rm -rf .npm USER 1001 diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yum b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yum index cfca9ccd5aa..198d42ab5c2 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yum +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.builder.yum @@ -1,10 +1,10 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest ARG RELEASE ENV IBIS_VERSION="9.5.0" USER 0 -RUN yum install -y ninja-build llvm-devel cmake llvm-toolset ncurses-devel rust cargo +RUN microdnf install -y ninja-build llvm-devel cmake llvm-toolset ncurses-devel rust cargo npm git && microdnf clean all RUN if [[ -z "$RELEASE" ]] ; then npm install -g yarn yalc && rm -rf .npm ; fi USER 1001 diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist index 5c62bdec22a..e6e32718667 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist @@ -13,6 +13,7 @@ ENV THIRD_PARTY_PATH=/tmp/hermeto-generic-output/deps/generic # unecessary for konflux build ENV RPM_PATH=/tmp/hermeto-rpm-output/deps/rpm/x86_64 USER 0 +RUN microdnf install -y shadow-utils && microdnf clean all RUN useradd mockbuild RUN groupadd mock RUN usermod -G mock mockbuild @@ -71,7 +72,7 @@ RUN mkdir ${APP_ROOT}/src/arrow ${ARROW_HOME} ${APP_ROOT}/src/arrow-build && \ ARROW_ZLIB_URL="${THIRD_PARTY_PATH}/zlib-1.3.1.tar.gz" \ ARROW_ZSTD_URL="${THIRD_PARTY_PATH}/zstd-1.5.6.tar.gz" \ && \ - cmake \ + cmake -G Ninja \ -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \ -DARROW_COMPUTE=ON \ -DARROW_ACERO=ON \ @@ -130,11 +131,11 @@ RUN source /tmp/hermeto.env && \ # This section only necessary when building from local feast source ... e.g. ".[minimal]" ######################## -COPY --chown=default .git ${APP_ROOT}/src/.git -COPY --chown=default pyproject.toml README.md Makefile ${APP_ROOT}/src/ -COPY --chown=default protos ${APP_ROOT}/src/protos -COPY --chown=default ui ${APP_ROOT}/src/ui -COPY --chown=default sdk/python ${APP_ROOT}/src/sdk/python +COPY --chown=1001:0 .git ${APP_ROOT}/src/.git +COPY --chown=1001:0 pyproject.toml README.md Makefile ${APP_ROOT}/src/ +COPY --chown=1001:0 protos ${APP_ROOT}/src/protos +COPY --chown=1001:0 ui ${APP_ROOT}/src/ui +COPY --chown=1001:0 sdk/python ${APP_ROOT}/src/sdk/python WORKDIR ${APP_ROOT}/src/ui ENV NPM_TOKEN= diff --git a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist.release b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist.release index 8fd6f85c6a1..02977b5c0bd 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist.release +++ b/sdk/python/feast/infra/feature_servers/multicloud/offline/Dockerfile.sdist.release @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/python-312:1 +FROM registry.access.redhat.com/ubi9/python-312-minimal:latest ENV APACHE_ARROW_VERSION="17.0.0" ENV MILVUS_LITE_VERSION="2.4.12" @@ -13,6 +13,7 @@ ENV THIRD_PARTY_PATH=/tmp/hermeto-generic-output/deps/generic # unecessary for konflux build ENV RPM_PATH=/tmp/hermeto-rpm-output/deps/rpm/x86_64 USER 0 +RUN microdnf install -y shadow-utils && microdnf clean all RUN useradd mockbuild RUN groupadd mock RUN usermod -G mock mockbuild @@ -71,7 +72,7 @@ RUN mkdir ${APP_ROOT}/src/arrow ${ARROW_HOME} ${APP_ROOT}/src/arrow-build && \ ARROW_ZLIB_URL="${THIRD_PARTY_PATH}/zlib-1.3.1.tar.gz" \ ARROW_ZSTD_URL="${THIRD_PARTY_PATH}/zstd-1.5.6.tar.gz" \ && \ - cmake \ + cmake -G Ninja \ -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \ -DARROW_COMPUTE=ON \ -DARROW_ACERO=ON \ diff --git a/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt b/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt index 50874eddeb5..7f5af66bf68 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt +++ b/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt @@ -1,2 +1,2 @@ # keep VERSION on line #2, this is critical to release CI -feast[minimal] == 0.61.0 +feast[minimal] == 0.64.0 diff --git a/sdk/python/feast/infra/mcp_servers/mcp_config.py b/sdk/python/feast/infra/mcp_servers/mcp_config.py index dfb391eb137..8e48da58246 100644 --- a/sdk/python/feast/infra/mcp_servers/mcp_config.py +++ b/sdk/python/feast/infra/mcp_servers/mcp_config.py @@ -1,4 +1,4 @@ -from typing import Literal, Optional +from typing import Literal from pydantic import StrictBool, StrictStr @@ -20,8 +20,7 @@ class McpFeatureServerConfig(BaseFeatureServerConfig): # MCP server version mcp_server_version: StrictStr = "1.0.0" - # Optional MCP transport configuration - mcp_transport: Optional[StrictStr] = None + mcp_transport: Literal["sse", "http"] = "sse" # The endpoint definition for transformation_service (inherited from base) transformation_service_endpoint: StrictStr = "localhost:6566" diff --git a/sdk/python/feast/infra/mcp_servers/mcp_server.py b/sdk/python/feast/infra/mcp_servers/mcp_server.py index 611b4688795..972023cdd12 100644 --- a/sdk/python/feast/infra/mcp_servers/mcp_server.py +++ b/sdk/python/feast/infra/mcp_servers/mcp_server.py @@ -26,6 +26,10 @@ FastApiMCP = None +class McpTransportNotSupportedError(RuntimeError): + pass + + def add_mcp_support_to_app(app, store: FeatureStore, config) -> Optional["FastApiMCP"]: """Add MCP support to the FastAPI app if enabled in configuration.""" if not MCP_AVAILABLE: @@ -40,8 +44,29 @@ def add_mcp_support_to_app(app, store: FeatureStore, config) -> Optional["FastAp description="Feast Feature Store MCP Server - Access feature store data and operations through MCP", ) - # Mount the MCP server to the FastAPI app - mcp.mount() + transport = getattr(config, "mcp_transport", "sse") + if transport == "http": + mount_http = getattr(mcp, "mount_http", None) + if mount_http is None: + raise McpTransportNotSupportedError( + "mcp_transport=http requires fastapi_mcp with FastApiMCP.mount_http(). " + "Upgrade fastapi_mcp (or install feast[mcp]) to a newer version." + ) + mount_http() + elif transport == "sse": + mount_sse = getattr(mcp, "mount_sse", None) + if mount_sse is not None: + mount_sse() + else: + logger.warning( + "transport sse not supported, fallback to the deprecated mount()." + ) + mcp.mount() + else: + # Defensive guard for programmatic callers. + raise McpTransportNotSupportedError( + f"Unsupported mcp_transport={transport!r}. Expected 'sse' or 'http'." + ) logger.info( "MCP support has been enabled for the Feast feature server at /mcp endpoint" @@ -53,6 +78,8 @@ def add_mcp_support_to_app(app, store: FeatureStore, config) -> Optional["FastAp return mcp + except McpTransportNotSupportedError: + raise except Exception as e: - logger.error(f"Failed to initialize MCP integration: {e}") + logger.error(f"Failed to initialize MCP integration: {e}", exc_info=True) return None diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py index fac3439b911..77c9a17de87 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery.py +++ b/sdk/python/feast/infra/offline_stores/bigquery.py @@ -1,7 +1,8 @@ import contextlib +import json import tempfile import uuid -from datetime import date, datetime, timedelta +from datetime import date, datetime, timedelta, timezone from pathlib import Path from typing import ( Any, @@ -42,6 +43,17 @@ RetrievalMetadata, ) from feast.infra.registry.base_registry import BaseRegistry +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.on_demand_feature_view import OnDemandFeatureView from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage @@ -161,6 +173,19 @@ def pull_latest_from_table_or_query( project=project_id, location=config.offline_store.location, ) + cast_style: Literal["date_func", "timestamp_func"] = ( + "date_func" + if data_source.timestamp_field_type == "DATE" + else "timestamp_func" + ) + timestamp_filter = get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + date_partition_column=data_source.date_partition_column, + quote_fields=False, + cast_style=cast_style, + ) query = f""" SELECT {field_string} @@ -169,7 +194,7 @@ def pull_latest_from_table_or_query( SELECT {field_string}, ROW_NUMBER() OVER({partition_by_join_key_string} ORDER BY {timestamp_desc_string}) AS _feast_row FROM {from_expression} - WHERE {timestamp_field} BETWEEN TIMESTAMP('{start_date}') AND TIMESTAMP('{end_date}') + WHERE {timestamp_filter} ) WHERE _feast_row = 1 """ @@ -212,12 +237,18 @@ def pull_all_from_table_or_query( + BigQueryOfflineStore._escape_query_columns(feature_name_columns) + timestamp_fields ) + cast_style: Literal["date_func", "timestamp_func"] = ( + "date_func" + if data_source.timestamp_field_type == "DATE" + else "timestamp_func" + ) timestamp_filter = get_timestamp_filter_sql( start_date, end_date, timestamp_field, + date_partition_column=data_source.date_partition_column, quote_fields=False, - cast_style="timestamp_func", + cast_style=cast_style, ) query = f""" SELECT {field_string} @@ -425,11 +456,15 @@ def offline_write_batch( location=config.offline_store.location, ) + parquet_options = bigquery.ParquetOptions() + parquet_options.enable_list_inference = True + job_config = bigquery.LoadJobConfig( source_format=bigquery.SourceFormat.PARQUET, schema=arrow_schema_to_bq_schema(pa_schema), create_disposition=config.offline_store.table_create_disposition, write_disposition="WRITE_APPEND", # Default but included for clarity + parquet_options=parquet_options, ) with tempfile.TemporaryFile() as parquet_temp_file: @@ -454,6 +489,648 @@ def offline_write_batch( def _escape_query_columns(columns: List[str]) -> List[str]: return [f"`{x}`" for x in columns] + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + assert isinstance(data_source, BigQuerySource) + return _bq_compute_monitoring_metrics( + config, + data_source, + feature_columns, + timestamp_field, + start_date=start_date, + end_date=end_date, + histogram_bins=histogram_bins, + top_n=top_n, + ) + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + assert isinstance(data_source, BigQuerySource) + return _bq_get_monitoring_max_timestamp(config, data_source, timestamp_field) + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + _bq_ensure_monitoring_tables(config) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + _bq_save_monitoring_metrics(config, metric_type, metrics) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + return _bq_query_monitoring_metrics( + config, project, metric_type, filters, start_date, end_date + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + _bq_clear_monitoring_baseline( + config, project, feature_view_name, feature_name, data_source_type + ) + + +# ------------------------------------------------------------------ # +# BigQuery monitoring metrics (native) +# ------------------------------------------------------------------ # + + +def _bq_monitoring_table_fqn(config: RepoConfig, table_name: str) -> str: + assert isinstance(config.offline_store, BigQueryOfflineStoreConfig) + project_id = config.offline_store.project_id + if not project_id: + client = _get_bigquery_client( + project=config.offline_store.billing_project_id, + location=config.offline_store.location, + ) + project_id = client.project + return f"`{project_id}.{config.offline_store.dataset}.{table_name}`" + + +def _bq_scalar_param_type(column: str) -> str: + if column == "is_baseline": + return "BOOL" + if column == "metric_date": + return "DATE" + if column == "computed_at": + return "TIMESTAMP" + if column in { + "row_count", + "null_count", + "total_row_count", + "total_features", + "features_with_nulls", + "total_feature_views", + }: + return "INT64" + if column in { + "null_rate", + "mean", + "stddev", + "min_val", + "max_val", + "p50", + "p75", + "p90", + "p95", + "p99", + "avg_null_rate", + "max_null_rate", + }: + return "FLOAT64" + return "STRING" + + +def _bq_merge_row( + config: RepoConfig, + table_fqn: str, + columns: List[str], + pk_columns: List[str], + row: Dict[str, Any], +) -> None: + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + non_pk = [c for c in columns if c not in pk_columns] + params: List[Any] = [] + using_parts: List[str] = [] + on_parts: List[str] = [] + merge_idx = 0 + for col in columns: + p = f"p{merge_idx}" + merge_idx += 1 + val = row.get(col) + if col == "histogram" and val is not None and not isinstance(val, str): + val = json.dumps(val) + param_type = _bq_scalar_param_type(col) + params.append(bigquery.ScalarQueryParameter(p, param_type, val)) + using_parts.append(f"@{p} AS {col}") + on_parts = [f"T.{col} = S.{col}" for col in pk_columns] + update_set = ", ".join(f"{c} = S.{c}" for c in non_pk) + merge_sql = f""" +MERGE {table_fqn} T +USING (SELECT {", ".join(using_parts)}) S +ON {" AND ".join(on_parts)} +WHEN MATCHED THEN UPDATE SET {update_set} +WHEN NOT MATCHED THEN INSERT ({", ".join(columns)}) VALUES ({", ".join(f"S.{c}" for c in columns)}) +""" + job_config = bigquery.QueryJobConfig(query_parameters=params) + client.query(merge_sql, job_config=job_config).result() + + +def _bq_save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], +) -> None: + table_short, columns, pk_columns = monitoring_table_meta(metric_type) + table_fqn = _bq_monitoring_table_fqn(config, table_short) + for row in metrics: + _bq_merge_row(config, table_fqn, columns, pk_columns, row) + + +def _bq_query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, +) -> List[Dict[str, Any]]: + table_short, columns, _ = monitoring_table_meta(metric_type) + table_fqn = _bq_monitoring_table_fqn(config, table_short) + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + params: List[Any] = [] + conditions: List[str] = [] + if project: + params.append( + bigquery.ScalarQueryParameter("project", "STRING", project), + ) + conditions.append("project_id = @project") + if filters: + for key, value in filters.items(): + if value is not None: + conditions.append(f"`{key}` = @{key}") + params.append( + bigquery.ScalarQueryParameter( + key, _bq_scalar_param_type(key), value + ) + ) + if start_date: + conditions.append("metric_date >= @start_date") + params.append(bigquery.ScalarQueryParameter("start_date", "DATE", start_date)) + if end_date: + conditions.append("metric_date <= @end_date") + params.append(bigquery.ScalarQueryParameter("end_date", "DATE", end_date)) + col_list = ", ".join(f"`{c}`" for c in columns) + where_sql = " AND ".join(conditions) if conditions else "TRUE" + order_col = "metric_date" if "metric_date" in columns else "job_id" + sql = f"SELECT {col_list} FROM {table_fqn} WHERE {where_sql} ORDER BY `{order_col}` ASC" + job_config = bigquery.QueryJobConfig(query_parameters=params) + job = client.query(sql, job_config=job_config) + job.result() + results: List[Dict[str, Any]] = [] + for r in job: + record = {columns[i]: r[i] for i in range(len(columns))} + results.append(normalize_monitoring_row(record)) + return results + + +def _bq_clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, +) -> None: + table_fqn = _bq_monitoring_table_fqn(config, MON_TABLE_FEATURE) + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + params: List[Any] = [ + bigquery.ScalarQueryParameter("project", "STRING", project), + ] + conditions = ["project_id = @project", "is_baseline = TRUE"] + if feature_view_name: + conditions.append("feature_view_name = @feature_view_name") + params.append( + bigquery.ScalarQueryParameter( + "feature_view_name", "STRING", feature_view_name + ) + ) + if feature_name: + conditions.append("feature_name = @feature_name") + params.append( + bigquery.ScalarQueryParameter("feature_name", "STRING", feature_name) + ) + if data_source_type: + conditions.append("data_source_type = @data_source_type") + params.append( + bigquery.ScalarQueryParameter( + "data_source_type", "STRING", data_source_type + ) + ) + sql = f"UPDATE {table_fqn} SET is_baseline = FALSE WHERE {' AND '.join(conditions)}" + job_config = bigquery.QueryJobConfig(query_parameters=params) + client.query(sql, job_config=job_config).result() + + +def _bq_ensure_monitoring_tables(config: RepoConfig) -> None: + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + ds = config.offline_store.dataset + proj = config.offline_store.project_id or client.project + feature_ddl = f""" +CREATE TABLE IF NOT EXISTS `{proj}.{ds}.{MON_TABLE_FEATURE}` ( + project_id STRING NOT NULL, + feature_view_name STRING NOT NULL, + feature_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOL NOT NULL, + feature_type STRING NOT NULL, + row_count INT64, + null_count INT64, + null_rate FLOAT64, + mean FLOAT64, + stddev FLOAT64, + min_val FLOAT64, + max_val FLOAT64, + p50 FLOAT64, + p75 FLOAT64, + p90 FLOAT64, + p95 FLOAT64, + p99 FLOAT64, + histogram STRING +) +PRIMARY KEY (project_id, feature_view_name, feature_name, metric_date, granularity, data_source_type) NOT ENFORCED +""" + view_ddl = f""" +CREATE TABLE IF NOT EXISTS `{proj}.{ds}.{MON_TABLE_FEATURE_VIEW}` ( + project_id STRING NOT NULL, + feature_view_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOL NOT NULL, + total_row_count INT64, + total_features INT64, + features_with_nulls INT64, + avg_null_rate FLOAT64, + max_null_rate FLOAT64 +) +PRIMARY KEY (project_id, feature_view_name, metric_date, granularity, data_source_type) NOT ENFORCED +""" + service_ddl = f""" +CREATE TABLE IF NOT EXISTS `{proj}.{ds}.{MON_TABLE_FEATURE_SERVICE}` ( + project_id STRING NOT NULL, + feature_service_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOL NOT NULL, + total_feature_views INT64, + total_features INT64, + avg_null_rate FLOAT64, + max_null_rate FLOAT64 +) +PRIMARY KEY (project_id, feature_service_name, metric_date, granularity, data_source_type) NOT ENFORCED +""" + job_ddl = f""" +CREATE TABLE IF NOT EXISTS `{proj}.{ds}.{MON_TABLE_JOB}` ( + job_id STRING NOT NULL, + project_id STRING NOT NULL, + feature_view_name STRING, + job_type STRING NOT NULL, + status STRING NOT NULL, + parameters STRING, + metric_date DATE NOT NULL, + started_at TIMESTAMP, + completed_at TIMESTAMP, + error_message STRING, + result_summary STRING +) +PRIMARY KEY (job_id) NOT ENFORCED +""" + for ddl in (feature_ddl, view_ddl, service_ddl, job_ddl): + client.query(ddl).result() + + +def _bq_get_monitoring_max_timestamp( + config: RepoConfig, + data_source: BigQuerySource, + timestamp_field: str, +) -> Optional[datetime]: + from_expression = data_source.get_table_query_string() + ts_col = f"`{timestamp_field}`" + sql = f"SELECT MAX({ts_col}) AS _max_ts FROM {from_expression}" + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + job = client.query(sql) + job.result() + rows = list(job) + if not rows or rows[0][0] is None: + return None + val = rows[0][0] + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + if isinstance(val, date): + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + return val # type: ignore[no-any-return] + + +def _bq_numeric_histogram( + config: RepoConfig, + from_expression: str, + col_name: str, + ts_filter: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = f"`{col_name}`" + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + if min_val == max_val: + sql = ( + f"SELECT COUNT(*) AS cnt FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_filter}" + ) + job = client.query(sql) + job.result() + hrows = list(job) + cnt = int(hrows[0][0]) if hrows else 0 + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + bin_width = (max_val - min_val) / bins + sql = f""" +SELECT + LEAST( + GREATEST( + CAST(FLOOR((CAST({q_col} AS FLOAT64) - {min_val}) / {bin_width}) AS INT64) + 1, + 1 + ), + {bins} + ) AS bucket, + COUNT(*) AS cnt +FROM {from_expression} AS _src +WHERE {q_col} IS NOT NULL AND {ts_filter} +GROUP BY bucket +ORDER BY bucket +""" + job = client.query(sql) + job.result() + rows = list(job) + counts = [0] * bins + for bucket, cnt in rows: + b = int(bucket) + if 1 <= b <= bins: + counts[b - 1] += int(cnt) + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _bq_numeric_stats( + config: RepoConfig, + from_expression: str, + feature_names: List[str], + ts_filter: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + select_parts: List[str] = ["COUNT(*) AS _row_count"] + for i, col in enumerate(feature_names): + q = f"`{col}`" + c = f"CAST({q} AS FLOAT64)" + select_parts.extend( + [ + f"COUNT({q}) AS c{i}_nn", + f"AVG({c}) AS c{i}_avg", + f"STDDEV_SAMP({c}) AS c{i}_stddev", + f"MIN({c}) AS c{i}_min", + f"MAX({c}) AS c{i}_max", + f"APPROX_QUANTILES({c}, 100)[OFFSET(50)] AS c{i}_p50", + f"APPROX_QUANTILES({c}, 100)[OFFSET(75)] AS c{i}_p75", + f"APPROX_QUANTILES({c}, 100)[OFFSET(90)] AS c{i}_p90", + f"APPROX_QUANTILES({c}, 100)[OFFSET(95)] AS c{i}_p95", + f"APPROX_QUANTILES({c}, 100)[OFFSET(99)] AS c{i}_p99", + ] + ) + query = ( + f"SELECT {', '.join(select_parts)} " + f"FROM {from_expression} AS _src WHERE {ts_filter}" + ) + job = client.query(query) + job.result() + rows = list(job) + if not rows: + return [empty_numeric_metric(n) for n in feature_names] + row = rows[0] + row_count = row["_row_count"] or 0 + results: List[Dict[str, Any]] = [] + for i, col in enumerate(feature_names): + base = f"c{i}_" + non_null = row[f"{base}nn"] or 0 + null_count = int(row_count) - int(non_null) + min_v = opt_float(row[f"{base}min"]) + max_v = opt_float(row[f"{base}max"]) + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": int(row_count), + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[f"{base}avg"]), + "stddev": opt_float(row[f"{base}stddev"]), + "min_val": min_v, + "max_val": max_v, + "p50": opt_float(row[f"{base}p50"]), + "p75": opt_float(row[f"{base}p75"]), + "p90": opt_float(row[f"{base}p90"]), + "p95": opt_float(row[f"{base}p95"]), + "p99": opt_float(row[f"{base}p99"]), + "histogram": None, + } + if min_v is not None and max_v is not None and non_null and int(non_null) > 0: + result["histogram"] = _bq_numeric_histogram( + config, + from_expression, + col, + ts_filter, + histogram_bins, + min_v, + max_v, + ) + results.append(result) + return results + + +def _bq_categorical_stats( + config: RepoConfig, + from_expression: str, + col_name: str, + ts_filter: str, + top_n: int, +) -> Dict[str, Any]: + q_col = f"`{col_name}`" + project_id = ( + config.offline_store.billing_project_id or config.offline_store.project_id + ) + client = _get_bigquery_client( + project=project_id, + location=config.offline_store.location, + ) + query = f""" +WITH filtered AS ( + SELECT * FROM {from_expression} AS _src WHERE {ts_filter} +) +SELECT + (SELECT COUNT(*) FROM filtered) AS row_count, + (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, + (SELECT COUNT(DISTINCT {q_col}) FROM filtered WHERE {q_col} IS NOT NULL) AS unique_count, + CAST({q_col} AS STRING) AS value, + COUNT(*) AS cnt +FROM filtered +WHERE {q_col} IS NOT NULL +GROUP BY CAST({q_col} AS STRING) +ORDER BY cnt DESC +LIMIT {int(top_n)} +""" + job = client.query(query) + job.result() + rows = list(job) + if not rows: + return empty_categorical_metric(col_name) + row_count = rows[0]["row_count"] + null_count = rows[0]["null_count"] + unique_count = rows[0]["unique_count"] + top_entries = [{"value": r["value"], "count": r["cnt"]} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +def _bq_compute_monitoring_metrics( + config: RepoConfig, + data_source: BigQuerySource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, +) -> List[Dict[str, Any]]: + from_expression = data_source.get_table_query_string() + ts_filter = ( + get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + date_partition_column=data_source.date_partition_column, + quote_fields=False, + cast_style="timestamp_func", + ) + or "1=1" + ) + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + if numeric_features: + results.extend( + _bq_numeric_stats( + config, + from_expression, + numeric_features, + ts_filter, + histogram_bins, + ) + ) + for col_name in categorical_features: + results.append( + _bq_categorical_stats(config, from_expression, col_name, ts_filter, top_n) + ) + return results + class BigQueryRetrievalJob(RetrievalJob): def __init__( @@ -925,10 +1602,23 @@ def arrow_schema_to_bq_schema(arrow_schema: pyarrow.Schema) -> List[SchemaField] {% if loop.last %}{% else %}, {% endif %} {% endfor %} FROM {{ featureview.table_subquery }} + {% if featureview.timestamp_field_type == "DATE" %} + WHERE {{ featureview.timestamp_field }} <= DATE('{{ featureview.max_event_timestamp[:10] }}') + {% if featureview.ttl == 0 %}{% else %} + AND {{ featureview.timestamp_field }} >= DATE('{{ featureview.min_event_timestamp[:10] }}') + {% endif %} + {% else %} WHERE {{ featureview.timestamp_field }} <= '{{ featureview.max_event_timestamp }}' {% if featureview.ttl == 0 %}{% else %} AND {{ featureview.timestamp_field }} >= '{{ featureview.min_event_timestamp }}' {% endif %} + {% endif %} + {% if featureview.date_partition_column %} + AND {{ featureview.date_partition_column | backticks }} <= '{{ featureview.max_event_timestamp[:10] }}' + {% if featureview.min_event_timestamp %} + AND {{ featureview.date_partition_column | backticks }} >= '{{ featureview.min_event_timestamp[:10] }}' + {% endif %} + {% endif %} ), {{ featureview.name }}__base AS ( diff --git a/sdk/python/feast/infra/offline_stores/bigquery_source.py b/sdk/python/feast/infra/offline_stores/bigquery_source.py index 1dda7af928f..5fdc29a19fb 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery_source.py +++ b/sdk/python/feast/infra/offline_stores/bigquery_source.py @@ -34,6 +34,8 @@ def __init__( table: Optional[str] = None, created_timestamp_column: Optional[str] = "", field_mapping: Optional[Dict[str, str]] = None, + date_partition_column: Optional[str] = None, + timestamp_field_type: Optional[str] = None, query: Optional[str] = None, description: Optional[str] = "", tags: Optional[Dict[str, str]] = None, @@ -46,14 +48,18 @@ def __init__( case the table must be specified. timestamp_field (optional): Event timestamp field used for point in time joins of feature values. - table (optional): BigQuery table where the features are stored. Exactly one of 'table' - and 'query' must be specified. - table (optional): The BigQuery table where features can be found. + table (optional): BigQuery table where the features are stored. At least one of 'table' + and 'query' must be specified. When both are set, 'query' is used for reads and + 'table' is used as the write destination. created_timestamp_column (optional): Timestamp column when row was created, used for deduplicating rows. field_mapping (optional): A dictionary mapping of column names in this data source to feature names in a feature table or view. Only used for feature columns, not entities or timestamp columns. - query (optional): The query to be executed to obtain the features. Exactly one of 'table' - and 'query' must be specified. + date_partition_column (optional): Timestamp column used for partitioning. + timestamp_field_type (optional): Type of the timestamp_field column. + Set to "DATE" when the event timestamp column is a DATE type, + so SQL generation uses date-only comparisons instead of TIMESTAMP(). + query (optional): The query to be executed to obtain the features. When both 'table' + and 'query' are provided, 'query' takes priority for reads. description (optional): A human-readable description. tags (optional): A dictionary of key-value pairs to store arbitrary metadata. owner (optional): The owner of the bigquery source, typically the email of the primary @@ -78,6 +84,8 @@ def __init__( timestamp_field=timestamp_field, created_timestamp_column=created_timestamp_column, field_mapping=field_mapping, + date_partition_column=date_partition_column, + timestamp_field_type=timestamp_field_type, description=description, tags=tags, owner=owner, @@ -117,6 +125,8 @@ def from_proto(data_source: DataSourceProto): table=data_source.bigquery_options.table, timestamp_field=data_source.timestamp_field, created_timestamp_column=data_source.created_timestamp_column, + date_partition_column=data_source.date_partition_column, + timestamp_field_type=data_source.timestamp_field_type or None, query=data_source.bigquery_options.query, description=data_source.description, tags=dict(data_source.tags), @@ -134,6 +144,8 @@ def _to_proto_impl(self) -> DataSourceProto: owner=self.owner, timestamp_field=self.timestamp_field, created_timestamp_column=self.created_timestamp_column, + date_partition_column=self.date_partition_column, + timestamp_field_type=self.timestamp_field_type, ) return data_source_proto @@ -151,10 +163,10 @@ def validate(self, config: RepoConfig): def get_table_query_string(self) -> str: """Returns a string that can directly be used to reference this table in SQL""" - if self.table: - return f"`{self.table}`" - else: + if self.query: return f"({self.query})" + else: + return f"`{self.table}`" @staticmethod def source_datatype_to_feast_value_type() -> Callable[[str], ValueType]: @@ -180,14 +192,14 @@ def get_table_column_names_and_types( location=config.offline_store.location, client_info=http_client_info.ClientInfo(user_agent=get_user_agent()), ) - if self.table: - schema = client.get_table(self.table).schema - if not isinstance(schema[0], bigquery.schema.SchemaField): - raise TypeError("Could not parse BigQuery table schema.") - else: + if self.query: bq_columns_query = f"SELECT * FROM ({self.query}) LIMIT 0" query_res = client.query(bq_columns_query).result() schema = query_res.schema + else: + schema = client.get_table(self.table).schema + if not isinstance(schema[0], bigquery.schema.SchemaField): + raise TypeError("Could not parse BigQuery table schema.") name_type_pairs: List[Tuple[str, str]] = [] for field in schema: diff --git a/sdk/python/feast/infra/offline_stores/contrib/clickhouse_offline_store/clickhouse.py b/sdk/python/feast/infra/offline_stores/contrib/clickhouse_offline_store/clickhouse.py index 723869c6bd1..79958960c85 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/clickhouse_offline_store/clickhouse.py +++ b/sdk/python/feast/infra/offline_stores/contrib/clickhouse_offline_store/clickhouse.py @@ -31,7 +31,7 @@ from feast.infra.utils.clickhouse.clickhouse_config import ClickhouseConfig from feast.infra.utils.clickhouse.connection_utils import get_client from feast.saved_dataset import SavedDatasetStorage -from feast.utils import _utc_now, make_tzaware +from feast.utils import compute_non_entity_date_range class ClickhouseOfflineStoreConfig(ClickhouseConfig): @@ -56,12 +56,11 @@ def get_historical_features( # Handle non-entity retrieval mode if entity_df is None: - end_date = kwargs.get("end_date", None) - if end_date is None: - end_date = _utc_now() - else: - end_date = make_tzaware(end_date) - + start_date, end_date = compute_non_entity_date_range( + feature_views, + start_date=kwargs.get("start_date"), + end_date=kwargs.get("end_date"), + ) entity_df = pd.DataFrame({"event_timestamp": [end_date]}) entity_schema = _get_entity_schema(entity_df, config) diff --git a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/README.md b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/README.md new file mode 100644 index 00000000000..24446f8c003 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/README.md @@ -0,0 +1,71 @@ +# MongoDB Offline Store + +This offline store lets you train models and run batch scoring directly from it. +All feature views share a single collection. Reads use +MongoDB aggregation pipelines with a compound index, so per-entity cost is +O(log n_observations) regardless of collection size. + +## Schema + +All feature views share one collection (default: `feature_history`), discriminated by the `feature_view` field. + +```javascript +// Collection: feature_history +{ + "entity_id": Binary("..."), // Serialized entity key (bytes) + "feature_view": "driver_stats", // Discriminator + "features": { // Nested subdocument + "trips_today": 5, + "rating": 4.8 + }, + "event_timestamp": ISODate("2024-01-15T10:00:00Z"), + "created_at": ISODate("2024-01-15T10:00:01Z") +} +``` +## Index + +The store creates one compound index lazily on first use. This index supports every query issued.. + +```javascript +db.feature_history.createIndex({ + "entity_id": 1, + "feature_view": 1, + "event_timestamp": -1, + "created_at": -1 +}) + +``` +## Configuration + +```yaml +offline_store: + type: feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore + connection_string: mongodb://localhost:27017 + database: feast + collection: feature_history # optional, default: feature_history +``` + +## Key Features + +**Query-collapse** — Feature views that share the same join key set are grouped into a single MongoDB aggregation round-trip instead of one per feature view. Reduces round-trips from K to the number of unique join key signatures, often one. + +**Scoring path** — When `entity_df` contains unique entity IDs, a `$match + $sort + $group` pipeline performs server-side deduplication returning at most one document per `(entity_id, feature_view)`. The compound index makes per-entity cost O(log n_obs). + +**Training path** — When `entity_df` contains repeated entity IDs at different timestamps, the `$group` stage is omitted and `pandas.merge_asof` performs per-row point-in-time joins optimized in C. + +**`strict_pit`** — `get_historical_features` accepts a `strict_pit` keyword argument (default `True`). With `strict_pit=True` (default, safe for training), documents whose timestamp is strictly after the entity request timestamp are returned as `NULL`. Set `strict_pit=False` for real-time inference where you always want the most recent observation. + + +## Writing Data + +Use `offline_write_batch` (called automatically by `feast materialize`) to write feature observations: + +```python +store.write_to_offline_store(feature_view_name, df) +``` + +Documents are appended; `pull_latest` and the scoring path select the highest `created_at` at read time. + +## Memory Behaviour + +The store filters by entity key in `$match` rather than loading the entire collection. Memory usage is bounded by the number of unique entity IDs × documents per entity, not the total collection size. diff --git a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py new file mode 100644 index 00000000000..535583bc38d --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py @@ -0,0 +1,8 @@ +import feast.version + +try: + from pymongo.driver_info import DriverInfo + + DRIVER_METADATA = DriverInfo(name="Feast", version=feast.version.get_version()) +except ImportError: + DRIVER_METADATA = None # type: ignore[assignment] diff --git a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/mongodb.py b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/mongodb.py new file mode 100644 index 00000000000..76aa173cb95 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/mongodb.py @@ -0,0 +1,1067 @@ +# Copyright 2026 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +MongoDB Offline Store. + +Single-collection schema. Key optimizations: + +1. Server-side deduplication (scoring path): when entity_df has unique + entity IDs the aggregation adds a ``$group`` stage that returns at most + one document per (entity_id, feature_view) pair — O(N×K) transfer + instead of O(N×P×K). The compound index backs the entire pipeline, + making per-entity cost O(log P) rather than O(P). + + For training data (repeated entity IDs at different timestamps) the + ``$group`` optimisation is skipped and ``merge_asof`` is used instead, + + +Index (created lazily on first use):: + + (entity_id ASC, feature_view ASC, event_timestamp DESC, created_at DESC) +""" + +from collections import defaultdict +from datetime import datetime, timezone +from typing import ( + Any, + Callable, + Dict, + Generator, + List, + Optional, + Set, + Tuple, + Union, +) + +import pandas as pd +import pyarrow + +try: + from pymongo import ASCENDING, DESCENDING, MongoClient +except ImportError: + MongoClient = None # type: ignore[assignment,misc] + +from pydantic import StrictStr + +from feast.data_source import DataSource +from feast.errors import ( + DataSourceNoNameException, + FeastExtrasDependencyImportError, + SavedDatasetLocationAlreadyExists, +) +from feast.feature_view import FeatureView +from feast.infra.key_encoding_utils import deserialize_entity_key, serialize_entity_key +from feast.infra.offline_stores.offline_store import ( + OfflineStore, + RetrievalJob, + RetrievalMetadata, +) +from feast.infra.offline_stores.offline_utils import ( + get_expected_join_keys, + infer_event_timestamp_from_entity_df, +) +from feast.infra.registry.base_registry import BaseRegistry +from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import FeastConfigBaseModel, RepoConfig +from feast.saved_dataset import SavedDatasetStorage +from feast.type_map import mongodb_to_feast_value_type +from feast.value_type import ValueType + +from . import DRIVER_METADATA + +# Cache: avoid re-creating the compound index on every call +_indexes_ensured: Set[str] = set() + +# Chunk sizes — exposed at module level so tests can patch them. +_CHUNK_SIZE = 50_000 +_MONGO_BATCH_SIZE = 10_000 + + +# --------------------------------------------------------------------------- +# Config +# --------------------------------------------------------------------------- + + +class MongoDBOfflineStoreConfig(FeastConfigBaseModel): + """Configuration for the MongoDB offline store (single shared collection).""" + + type: StrictStr = "feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore" + + connection_string: StrictStr = "mongodb://localhost:27017" + """MongoDB connection URI""" + + database: StrictStr = "feast" + """MongoDB database name""" + + collection: StrictStr = "feature_history" + """Single collection shared by all feature views""" + + +# --------------------------------------------------------------------------- +# Data source +# --------------------------------------------------------------------------- + + +class MongoDBSource(DataSource): + """Data source for the MongoDB offline store. + + The ``name`` field is used as the ``feature_view`` discriminator inside + the single shared collection. + """ + + def __init__( + self, + name: Optional[str] = None, + timestamp_field: str = "event_timestamp", + created_timestamp_column: str = "created_at", + field_mapping: Optional[Dict[str, str]] = None, + description: Optional[str] = "", + tags: Optional[Dict[str, str]] = None, + owner: Optional[str] = "", + ): + if name is None: + raise DataSourceNoNameException() + super().__init__( + name=name, + timestamp_field=timestamp_field, + created_timestamp_column=created_timestamp_column, + field_mapping=field_mapping or {}, + description=description, + tags=tags or {}, + owner=owner, + ) + + @property + def feature_view_name(self) -> str: + return self.name + + def source_type(self) -> DataSourceProto.SourceType.ValueType: + return DataSourceProto.CUSTOM_SOURCE + + def validate(self, config: RepoConfig) -> None: + pass + + @staticmethod + def from_proto(data_source: DataSourceProto) -> "MongoDBSource": + assert data_source.HasField("custom_options") + return MongoDBSource( + name=data_source.name, + timestamp_field=data_source.timestamp_field, + created_timestamp_column=data_source.created_timestamp_column, + field_mapping=dict(data_source.field_mapping), + description=data_source.description, + tags=dict(data_source.tags), + owner=data_source.owner, + ) + + def _to_proto_impl(self) -> DataSourceProto: + import json + + return DataSourceProto( + name=self.name, + type=DataSourceProto.CUSTOM_SOURCE, + data_source_class_type="feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBSource", + field_mapping=self.field_mapping, + custom_options=DataSourceProto.CustomSourceOptions( + configuration=json.dumps({"feature_view": self.name}).encode() + ), + description=self.description, + tags=self.tags, + owner=self.owner, + timestamp_field=self.timestamp_field, + created_timestamp_column=self.created_timestamp_column, + ) + + def get_table_query_string(self) -> str: + return self.name + + def get_table_column_names_and_types( + self, config: RepoConfig + ) -> List[Tuple[str, str]]: + """Infer column names and types by reading a sample document from MongoDB.""" + if MongoClient is None: + raise FeastExtrasDependencyImportError("pymongo", "mongodb") + client: Any = MongoClient( + config.offline_store.connection_string, driver=DRIVER_METADATA + ) + try: + coll = client[config.offline_store.database][ + config.offline_store.collection + ] + doc = coll.find_one({"feature_view": self.feature_view_name}) + if doc is None: + return [] + result: List[Tuple[str, str]] = [] + # Entity key is binary — join keys are inferred from the FeatureView, + # not from the document. Expose event_timestamp and created_at. + if "event_timestamp" in doc: + result.append(("event_timestamp", "datetime")) + if "created_at" in doc: + result.append(("created_at", "datetime")) + features = doc.get("features", {}) + if isinstance(features, dict): + for k, v in features.items(): + if isinstance(v, bool): + result.append((k, "bool")) + elif isinstance(v, int): + result.append((k, "int64")) + elif isinstance(v, float): + result.append((k, "float64")) + elif isinstance(v, str): + result.append((k, "string")) + elif isinstance(v, list): + result.append((k, "list")) + elif isinstance(v, dict): + result.append((k, "dict")) + else: + result.append((k, "object")) + return result + finally: + client.close() + + @staticmethod + def source_datatype_to_feast_value_type() -> Callable[[str], ValueType]: + return mongodb_to_feast_value_type + + +# --------------------------------------------------------------------------- +# Retrieval job +# --------------------------------------------------------------------------- + + +class MongoDBRetrievalJob(RetrievalJob): + def __init__( + self, + query_fn: Callable[[], pyarrow.Table], + full_feature_names: bool, + config: RepoConfig, + metadata: Optional[RetrievalMetadata] = None, + ): + self._query_fn = query_fn + self._full_feature_names = full_feature_names + self._config = config + self._metadata = metadata + + @property + def full_feature_names(self) -> bool: + return self._full_feature_names + + @property + def on_demand_feature_views(self) -> List[Any]: + return [] + + @property + def metadata(self) -> Optional[RetrievalMetadata]: + return self._metadata + + def _to_arrow_internal(self, timeout: Optional[int] = None) -> pyarrow.Table: + return self._query_fn() + + def persist( + self, + storage: SavedDatasetStorage, + allow_overwrite: bool = False, + timeout: Optional[int] = None, + ) -> None: + import os + + from feast.infra.offline_stores.file_source import SavedDatasetFileStorage + + if isinstance(storage, SavedDatasetFileStorage): + path = storage.file_options.uri + elif hasattr(storage, "path"): + path = storage.path # type: ignore[union-attr] + else: + raise ValueError( + f"MongoDBRetrievalJob.persist does not support " + f"{type(storage).__name__!r}. Use SavedDatasetFileStorage." + ) + + if not allow_overwrite and os.path.exists(path): + raise SavedDatasetLocationAlreadyExists(location=path) + self.to_df().to_parquet(path) + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _fetch_documents( + client: Any, db_name: str, collection_name: str, pipeline: List[Dict] +) -> List[Dict]: + db = client[db_name] + return list(db[collection_name].aggregate(pipeline)) + + +def _serialize_entity_key_from_row( + row: pd.Series, + join_keys: List[str], + entity_key_version: int, + join_key_types: Dict[str, ValueType], +) -> bytes: + entity_key = EntityKeyProto() + for jk in sorted(join_keys): + val = row[jk] + entity_key.join_keys.append(jk) + proto_val = ValueProto() + vtype = join_key_types.get(jk, ValueType.UNKNOWN) + if vtype == ValueType.INT32: + proto_val.int32_val = int(val) + elif vtype == ValueType.INT64 or isinstance(val, int): + proto_val.int64_val = int(val) + elif vtype == ValueType.STRING or isinstance(val, str): + proto_val.string_val = str(val) + elif isinstance(val, float): + proto_val.double_val = float(val) + else: + proto_val.int64_val = int(val) + entity_key.entity_values.append(proto_val) + return serialize_entity_key(entity_key, entity_key_version) + + +def _expand_entity_id_column( + df: pd.DataFrame, + join_key_columns: List[str], + entity_key_version: int, +) -> pd.DataFrame: + """Deserialize ``entity_id`` bytes into individual join key columns. + + Each ``entity_id`` value is deserialized via ``deserialize_entity_key`` + and the resulting join key names/values are added as new columns. + The ``entity_id`` column is then dropped. + """ + if "entity_id" not in df.columns or df.empty: + return df + + def _extract(eid_bytes: bytes) -> Dict[str, Any]: + ek = deserialize_entity_key(eid_bytes, entity_key_version) + row: Dict[str, Any] = {} + for key, val in zip(ek.join_keys, ek.entity_values): + which = val.WhichOneof("val") + row[key] = getattr(val, which) if which else None + return row + + expanded = pd.DataFrame([_extract(eid) for eid in df["entity_id"]]) + # Only keep the columns the caller asked for (in case the serialized + # key contains more keys than expected). + for col in join_key_columns: + if col in expanded.columns: + df[col] = expanded[col].values + df = df.drop(columns=["entity_id"], errors="ignore") + return df + + +# --------------------------------------------------------------------------- +# Offline store +# --------------------------------------------------------------------------- + + +class MongoDBOfflineStore(OfflineStore): + """MongoDB offline store using a single collection and grouped aggregation. + + Key optimizations: + - Collapsing K feature-view queries into one aggregation per join-key group + - Using server-side ``$group`` (O(log P) with index) for the scoring path + """ + + @staticmethod + def _ensure_indexes(client: Any, db_name: str, collection_name: str) -> None: + """Create the compound index that enables O(log P) per-entity lookups.""" + collection = client[db_name][collection_name] + target_key = [ + ("entity_id", ASCENDING), + ("feature_view", ASCENDING), + ("event_timestamp", DESCENDING), + ("created_at", DESCENDING), + ] + existing = collection.index_information() + for idx_info in existing.values(): + if idx_info.get("key") == target_key: + return + collection.create_index(target_key, name="entity_fv_ts_idx", background=True) + + @staticmethod + def _get_client_and_ensure_indexes(config: RepoConfig) -> Any: + if MongoClient is None: + raise FeastExtrasDependencyImportError("pymongo", "mongodb") + conn_str = config.offline_store.connection_string + db_name = config.offline_store.database + collection = config.offline_store.collection + cache_key = f"{conn_str}/{db_name}/{collection}" + client: Any = MongoClient(conn_str, driver=DRIVER_METADATA) + if cache_key not in _indexes_ensured: + MongoDBOfflineStore._ensure_indexes(client, db_name, collection) + _indexes_ensured.add(cache_key) + return client + + @staticmethod + def pull_latest_from_table_or_query( + config: RepoConfig, + data_source: DataSource, + join_key_columns: List[str], + feature_name_columns: List[str], + timestamp_field: str, + created_timestamp_column: Optional[str], + start_date: datetime, + end_date: datetime, + ) -> RetrievalJob: + if not isinstance(data_source, MongoDBSource): + raise ValueError( + f"MongoDBOfflineStore expected MongoDBSource, " + f"got {type(data_source).__name__!r}." + ) + db_name = config.offline_store.database + collection = config.offline_store.collection + feature_view_name = data_source.feature_view_name + start_utc = start_date.astimezone(tz=timezone.utc) + end_utc = end_date.astimezone(tz=timezone.utc) + + project_stage: Dict[str, Any] = { + "_id": 0, + "entity_id": "$doc.entity_id", + "event_timestamp": "$doc.event_timestamp", + } + if created_timestamp_column: + project_stage["created_at"] = "$doc.created_at" + for feat in feature_name_columns: + project_stage[feat] = f"$doc.features.{feat}" + + pipeline: List[Dict[str, Any]] = [ + { + "$match": { + "feature_view": feature_view_name, + "event_timestamp": {"$gte": start_utc, "$lte": end_utc}, + } + }, + {"$sort": {"entity_id": 1, "event_timestamp": -1, "created_at": -1}}, + {"$group": {"_id": "$entity_id", "doc": {"$first": "$$ROOT"}}}, + {"$project": project_stage}, + ] + + entity_key_version = config.entity_key_serialization_version + + def _run() -> pyarrow.Table: + client = MongoDBOfflineStore._get_client_and_ensure_indexes(config) + try: + docs = _fetch_documents(client, db_name, collection, pipeline) + if not docs: + return pyarrow.Table.from_pydict({}) + df = pd.DataFrame(docs) + df = _expand_entity_id_column(df, join_key_columns, entity_key_version) + if not df.empty and "event_timestamp" in df.columns: + if df["event_timestamp"].dt.tz is None: + df["event_timestamp"] = pd.to_datetime( + df["event_timestamp"], utc=True + ) + return pyarrow.Table.from_pandas(df, preserve_index=False) + finally: + client.close() + + return MongoDBRetrievalJob( + query_fn=_run, full_feature_names=False, config=config + ) + + @staticmethod + def pull_all_from_table_or_query( + config: RepoConfig, + data_source: DataSource, + join_key_columns: List[str], + feature_name_columns: List[str], + timestamp_field: str, + created_timestamp_column: Optional[str] = None, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + ) -> RetrievalJob: + if not isinstance(data_source, MongoDBSource): + raise ValueError( + f"MongoDBOfflineStore expected MongoDBSource, " + f"got {type(data_source).__name__!r}." + ) + db_name = config.offline_store.database + collection = config.offline_store.collection + feature_view_name = data_source.feature_view_name + match_filter: Dict[str, Any] = {"feature_view": feature_view_name} + if start_date or end_date: + ts_filter: Dict[str, Any] = {} + if start_date: + ts_filter["$gte"] = start_date.astimezone(tz=timezone.utc) + if end_date: + ts_filter["$lte"] = end_date.astimezone(tz=timezone.utc) + match_filter["event_timestamp"] = ts_filter + project_stage: Dict[str, Any] = {"_id": 0, "entity_id": 1, "event_timestamp": 1} + if created_timestamp_column: + project_stage["created_at"] = 1 + for feat in feature_name_columns: + project_stage[feat] = f"$features.{feat}" + pipeline = [{"$match": match_filter}, {"$project": project_stage}] + entity_key_version = config.entity_key_serialization_version + + def _run() -> pyarrow.Table: + client = MongoDBOfflineStore._get_client_and_ensure_indexes(config) + try: + docs = _fetch_documents(client, db_name, collection, pipeline) + if not docs: + return pyarrow.Table.from_pydict({}) + df = pd.DataFrame(docs) + df = _expand_entity_id_column(df, join_key_columns, entity_key_version) + if not df.empty and "event_timestamp" in df.columns: + if df["event_timestamp"].dt.tz is None: + df["event_timestamp"] = pd.to_datetime( + df["event_timestamp"], utc=True + ) + return pyarrow.Table.from_pandas(df, preserve_index=False) + finally: + client.close() + + return MongoDBRetrievalJob( + query_fn=_run, full_feature_names=False, config=config + ) + + @staticmethod + def get_historical_features( + config: RepoConfig, + feature_views: List[FeatureView], + feature_refs: List[str], + entity_df: Union[pd.DataFrame, str], + registry: BaseRegistry, + project: str, + full_feature_names: bool = False, + strict_pit: bool = True, + ) -> RetrievalJob: + """Fetch historical features using grouped aggregation. + + Groups feature views by join key signature so that FVs sharing the + same entity key are handled in a single MongoDB aggregation instead + of K separate queries. + + Scoring path (unique entity IDs in entity_df): + Uses ``$match + $sort + $group`` — server returns at most one + document per (entity_id, feature_view). The compound index + makes per-entity cost O(log P). Python post-filters the result. + + Training path (repeated entity IDs at different timestamps): + Omits ``$group`` and uses ``merge_asof`` in Python, matching + standard PIT behaviour. + + Args: + strict_pit: When True (default) features whose document timestamp + is strictly after the entity request timestamp are returned as + NULL — this is the safe training/evaluation default. Set to + False for real-time scoring where you want the most recent + observation even if it post-dates the nominal request time. + """ + if isinstance(entity_df, str): + raise ValueError( + "MongoDBOfflineStore does not support SQL entity_df strings." + ) + + db_name = config.offline_store.database + feature_collection = config.offline_store.collection + entity_key_version = config.entity_key_serialization_version + + entity_schema = dict(zip(entity_df.columns, entity_df.dtypes)) + event_timestamp_col = infer_event_timestamp_from_entity_df(entity_schema) + + # Feature refs use projection names (e.g. "origin:temperature") + fv_to_features: Dict[str, List[str]] = defaultdict(list) + for ref in feature_refs: + fv_name, feat_name = ref.split(":", 1) + fv_to_features[fv_name].append(feat_name) + + # All dicts keyed by projection name (name_to_use), not fv.name, + # because entity mapping creates multiple projections of the same FV. + fv_by_proj: Dict[str, FeatureView] = { + fv.projection.name_to_use(): fv for fv in feature_views + } + + # projection_name → MongoDB feature_view discriminator value + # (the data source name, NOT the FeatureView name) + fv_mongo_name: Dict[str, str] = {} + for fv in feature_views: + proj = fv.projection.name_to_use() + src = fv.batch_source + fv_mongo_name[proj] = ( + src.feature_view_name + if isinstance(src, MongoDBSource) + else getattr(src, "name", fv.name) + ) + + # projection_name → mapped join keys (as in entity_df columns) + fv_mapped_join_keys: Dict[str, List[str]] = { + fv.projection.name_to_use(): list( + get_expected_join_keys(project, [fv], registry) + ) + for fv in feature_views + } + + # projection_name → {mapped_key → original_key} + fv_reverse_jk: Dict[str, Dict[str, str]] = { + fv.projection.name_to_use(): { + v: k for k, v in fv.projection.join_key_map.items() + } + for fv in feature_views + } + + # projection_name → original join key types (keyed by original name) + fv_jk_types_original: Dict[str, Dict[str, ValueType]] = { + fv.projection.name_to_use(): { + ec.name: ec.dtype.to_value_type() for ec in fv.entity_columns + } + for fv in feature_views + } + + # projection_name → reverse field_mapping (feast_name → source_col_name) + fv_reverse_fm: Dict[str, Dict[str, str]] = {} + for fv in feature_views: + proj = fv.projection.name_to_use() + fm = fv.batch_source.field_mapping if fv.batch_source else {} + fv_reverse_fm[proj] = {v: k for k, v in fm.items()} if fm else {} + + CHUNK_SIZE = _CHUNK_SIZE + MONGO_BATCH_SIZE = _MONGO_BATCH_SIZE + + def _chunk_dataframe( + df: pd.DataFrame, size: int + ) -> Generator[pd.DataFrame, None, None]: + for i in range(0, len(df), size): + yield df.iloc[i : i + size] + + def _run_single(entity_subset_df: pd.DataFrame, coll: Any) -> pd.DataFrame: + result = entity_subset_df.copy() + if not pd.api.types.is_datetime64_any_dtype(result[event_timestamp_col]): + result[event_timestamp_col] = pd.to_datetime( + result[event_timestamp_col], utc=True + ) + elif result[event_timestamp_col].dt.tz is None: + result[event_timestamp_col] = pd.to_datetime( + result[event_timestamp_col], utc=True + ) + + max_ts = result[event_timestamp_col].max() + min_ts = result[event_timestamp_col].min() + + # Process each feature view projection independently. + # (Different projections of the same FV have different + # entity key mappings and must be handled separately.) + for proj_name, features in fv_to_features.items(): + fv = fv_by_proj.get(proj_name) + if fv is None: + for feat in features: + col = f"{proj_name}__{feat}" if full_feature_names else feat + result[col] = None + continue + + mongo_fv_name = fv_mongo_name[proj_name] + mapped_keys = fv_mapped_join_keys[proj_name] + reverse_jk = fv_reverse_jk[proj_name] + orig_key_types = fv_jk_types_original[proj_name] + reverse_fm = fv_reverse_fm[proj_name] + + # Serialize entity keys: read values from MAPPED columns in + # entity_df, but serialize with ORIGINAL join key names to + # match the bytes stored in MongoDB. + _mk = mapped_keys + _rjk = reverse_jk + _okt = orig_key_types + + def _ser(row, __mk=_mk, __rjk=_rjk, __okt=_okt): + ek = EntityKeyProto() + orig_keys = sorted([__rjk.get(m, m) for m in __mk]) + o2m = {__rjk.get(m, m): m for m in __mk} + for ok in orig_keys: + mk = o2m[ok] + val = row[mk] + ek.join_keys.append(ok) + pv = ValueProto() + vt = __okt.get(ok, ValueType.UNKNOWN) + if vt == ValueType.INT32: + pv.int32_val = int(val) + elif vt == ValueType.INT64 or isinstance(val, int): + pv.int64_val = int(val) + elif vt == ValueType.STRING or isinstance(val, str): + pv.string_val = str(val) + elif isinstance(val, float): + pv.double_val = float(val) + else: + pv.int64_val = int(val) + ek.entity_values.append(pv) + return serialize_entity_key(ek, entity_key_version) + + eid_col = f"_eid_{proj_name}" + result[eid_col] = result.apply(_ser, axis=1) + unique_eids = result[eid_col].unique().tolist() + + # Detect scoring vs training path per-FV. + # + # The scoring path ($group $first) requires unique entity + # IDs for THIS FV — otherwise $group discards rows that + # share an entity_id. + # + # When strict_pit=True, there is an additional constraint: + # all entity request timestamps must be identical. The + # $match uses $lte: max_ts which is correct only when + # every entity shares the same request time. When + # timestamps differ, $group may pick a doc that is after + # a specific entity's request time; the Python future_mask + # would null it, but the valid older doc was already + # discarded by $group. + # + # When strict_pit=False, there is no $lte filter and no + # future_mask — we want the globally latest doc per entity + # regardless of request time, so $group $first is always + # correct. + unique_entities = result[eid_col].nunique() == len(result) + scoring_path = unique_entities and ( + not strict_pit or result[event_timestamp_col].nunique() == 1 + ) + + # TTL filter — use min_ts for the lower bound so that + # documents needed for early entity rows are included. + # Per-row TTL enforcement happens in the merge_asof path. + fv_ttl = fv.ttl if fv else None + ts_filter: Dict[str, Any] = {"$lte": max_ts} if strict_pit else {} + if fv_ttl: + lower_ref = min_ts if strict_pit else datetime.now(tz=timezone.utc) + ts_filter["$gte"] = lower_ref - fv_ttl + + # Query MongoDB + all_docs: List[Dict] = [] + for i in range(0, len(unique_eids), MONGO_BATCH_SIZE): + batch_ids = unique_eids[i : i + MONGO_BATCH_SIZE] + match_q: Dict[str, Any] = { + "entity_id": {"$in": batch_ids}, + "feature_view": mongo_fv_name, + } + if ts_filter: + match_q["event_timestamp"] = ts_filter + + if scoring_path: + pipeline: List[Dict] = [ + {"$match": match_q}, + { + "$sort": { + "entity_id": 1, + "event_timestamp": -1, + "created_at": -1, + } + }, + { + "$group": { + "_id": "$entity_id", + "event_timestamp": {"$first": "$event_timestamp"}, + "features": {"$first": "$features"}, + "created_at": {"$first": "$created_at"}, + } + }, + { + "$project": { + "_id": 0, + "entity_id": "$_id", + "event_timestamp": 1, + "features": 1, + "created_at": 1, + } + }, + ] + else: + pipeline = [{"$match": match_q}] + + all_docs.extend(list(coll.aggregate(pipeline))) + + if not all_docs: + for feat in features: + col = f"{proj_name}__{feat}" if full_feature_names else feat + result[col] = None + result = result.drop(columns=[eid_col], errors="ignore") + continue + + fv_df = pd.DataFrame(all_docs) + fv_df = fv_df.rename(columns={"entity_id": eid_col}) + + # Extract features from nested dict, applying reverse field_mapping. + # Using .apply() instead of json_normalize preserves complex types + # (dicts for Map/Struct, lists for Array). + if "features" in fv_df.columns: + for feat in features: + src_col = reverse_fm.get(feat, feat) + fv_df[feat] = fv_df["features"].apply( + lambda d, _s=src_col: ( + d.get(_s) if isinstance(d, dict) else None + ) + ) + fv_df = fv_df.drop(columns=["features"]) + + if fv_df["event_timestamp"].dt.tz is None: + fv_df["event_timestamp"] = pd.to_datetime( + fv_df["event_timestamp"], utc=True + ) + + if scoring_path: + fv_join_cols = [eid_col, "event_timestamp"] + [ + f for f in features if f in fv_df.columns + ] + fv_join = fv_df[fv_join_cols].rename( + columns={"event_timestamp": "_fv_ts"} + ) + merged = result[[eid_col, event_timestamp_col]].merge( + fv_join, on=eid_col, how="left" + ) + if strict_pit: + future_mask = merged["_fv_ts"] > merged[event_timestamp_col] + else: + future_mask = pd.Series( + [False] * len(merged), index=merged.index + ) + if fv_ttl: + ttl_mask = merged["_fv_ts"] < ( + merged[event_timestamp_col] - fv_ttl + ) + bad_mask = future_mask | ttl_mask + else: + bad_mask = future_mask + for feat in features: + col = f"{proj_name}__{feat}" if full_feature_names else feat + vals = ( + merged[feat].copy() + if feat in merged.columns + else pd.Series([None] * len(merged), dtype=object) + ) + vals[bad_mask | merged["_fv_ts"].isna()] = None + result[col] = vals.values + else: + # merge_asof path (training data) + result = result.sort_values(event_timestamp_col).reset_index( + drop=True + ) + fv_df = fv_df.sort_values( + ["event_timestamp", "created_at"] + ).reset_index(drop=True) + merge_cols = [eid_col, "event_timestamp"] + [ + f for f in features if f in fv_df.columns + ] + fv_df_subset = fv_df[ + [c for c in merge_cols if c in fv_df.columns] + ].copy() + fv_df_subset = fv_df_subset.rename( + columns={"event_timestamp": "_fv_ts"} + ) + fv_prefix = f"__fv_{proj_name}__" + fv_df_subset = fv_df_subset.rename( + columns={ + f: f"{fv_prefix}{f}" + for f in features + if f in fv_df_subset.columns + } + ) + result = pd.merge_asof( + result, + fv_df_subset, + left_on=event_timestamp_col, + right_on="_fv_ts", + by=eid_col, + direction="backward", + ) + if fv_ttl: + cutoff = result[event_timestamp_col] - fv_ttl + stale = result["_fv_ts"] < cutoff + for feat in features: + tc = f"{fv_prefix}{feat}" + if tc in result.columns: + result.loc[stale, tc] = None + for feat in features: + tc = f"{fv_prefix}{feat}" + col = f"{proj_name}__{feat}" if full_feature_names else feat + if tc in result.columns: + if col in result.columns: + result = result.drop(columns=[col]) + result = result.rename(columns={tc: col}) + elif col not in result.columns: + result[col] = None + result = result.drop(columns=["_fv_ts"], errors="ignore") + + result = result.drop(columns=[eid_col], errors="ignore") + + return result + + def _run() -> pyarrow.Table: + working_df = entity_df.copy() + working_df["_row_idx"] = range(len(working_df)) + + client = MongoDBOfflineStore._get_client_and_ensure_indexes(config) + try: + coll = client[db_name][feature_collection] + if len(working_df) <= CHUNK_SIZE: + result_df = _run_single(working_df, coll) + else: + chunks = [ + _run_single(chunk, coll) + for chunk in _chunk_dataframe(working_df, CHUNK_SIZE) + ] + result_df = pd.concat(chunks, ignore_index=True) + finally: + client.close() + + result_df = result_df.sort_values("_row_idx").reset_index(drop=True) + result_df = result_df.drop(columns=["_row_idx"], errors="ignore") + + if not result_df.empty and event_timestamp_col in result_df.columns: + if result_df[event_timestamp_col].dt.tz is None: + result_df[event_timestamp_col] = pd.to_datetime( + result_df[event_timestamp_col], utc=True + ) + + return pyarrow.Table.from_pandas(result_df, preserve_index=False) + + return MongoDBRetrievalJob( + query_fn=_run, + full_feature_names=full_feature_names, + config=config, + ) + + @staticmethod + def offline_write_batch( + config: RepoConfig, + feature_view: FeatureView, + table: pyarrow.Table, + progress: Optional[Callable[[int], Any]], + ) -> None: + """Write a batch of feature observations into the feature_history collection. + + Each row in *table* is stored as one document:: + + { + "entity_id": , + "feature_view": , + "features": {: , ...}, + "event_timestamp": , + "created_at": , + } + + Writes are append-only (no upsert). Conflict resolution at read time: + pull_latest picks the highest ``created_at``; the scoring path + ``$sort created_at DESC`` → ``$group $first`` also picks the highest. + + Args: + config: Feast repo configuration. + feature_view: The feature view being written; must have a + MongoDBSource batch source. + table: Arrow table with join key columns, feature columns, + ``event_timestamp``, and optionally ``created_at``. + progress: Optional callback invoked with the row count after each + batch insert. + """ + if not isinstance(feature_view.batch_source, MongoDBSource): + raise ValueError( + f"MongoDBOfflineStore.offline_write_batch expected a MongoDBSource " + f"batch source, got {type(feature_view.batch_source).__name__!r}." + ) + + entity_key_version = config.entity_key_serialization_version + db_name = config.offline_store.database + collection_name = config.offline_store.collection + + # Use original (unmapped) join key names so that the serialized + # entity_id bytes match those produced by get_historical_features, + # which also serializes with original names (see _ser at line ~662). + join_key_types: Dict[str, ValueType] = { + ec.name: ec.dtype.to_value_type() for ec in feature_view.entity_columns + } + join_keys = list(join_key_types.keys()) + + timestamp_field = feature_view.batch_source.timestamp_field + created_ts_col: Optional[str] = ( + feature_view.batch_source.created_timestamp_column or None + ) + + reserved = set(join_keys) | {timestamp_field} + if created_ts_col: + reserved.add(created_ts_col) + feature_cols = [c for c in table.column_names if c not in reserved] + + df = table.to_pandas() + + for ts_col in [timestamp_field] + ([created_ts_col] if created_ts_col else []): + if ts_col in df.columns: + if not pd.api.types.is_datetime64_any_dtype(df[ts_col]): + df[ts_col] = pd.to_datetime(df[ts_col], utc=True) + elif df[ts_col].dt.tz is None: + df[ts_col] = df[ts_col].dt.tz_localize("UTC") + + df["_entity_id"] = df.apply( + lambda row: _serialize_entity_key_from_row( + row, join_keys, entity_key_version, join_key_types + ), + axis=1, + ) + + now = datetime.now(tz=timezone.utc) + + # Use the batch source name as the MongoDB discriminator so that + # data written via push/write_to_offline_store lands in the same + # collection partition as the initial ingest from create_data_source. + mongo_fv_name = feature_view.batch_source.feature_view_name + + docs = [] + for _, row in df.iterrows(): + features: Dict[str, Any] = {} + for col in feature_cols: + val = row[col] + try: + is_na = pd.isna(val) + if isinstance(is_na, bool) and is_na: + continue + except (ValueError, TypeError): + pass # non-scalar (list/array) — not NA + if hasattr(val, "item"): + val = val.item() + features[col] = val + + created_at = now + if created_ts_col and created_ts_col in df.columns: + ct = row[created_ts_col] + if not pd.isna(ct): + created_at = ( + ct.to_pydatetime() if hasattr(ct, "to_pydatetime") else ct + ) + + docs.append( + { + "entity_id": row["_entity_id"], + "feature_view": mongo_fv_name, + "features": features, + "event_timestamp": ( + row[timestamp_field].to_pydatetime() + if hasattr(row[timestamp_field], "to_pydatetime") + else row[timestamp_field] + ), + "created_at": created_at, + } + ) + + client = MongoDBOfflineStore._get_client_and_ensure_indexes(config) + try: + coll = client[db_name][collection_name] + BATCH_SIZE = 10_000 + for i in range(0, len(docs), BATCH_SIZE): + batch = docs[i : i + BATCH_SIZE] + coll.insert_many(batch, ordered=False) + if progress: + progress(len(batch)) + finally: + client.close() diff --git a/sdk/python/feast/infra/offline_stores/contrib/oracle_offline_store/oracle.py b/sdk/python/feast/infra/offline_stores/contrib/oracle_offline_store/oracle.py index d76335a62a1..25517fa74c3 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/oracle_offline_store/oracle.py +++ b/sdk/python/feast/infra/offline_stores/contrib/oracle_offline_store/oracle.py @@ -1,6 +1,7 @@ -from datetime import datetime, timedelta, timezone +import json +from datetime import date, datetime, timezone from pathlib import Path -from typing import Any, Callable, List, Literal, Optional, Union +from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union import ibis import pandas as pd @@ -22,8 +23,21 @@ write_logged_features_ibis, ) from feast.infra.offline_stores.offline_store import OfflineStore, RetrievalJob +from feast.infra.offline_stores.offline_utils import get_timestamp_filter_sql from feast.infra.registry.base_registry import BaseRegistry +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.repo_config import FeastConfigBaseModel, RepoConfig +from feast.utils import compute_non_entity_date_range def get_ibis_connection(config: RepoConfig): @@ -153,35 +167,6 @@ def _validate_connection_params(self): return self -def _resolve_date_range( - start_date: Optional[datetime], - end_date: Optional[datetime], - feature_views: List[FeatureView], -) -> tuple: - """Resolve start/end dates to a UTC-aware range, using TTL as a fallback window.""" - if end_date is None: - end_date = datetime.now(tz=timezone.utc) - elif end_date.tzinfo is None: - end_date = end_date.replace(tzinfo=timezone.utc) - - if start_date is None: - max_ttl_seconds = max( - ( - int(fv.ttl.total_seconds()) - for fv in feature_views - if fv.ttl and isinstance(fv.ttl, timedelta) - ), - default=0, - ) - start_date = end_date - timedelta( - seconds=max_ttl_seconds if max_ttl_seconds > 0 else 30 * 86400 - ) - elif start_date.tzinfo is None: - start_date = start_date.replace(tzinfo=timezone.utc) - - return start_date, end_date - - def _build_entity_df_from_feature_sources( con, feature_views: List[FeatureView], @@ -207,6 +192,299 @@ def _build_entity_df_from_feature_sources( return pd.concat(entity_dfs, ignore_index=True).drop_duplicates() +# ------------------------------------------------------------------ # +# Oracle monitoring helpers +# ------------------------------------------------------------------ # + + +def _oracle_quote_ident(name: str) -> str: + return f'"{name}"' + + +def _oracle_ts_where(ts_filter: str) -> str: + return f"({ts_filter})" if (ts_filter and ts_filter.strip()) else "1=1" + + +def _oracle_fetchall(con, sql: str): + cur = con.raw_sql(sql) + try: + return cur.fetchall() + finally: + if hasattr(cur, "close"): + cur.close() + + +def _oracle_exec(con, sql: str) -> None: + cur = con.raw_sql(sql) + try: + pass + finally: + if hasattr(cur, "close"): + cur.close() + + +def _oracle_numeric_histogram( + con, + from_expression: str, + col_name: str, + ts_filter: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = _oracle_quote_ident(col_name) + + if min_val == max_val: + tw = _oracle_ts_where(ts_filter) + cnt_row = _oracle_fetchall( + con, + f"SELECT COUNT(*) FROM {from_expression} _src " + f"WHERE {q_col} IS NOT NULL AND {tw}", + ) + cnt = (cnt_row[0][0] if cnt_row else 0) or 0 + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + upper = max_val + (max_val - min_val) * 1e-10 + bin_width = (max_val - min_val) / bins + bw = bin_width if bin_width != 0 else 1e-300 + + tw = _oracle_ts_where(ts_filter) + query = ( + f"SELECT bucket, COUNT(*) AS cnt FROM (" + f" SELECT " + f" CASE WHEN {q_col} IS NULL THEN NULL " + f" WHEN {min_val} = {upper} THEN 1 " + f" ELSE LEAST(GREATEST(" + f" FLOOR((CAST({q_col} AS NUMBER) - {min_val}) / {bw}) + 1, " + f" 1), {bins}) " + f" END AS bucket " + f" FROM {from_expression} _src " + f" WHERE {q_col} IS NOT NULL AND {tw}" + f") sub " + f"WHERE bucket IS NOT NULL " + f"GROUP BY bucket ORDER BY bucket" + ) + + rows = _oracle_fetchall(con, query) + counts = [0] * bins + for bucket, cnt in rows: + b = int(bucket) + if 1 <= b <= bins: + counts[b - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _oracle_numeric_stats( + con, + from_expression: str, + feature_names: List[str], + ts_filter: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + select_parts = ["COUNT(*)"] + for col in feature_names: + q = _oracle_quote_ident(col) + c = f"CAST({q} AS NUMBER)" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY {c})", + ] + ) + + tw = _oracle_ts_where(ts_filter) + query = f"SELECT {', '.join(select_parts)} FROM {from_expression} _src WHERE {tw}" + + row = (_oracle_fetchall(con, query) or [None])[0] + + if row is None: + return [empty_numeric_metric(n) for n in feature_names] + + row_count = row[0] + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = row[base] or 0 + null_count = row_count - non_null + + min_val = opt_float(row[base + 3]) + max_val = opt_float(row[base + 4]) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[base + 1]), + "stddev": opt_float(row[base + 2]), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(row[base + 5]), + "p75": opt_float(row[base + 6]), + "p90": opt_float(row[base + 7]), + "p95": opt_float(row[base + 8]), + "p99": opt_float(row[base + 9]), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _oracle_numeric_histogram( + con, + from_expression, + col, + ts_filter, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _oracle_categorical_stats( + con, + from_expression: str, + col_name: str, + ts_filter: str, + top_n: int, +) -> Dict[str, Any]: + q_col = _oracle_quote_ident(col_name) + + tw = _oracle_ts_where(ts_filter) + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expression} _src WHERE {tw}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" TO_CHAR({q_col}) AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} " + f"ORDER BY cnt DESC " + f"FETCH FIRST {int(top_n)} ROWS ONLY" + ) + + rows = _oracle_fetchall(con, query) + + if not rows: + return empty_categorical_metric(col_name) + + row_count = rows[0][0] + null_count = rows[0][1] + unique_count = rows[0][2] + + top_entries = [{"value": r[3], "count": r[4]} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +def _oracle_escape_literal(val: Any) -> str: + if val is None: + return "NULL" + if isinstance(val, bool): + return "1" if val else "0" + if isinstance(val, (int, float)) and not isinstance(val, bool): + return str(val) + if isinstance(val, datetime): + s = val.isoformat(sep=" ", timespec="seconds") + return f"TIMESTAMP '{s}'" + if isinstance(val, date): + return f"DATE '{val.isoformat()}'" + s = str(val).replace("'", "''") + return f"'{s}'" + + +def _oracle_merge_metric_row( + con, table: str, columns: List[str], pk_cols: List[str], row: Dict[str, Any] +) -> None: + def qid(c: str) -> str: + return f'"{c}"' + + non_pk = [c for c in columns if c not in pk_cols] + vals = [] + for c in columns: + v = row.get(c) + if c == "histogram" and v is not None and not isinstance(v, str): + v = json.dumps(v) + vals.append(_oracle_escape_literal(v)) + + join_cond = " AND ".join(f"t.{qid(c)} = s.{qid(c)}" for c in pk_cols) + insert_cols = ", ".join(qid(c) for c in columns) + insert_vals = ", ".join(f"s.{qid(c)}" for c in columns) + update_set = ", ".join(f"t.{qid(c)} = s.{qid(c)}" for c in non_pk) + + src_select = ", ".join( + f"{vals[i]} AS {qid(columns[i])}" for i in range(len(columns)) + ) + + sql = ( + f"MERGE INTO {table} t " + f"USING (SELECT {src_select} FROM dual) s " + f"ON ({join_cond}) " + f"WHEN MATCHED THEN UPDATE SET {update_set} " + f"WHEN NOT MATCHED THEN INSERT ({insert_cols}) VALUES ({insert_vals})" + ) + _oracle_exec(con, sql) + + +def _oracle_try_execute_ddl(con, ddl: str) -> None: + """Run DDL; ignore ORA-00955 (name already used).""" + escaped = ddl.strip().replace("'", "''") + plsql = ( + "BEGIN\n" + f" EXECUTE IMMEDIATE '{escaped}';\n" + "EXCEPTION\n" + " WHEN OTHERS THEN\n" + " IF SQLCODE != -955 THEN RAISE;\n" + " END IF;\n" + "END;" + ) + _oracle_exec(con, plsql) + + class OracleOfflineStore(OfflineStore): @staticmethod def pull_latest_from_table_or_query( @@ -219,7 +497,6 @@ def pull_latest_from_table_or_query( start_date: datetime, end_date: datetime, ) -> RetrievalJob: - con = get_ibis_connection(config) return pull_latest_from_table_or_query_ibis( @@ -254,10 +531,10 @@ def get_historical_features( # Handle non-entity retrieval mode (start_date/end_date only) if entity_df is None: - start_date, end_date = _resolve_date_range( + start_date, end_date = compute_non_entity_date_range( + feature_views, start_date=kwargs.get("start_date"), end_date=kwargs.get("end_date"), - feature_views=feature_views, ) entity_df = _build_entity_df_from_feature_sources( con, feature_views, start_date, end_date @@ -335,3 +612,289 @@ def write_logged_features( logging_config=logging_config, registry=registry, ) + + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + assert isinstance(data_source, OracleSource) + + from_expression = data_source.get_table_query_string() + ts_filter = get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + tz=timezone.utc, + cast_style="timestamp", + date_time_separator=" ", + ) + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + con = get_ibis_connection(config) + + if numeric_features: + results.extend( + _oracle_numeric_stats( + con, + from_expression, + numeric_features, + ts_filter, + histogram_bins, + ) + ) + + for col_name in categorical_features: + results.append( + _oracle_categorical_stats( + con, + from_expression, + col_name, + ts_filter, + top_n, + ) + ) + + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + assert isinstance(data_source, OracleSource) + + from_expression = data_source.get_table_query_string() + ts_col = _oracle_quote_ident(timestamp_field) + + con = get_ibis_connection(config) + rows = _oracle_fetchall( + con, + f"SELECT MAX({ts_col}) FROM {from_expression} _src", + ) + row = rows[0] if rows else None + + if row is None or row[0] is None: + return None + val = row[0] + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + if isinstance(val, date): + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + return None + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + con = get_ibis_connection(config) + + _oracle_try_execute_ddl( + con, + f""" + CREATE TABLE {MON_TABLE_FEATURE} ( + project_id VARCHAR2(255) NOT NULL, + feature_view_name VARCHAR2(255) NOT NULL, + feature_name VARCHAR2(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR2(20) DEFAULT 'daily' NOT NULL, + data_source_type VARCHAR2(50) DEFAULT 'batch' NOT NULL, + computed_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, + is_baseline NUMBER(1) DEFAULT 0 NOT NULL, + feature_type VARCHAR2(50) NOT NULL, + row_count NUMBER, + null_count NUMBER, + null_rate NUMBER, + mean NUMBER, + stddev NUMBER, + min_val NUMBER, + max_val NUMBER, + p50 NUMBER, + p75 NUMBER, + p90 NUMBER, + p95 NUMBER, + p99 NUMBER, + histogram VARCHAR2(4000), + CONSTRAINT pk_fm PRIMARY KEY (project_id, feature_view_name, + feature_name, metric_date, granularity, data_source_type) + ) + """, + ) + + _oracle_try_execute_ddl( + con, + f""" + CREATE TABLE {MON_TABLE_FEATURE_VIEW} ( + project_id VARCHAR2(255) NOT NULL, + feature_view_name VARCHAR2(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR2(20) DEFAULT 'daily' NOT NULL, + data_source_type VARCHAR2(50) DEFAULT 'batch' NOT NULL, + computed_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, + is_baseline NUMBER(1) DEFAULT 0 NOT NULL, + total_row_count NUMBER, + total_features NUMBER, + features_with_nulls NUMBER, + avg_null_rate NUMBER, + max_null_rate NUMBER, + CONSTRAINT pk_fvm PRIMARY KEY (project_id, feature_view_name, + metric_date, granularity, data_source_type) + ) + """, + ) + + _oracle_try_execute_ddl( + con, + f""" + CREATE TABLE {MON_TABLE_FEATURE_SERVICE} ( + project_id VARCHAR2(255) NOT NULL, + feature_service_name VARCHAR2(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR2(20) DEFAULT 'daily' NOT NULL, + data_source_type VARCHAR2(50) DEFAULT 'batch' NOT NULL, + computed_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, + is_baseline NUMBER(1) DEFAULT 0 NOT NULL, + total_feature_views NUMBER, + total_features NUMBER, + avg_null_rate NUMBER, + max_null_rate NUMBER, + CONSTRAINT pk_fsm PRIMARY KEY (project_id, feature_service_name, + metric_date, granularity, data_source_type) + ) + """, + ) + + _oracle_try_execute_ddl( + con, + f""" + CREATE TABLE {MON_TABLE_JOB} ( + job_id VARCHAR2(36) NOT NULL, + project_id VARCHAR2(255) NOT NULL, + feature_view_name VARCHAR2(255), + job_type VARCHAR2(50) NOT NULL, + status VARCHAR2(20) DEFAULT 'pending' NOT NULL, + parameters VARCHAR2(4000), + metric_date DATE NOT NULL, + started_at TIMESTAMP WITH TIME ZONE, + completed_at TIMESTAMP WITH TIME ZONE, + error_message VARCHAR2(4000), + result_summary VARCHAR2(4000), + CONSTRAINT pk_fmj PRIMARY KEY (job_id) + ) + """, + ) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + + table, columns, pk_columns = monitoring_table_meta(metric_type) + con = get_ibis_connection(config) + for row in metrics: + _oracle_merge_metric_row(con, table, columns, pk_columns, row) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + + table, columns, _ = monitoring_table_meta(metric_type) + + conditions: list = [] + if project: + conditions.append( + f"{_oracle_quote_ident('project_id')} = {_oracle_escape_literal(project)}" + ) + if filters: + for key, value in filters.items(): + if value is not None: + conditions.append( + f"{_oracle_quote_ident(key)} = {_oracle_escape_literal(value)}" + ) + if start_date: + conditions.append( + f"{_oracle_quote_ident('metric_date')} >= {_oracle_escape_literal(start_date)}" + ) + if end_date: + conditions.append( + f"{_oracle_quote_ident('metric_date')} <= {_oracle_escape_literal(end_date)}" + ) + + where_sql = " AND ".join(conditions) if conditions else "1=1" + col_list = ", ".join(_oracle_quote_ident(c) for c in columns) + order_col = "metric_date" if "metric_date" in columns else "job_id" + + con = get_ibis_connection(config) + rows = _oracle_fetchall( + con, + f"SELECT {col_list} FROM {table} WHERE {where_sql} " + f"ORDER BY {_oracle_quote_ident(order_col)} ASC", + ) + + results = [] + for row in rows: + record = dict(zip(columns, row)) + results.append(normalize_monitoring_row(record)) + + return results + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, OracleOfflineStoreConfig) + + conditions = [ + f"{_oracle_quote_ident('project_id')} = {_oracle_escape_literal(project)}" + ] + if feature_view_name: + conditions.append( + f"{_oracle_quote_ident('feature_view_name')} = " + f"{_oracle_escape_literal(feature_view_name)}" + ) + if feature_name: + conditions.append( + f"{_oracle_quote_ident('feature_name')} = " + f"{_oracle_escape_literal(feature_name)}" + ) + if data_source_type: + conditions.append( + f"{_oracle_quote_ident('data_source_type')} = " + f"{_oracle_escape_literal(data_source_type)}" + ) + conditions.append(f"{_oracle_quote_ident('is_baseline')} = 1") + + where_sql = " AND ".join(conditions) + con = get_ibis_connection(config) + _oracle_exec( + con, + f"UPDATE {MON_TABLE_FEATURE} SET {_oracle_quote_ident('is_baseline')} = 0 " + f"WHERE {where_sql}", + ) diff --git a/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/postgres.py b/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/postgres.py index 7c65b649046..d2bbeb90133 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/postgres.py +++ b/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/postgres.py @@ -1,6 +1,6 @@ import contextlib from dataclasses import asdict -from datetime import datetime, timedelta, timezone +from datetime import date, datetime, timezone from enum import Enum from typing import ( Any, @@ -42,11 +42,22 @@ get_query_schema, ) from feast.infra.utils.postgres.postgres_config import PostgreSQLConfig +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.on_demand_feature_view import OnDemandFeatureView from feast.repo_config import RepoConfig from feast.saved_dataset import SavedDatasetStorage from feast.type_map import pg_type_code_to_arrow -from feast.utils import _utc_now, make_tzaware +from feast.utils import compute_non_entity_date_range from .postgres_source import PostgreSQLSource @@ -129,43 +140,17 @@ def get_historical_features( assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) for fv in feature_views: assert isinstance(fv.batch_source, PostgreSQLSource) - start_date: Optional[datetime] = kwargs.get("start_date", None) - end_date: Optional[datetime] = kwargs.get("end_date", None) + start_date: Optional[datetime] = kwargs.get("start_date") + end_date: Optional[datetime] = kwargs.get("end_date") # Handle non-entity retrieval mode if entity_df is None: - # Default to current time if end_date not provided - if end_date is None: - end_date = _utc_now() - else: - end_date = make_tzaware(end_date) - - # Calculate start_date from TTL if not provided - - if start_date is None: - # Find the maximum TTL across all feature views to ensure we capture enough data - max_ttl_seconds = 0 - for fv in feature_views: - if fv.ttl and isinstance(fv.ttl, timedelta): - ttl_seconds = int(fv.ttl.total_seconds()) - max_ttl_seconds = max(max_ttl_seconds, ttl_seconds) - - if max_ttl_seconds > 0: - # Start from (end_date - max_ttl) to ensure we capture all relevant features - start_date = end_date - timedelta(seconds=max_ttl_seconds) - else: - # If no TTL is set, default to 30 days before end_date - start_date = end_date - timedelta(days=30) - else: - start_date = make_tzaware(start_date) - - entity_df = pd.DataFrame( - { - "event_timestamp": pd.date_range( - start=start_date, end=end_date, freq="1s", tz=timezone.utc - )[:1] # Just one row - } + start_date, end_date = compute_non_entity_date_range( + feature_views, + start_date=start_date, + end_date=end_date, ) + entity_df = pd.DataFrame({"event_timestamp": [end_date]}) entity_schema = _get_entity_schema(entity_df, config) @@ -173,11 +158,18 @@ def get_historical_features( offline_utils.infer_event_timestamp_from_entity_df(entity_schema) ) - entity_df_event_timestamp_range = _get_entity_df_event_timestamp_range( - entity_df, - entity_df_event_timestamp_col, - config, - ) + # In non-entity mode, use the actual requested range so that + # min_event_timestamp (= range[0] - TTL) doesn't clip the window. + # The synthetic entity_df only has end_date, which would wrongly + # set min_event_timestamp to end_date - TTL instead of start_date - TTL. + if start_date is not None and end_date is not None: + entity_df_event_timestamp_range = (start_date, end_date) + else: + entity_df_event_timestamp_range = _get_entity_df_event_timestamp_range( + entity_df, + entity_df_event_timestamp_col, + config, + ) @contextlib.contextmanager def query_generator() -> Iterator[str]: @@ -308,6 +300,263 @@ def pull_all_from_table_or_query( on_demand_feature_views=None, ) + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + assert isinstance(data_source, PostgreSQLSource) + + from_expression = data_source.get_table_query_string() + ts_filter = ( + get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + tz=timezone.utc, + cast_style="timestamptz", + date_time_separator=" ", + ) + or "1=1" + ) + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + with _get_conn(config.offline_store) as conn: + conn.read_only = True + + if numeric_features: + results.extend( + _sql_numeric_stats( + conn, + from_expression, + numeric_features, + ts_filter, + histogram_bins, + ) + ) + + for col_name in categorical_features: + results.append( + _sql_categorical_stats( + conn, + from_expression, + col_name, + ts_filter, + top_n, + ) + ) + + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + assert isinstance(data_source, PostgreSQLSource) + + from_expression = data_source.get_table_query_string_with_alias("max_ts_alias") + + with _get_conn(config.offline_store) as conn: + conn.read_only = True + with conn.cursor() as cur: + cur.execute(f'SELECT MAX("{timestamp_field}") FROM {from_expression}') + row = cur.fetchone() + + if row is None or row[0] is None: + return None + val = row[0] + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + + # ------------------------------------------------------------------ # + # Monitoring metrics storage (native PostgreSQL) + # ------------------------------------------------------------------ # + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + with _get_conn(config.offline_store) as conn, conn.cursor() as cur: + cur.execute(f""" + CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE} ( + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255) NOT NULL, + feature_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + feature_type VARCHAR(50) NOT NULL, + row_count BIGINT, + null_count BIGINT, + null_rate DOUBLE PRECISION, + mean DOUBLE PRECISION, + stddev DOUBLE PRECISION, + min_val DOUBLE PRECISION, + max_val DOUBLE PRECISION, + p50 DOUBLE PRECISION, + p75 DOUBLE PRECISION, + p90 DOUBLE PRECISION, + p95 DOUBLE PRECISION, + p99 DOUBLE PRECISION, + histogram JSONB, + PRIMARY KEY (project_id, feature_view_name, feature_name, + metric_date, granularity, data_source_type) + ); + CREATE INDEX IF NOT EXISTS idx_fm_feature_metrics_project + ON {MON_TABLE_FEATURE} (project_id); + CREATE INDEX IF NOT EXISTS idx_fm_feature_metrics_view + ON {MON_TABLE_FEATURE} (project_id, feature_view_name); + CREATE INDEX IF NOT EXISTS idx_fm_feature_metrics_date + ON {MON_TABLE_FEATURE} (metric_date); + CREATE INDEX IF NOT EXISTS idx_fm_feature_metrics_granularity + ON {MON_TABLE_FEATURE} (granularity); + CREATE INDEX IF NOT EXISTS idx_fm_feature_metrics_baseline + ON {MON_TABLE_FEATURE} (project_id, feature_view_name, feature_name) + WHERE is_baseline = TRUE; + """) + + cur.execute(f""" + CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_VIEW} ( + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + total_row_count BIGINT, + total_features INTEGER, + features_with_nulls INTEGER, + avg_null_rate DOUBLE PRECISION, + max_null_rate DOUBLE PRECISION, + PRIMARY KEY (project_id, feature_view_name, metric_date, + granularity, data_source_type) + ); + """) + + cur.execute(f""" + CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_SERVICE} ( + project_id VARCHAR(255) NOT NULL, + feature_service_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + total_feature_views INTEGER, + total_features INTEGER, + avg_null_rate DOUBLE PRECISION, + max_null_rate DOUBLE PRECISION, + PRIMARY KEY (project_id, feature_service_name, metric_date, + granularity, data_source_type) + ); + """) + + cur.execute(f""" + CREATE TABLE IF NOT EXISTS {MON_TABLE_JOB} ( + job_id VARCHAR(36) PRIMARY KEY, + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255), + job_type VARCHAR(50) NOT NULL, + status VARCHAR(20) NOT NULL DEFAULT 'pending', + parameters TEXT, + metric_date DATE NOT NULL, + started_at TIMESTAMPTZ, + completed_at TIMESTAMPTZ, + error_message TEXT, + result_summary TEXT + ); + CREATE INDEX IF NOT EXISTS idx_fm_jobs_status + ON {MON_TABLE_JOB} (status); + CREATE INDEX IF NOT EXISTS idx_fm_jobs_project + ON {MON_TABLE_JOB} (project_id); + """) + conn.commit() + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + + table, columns, pk_columns = monitoring_table_meta(metric_type) + _mon_upsert(config.offline_store, table, columns, pk_columns, metrics) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional["date"] = None, + end_date: Optional["date"] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + + _, columns, _ = monitoring_table_meta(metric_type) + return _mon_query( + config.offline_store, + metric_type, + columns, + project, + filters, + start_date, + end_date, + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, PostgreSQLOfflineStoreConfig) + + conditions = [sql.SQL("project_id = %s")] + params: list = [project] + + if feature_view_name: + conditions.append(sql.SQL("feature_view_name = %s")) + params.append(feature_view_name) + if feature_name: + conditions.append(sql.SQL("feature_name = %s")) + params.append(feature_name) + if data_source_type: + conditions.append(sql.SQL("data_source_type = %s")) + params.append(data_source_type) + + conditions.append(sql.SQL("is_baseline = TRUE")) + + query = sql.SQL("UPDATE {} SET is_baseline = FALSE WHERE {}").format( + sql.Identifier(MON_TABLE_FEATURE), + sql.SQL(" AND ").join(conditions), + ) + + with _get_conn(config.offline_store) as conn, conn.cursor() as cur: + cur.execute(query, params) + conn.commit() + class PostgreSQLRetrievalJob(RetrievalJob): def __init__( @@ -801,3 +1050,295 @@ def _get_entity_schema( {% endfor %} {% endif %} """ + + +# ------------------------------------------------------------------ # +# Monitoring SQL push-down helpers +# ------------------------------------------------------------------ # + + +def _sql_numeric_stats( + conn, + from_expression: str, + feature_names: List[str], + ts_filter: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + """Batch-compute numeric statistics via one SQL query, then histograms.""" + # 11 aggregate columns per feature (non_null, mean..p99) + 1 row_count + select_parts = ["COUNT(*)"] + for col in feature_names: + q = f'"{col}"' + c = f"{q}::float8" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY {c})", + ] + ) + + query = ( + f"SELECT {', '.join(select_parts)} " + f"FROM {from_expression} AS _src WHERE {ts_filter}" + ) + + with conn.cursor() as cur: + cur.execute(query) + row = cur.fetchone() + + if row is None: + return [empty_numeric_metric(n) for n in feature_names] + + row_count = row[0] + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = row[base] or 0 + null_count = row_count - non_null + + min_val = opt_float(row[base + 3]) + max_val = opt_float(row[base + 4]) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[base + 1]), + "stddev": opt_float(row[base + 2]), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(row[base + 5]), + "p75": opt_float(row[base + 6]), + "p90": opt_float(row[base + 7]), + "p95": opt_float(row[base + 8]), + "p99": opt_float(row[base + 9]), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _sql_numeric_histogram( + conn, + from_expression, + col, + ts_filter, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _sql_numeric_histogram( + conn, + from_expression: str, + col_name: str, + ts_filter: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + if min_val == max_val: + with conn.cursor() as cur: + cur.execute( + f"SELECT COUNT(*) FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_filter}" + ) + cnt = (cur.fetchone() or (0,))[0] + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + upper = max_val + (max_val - min_val) * 1e-10 + bin_width = (max_val - min_val) / bins + + query = ( + f"SELECT width_bucket({q_col}::float8, {min_val}, {upper}, {bins}) AS bucket, " + f"COUNT(*) AS cnt " + f"FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_filter} " + f"GROUP BY bucket ORDER BY bucket" + ) + + with conn.cursor() as cur: + cur.execute(query) + rows = cur.fetchall() + + counts = [0] * bins + for bucket, cnt in rows: + if 1 <= bucket <= bins: + counts[bucket - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _sql_categorical_stats( + conn, + from_expression: str, + col_name: str, + ts_filter: str, + top_n: int, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expression} AS _src WHERE {ts_filter}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" {q_col}::text AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} ORDER BY cnt DESC LIMIT {int(top_n)}" + ) + + with conn.cursor() as cur: + cur.execute(query) + rows = cur.fetchall() + + if not rows: + return empty_categorical_metric(col_name) + + row_count = rows[0][0] + null_count = rows[0][1] + unique_count = rows[0][2] + + top_entries = [{"value": r[3], "count": r[4]} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +# ------------------------------------------------------------------ # +# Monitoring metrics storage helpers +# ------------------------------------------------------------------ # + + +def _mon_upsert( + pg_config: PostgreSQLConfig, + table: str, + columns: List[str], + pk_columns: List[str], + rows: List[Dict[str, Any]], +) -> None: + import json as _json + + non_pk = [c for c in columns if c not in pk_columns] + col_ids = sql.SQL(", ").join(sql.Identifier(c) for c in columns) + placeholders = sql.SQL(", ").join(sql.Placeholder() for _ in columns) + update_clause = sql.SQL(", ").join( + sql.SQL("{} = EXCLUDED.{}").format(sql.Identifier(c), sql.Identifier(c)) + for c in non_pk + ) + pk_ids = sql.SQL(", ").join(sql.Identifier(c) for c in pk_columns) + + query = sql.SQL( + "INSERT INTO {} ({}) VALUES ({}) ON CONFLICT ({}) DO UPDATE SET {}" + ).format(sql.Identifier(table), col_ids, placeholders, pk_ids, update_clause) + + with _get_conn(pg_config) as conn, conn.cursor() as cur: + for row in rows: + values = [] + for col in columns: + val = row.get(col) + if col == "histogram" and val is not None: + val = _json.dumps(val) + values.append(val) + cur.execute(query, values) + conn.commit() + + +def _mon_query( + pg_config: PostgreSQLConfig, + metric_type: str, + columns: List[str], + project: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional["date"] = None, + end_date: Optional["date"] = None, +) -> List[Dict[str, Any]]: + table, _, _ = monitoring_table_meta(metric_type) + + conditions: list = [] + params: list = [] + + if project: + conditions.append(sql.SQL("project_id = %s")) + params.append(project) + + if filters: + for key, value in filters.items(): + if value is not None: + conditions.append(sql.SQL("{} = %s").format(sql.Identifier(key))) + params.append(value) + + if start_date: + conditions.append(sql.SQL("metric_date >= %s")) + params.append(start_date) + if end_date: + conditions.append(sql.SQL("metric_date <= %s")) + params.append(end_date) + + col_ids = sql.SQL(", ").join(sql.Identifier(c) for c in columns) + where = sql.SQL(" AND ").join(conditions) if conditions else sql.SQL("TRUE") + order_col = "metric_date" if "metric_date" in columns else "job_id" + query = sql.SQL("SELECT {} FROM {} WHERE {} ORDER BY {} ASC").format( + col_ids, + sql.Identifier(table), + where, + sql.Identifier(order_col), + ) + + with _get_conn(pg_config) as conn, conn.cursor() as cur: + conn.read_only = True + cur.execute(query, params) + rows = cur.fetchall() + + results = [] + for row in rows: + record = dict(zip(columns, row)) + results.append(normalize_monitoring_row(record)) + + return results diff --git a/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/tests/data_source.py b/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/tests/data_source.py index a545d0434a9..273ae22cf54 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/tests/data_source.py +++ b/sdk/python/feast/infra/offline_stores/contrib/postgres_offline_store/tests/data_source.py @@ -85,6 +85,7 @@ def __init__( db_schema="public", user=self.container.env["POSTGRES_USER"], password=self.container.env["POSTGRES_PASSWORD"], + sslmode="disable", ) def create_data_source( @@ -124,6 +125,7 @@ def create_online_store(self) -> PostgreSQLOnlineStoreConfig: # type: ignore db_schema="feature_store", user=POSTGRES_USER, password=POSTGRES_PASSWORD, + sslmode="disable", ) def create_saved_dataset_destination(self): diff --git a/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray.py b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray.py index e4dbd67666d..5230797d94b 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray.py +++ b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray.py @@ -1,7 +1,7 @@ import logging import os import uuid -from datetime import datetime, timedelta +from datetime import datetime from pathlib import Path from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union @@ -59,7 +59,12 @@ feast_value_type_to_pandas_type, pa_to_feast_value_type, ) -from feast.utils import _get_column_names, make_df_tzaware, make_tzaware +from feast.utils import ( + _get_column_names, + compute_non_entity_date_range, + make_df_tzaware, + make_tzaware, +) logger = logging.getLogger(__name__) # Remote storage URI schemes supported by the Ray offline store @@ -360,6 +365,51 @@ class RayOfflineStoreConfig(FeastConfigBaseModel): kuberay_conf: Optional[Dict[str, Any]] = None """KubeRay/CodeFlare configuration parameters (passed to CodeFlare SDK)""" + # Worker task resource configuration + num_gpus: Optional[float] = None + """Number of GPUs to request per worker task. Requires GPU nodes in the + Ray cluster. Fractional values (e.g. 0.5) are supported by Ray for GPU + sharing. Supported in all modes: local, remote, and KubeRay.""" + + gpu_batch_format: str = "pandas" + """Batch format for map_batches when num_gpus is set. Use 'numpy' or + 'pyarrow' for GPU-native libraries (e.g. cuDF, PyTorch). Defaults to + 'pandas'.""" + + worker_task_options: Optional[Dict[str, Any]] = None + """Arbitrary Ray task options passed verbatim to @ray.remote .options() + and map_batches for every worker task Feast dispatches. This is the + escape hatch for any Ray or CodeFlare SDK scheduling parameter not + covered by the dedicated fields above. + + Pairs with ray_conf (which configures ray.init) — worker_task_options + targets the individual worker tasks rather than the cluster connection. + + Common keys (see https://docs.ray.io/en/latest/ray-core/api/doc/ray.remote_function.RemoteFunction.options.html): + num_cpus (float) – CPUs per task (default: 1) + memory (int) – Heap memory in bytes (e.g. 8 * 1024**3 for 8 GB) + accelerator_type (str) – Specific GPU model, e.g. 'A100', 'T4', 'V100'. + Pins tasks to nodes advertising that type. Useful + on KubeRay clusters with mixed GPU pools. + resources (dict) – Custom/extended resource labels, e.g. + {'intel.com/gpu': 1} for Kubernetes extended resources. + runtime_env (dict) – Per-task runtime environment (pip, conda, env_vars, + working_dir, …). For KubeRay use this to install + extra packages on workers without rebuilding images. + max_retries (int) – Task retry count on worker failure (default: 3). + scheduling_strategy (str) – 'DEFAULT', 'SPREAD', or a placement group strategy. + + Example: + worker_task_options: + num_cpus: 4 + memory: 8589934592 # 8 GB + accelerator_type: "A100" + max_retries: 5 + runtime_env: + pip: ["cudf-cu12==24.10.0"] + env_vars: {CUDA_VISIBLE_DEVICES: "0"} + """ + class RayResourceManager: """ @@ -377,12 +427,14 @@ def __init__(self, config: Optional[RayOfflineStoreConfig] = None) -> None: self.cluster_resources = {"CPU": 4, "memory": 8 * 1024**3} self.available_memory = 8 * 1024**3 self.available_cpus = 4 + self.available_gpus = 0 self.num_nodes = 1 return self.cluster_resources = ray.cluster_resources() self.available_memory = self.cluster_resources.get("memory", 8 * 1024**3) self.available_cpus = int(self.cluster_resources.get("CPU", 4)) + self.available_gpus = int(self.cluster_resources.get("GPU", 0)) self.num_nodes = len(ray.nodes()) def configure_ray_context(self) -> None: @@ -416,6 +468,7 @@ def configure_ray_context(self) -> None: if getattr(self.config, "enable_ray_logging", False): logger.info( f"Configured Ray context: {self.available_cpus} CPUs, " + f"{self.available_gpus} GPUs, " f"{self.available_memory // 1024**3}GB memory, {self.num_nodes} nodes" ) @@ -819,7 +872,7 @@ def windowed_temporal_join( ) combined_ds = entity_windowed.union(feature_windowed) result_ds = combined_ds.map_batches( - self._apply_windowed_point_in_time_logic, + self._apply_windowed_point_in_time_logic, # type: ignore[arg-type] batch_format="pandas", fn_kwargs={ "timestamp_field": timestamp_field, @@ -1005,6 +1058,17 @@ def _get_ray_dataset(self) -> Dataset: else: raise ValueError(f"Unsupported result type: {type(result)}") + def to_ray_dataset(self) -> Dataset: + """Return the underlying Ray Dataset directly. + + Preferred by RayReadNode over to_arrow() / to_df() because it + avoids materialising the full dataset to pandas on the driver and + keeps the computation on the cluster. Works for both local Ray + (StandardRayWrapper) and KubeRay / ray:// client mode + (RemoteDatasetProxy via CodeFlareRayWrapper). + """ + return self._get_ray_dataset() + def to_df( self, validation_reference: Optional[ValidationReference] = None, @@ -1055,12 +1119,10 @@ def to_arrow( if self._prefer_ray_datasets: try: + import ray as _ray + ray_ds = self._get_ray_dataset() - if hasattr(ray_ds, "to_arrow"): - return ray_ds.to_arrow() - else: - df = ray_ds.to_pandas() - return pa.Table.from_pandas(df) + return pa.concat_tables(_ray.get(ray_ds.to_arrow_refs())) except Exception: df = self.to_df( validation_reference=validation_reference, timeout=timeout @@ -1135,16 +1197,14 @@ def _to_df_internal(self, timeout: Optional[int] = None) -> pd.DataFrame: def _to_arrow_internal(self, timeout: Optional[int] = None) -> pa.Table: if self._prefer_ray_datasets: - ray_ds = self._get_ray_dataset() try: - if hasattr(ray_ds, "to_arrow"): - return ray_ds.to_arrow() - else: - df = ray_ds.to_pandas() - return pa.Table.from_pandas(df) + import ray as _ray + + ray_ds = self._get_ray_dataset() + return pa.concat_tables(_ray.get(ray_ds.to_arrow_refs())) except Exception: - df = ray_ds.to_pandas() - return pa.Table.from_pandas(df) + ray_ds = self._get_ray_dataset() + return pa.Table.from_pandas(ray_ds.to_pandas()) else: result = self._resolve() if isinstance(result, pd.DataFrame): @@ -1203,37 +1263,6 @@ def schema(self) -> pa.Schema: return pa.Table.from_pandas(df).schema -def _compute_non_entity_dates_ray( - feature_views: List[FeatureView], - start_date_opt: Optional[datetime], - end_date_opt: Optional[datetime], -) -> Tuple[datetime, datetime]: - # Why: derive bounded time window when no entity_df is provided using explicit dates or max TTL fallback - end_date = ( - make_tzaware(end_date_opt) if end_date_opt else make_tzaware(datetime.utcnow()) - ) - if start_date_opt is None: - max_ttl_seconds = 0 - for fv in feature_views: - if getattr(fv, "ttl", None): - try: - ttl_val = fv.ttl - if isinstance(ttl_val, timedelta): - max_ttl_seconds = max( - max_ttl_seconds, int(ttl_val.total_seconds()) - ) - except Exception: - pass - start_date = ( - end_date - timedelta(seconds=max_ttl_seconds) - if max_ttl_seconds > 0 - else end_date - timedelta(days=30) - ) - else: - start_date = make_tzaware(start_date_opt) - return start_date, end_date - - def _make_filter_range(timestamp_field: str, start_date: datetime, end_date: datetime): # Why: factory function for time-range filtering in Ray map_batches def _filter_range(batch: pd.DataFrame) -> pd.Series: @@ -1272,7 +1301,6 @@ def _distinct_entities_for_feature_view_ray( ) -> Tuple[Dataset, List[str]]: # Why: read minimal columns, filter by time, and project distinct (join_keys, event_timestamp) per FeatureView # This preserves multiple transactions per entity ID for proper point-in-time joins - ray_wrapper = get_ray_wrapper() entities = fv.entities or [] entity_objs = [registry.get_entity(e, project) for e in entities] original_join_keys, _rev_feats, timestamp_field, _created_col = _get_column_names( @@ -1282,9 +1310,10 @@ def _distinct_entities_for_feature_view_ray( source_info = resolve_feature_view_source_with_fallback( fv, config, is_materialization=False ) - source_path = store._get_source_path(source_info.data_source, config) required_columns = list(set(original_join_keys + [timestamp_field])) - ds = ray_wrapper.read_parquet(source_path, columns=required_columns) + ds = store._resolve_source_dataset( + source_info.data_source, config, columns=required_columns + ) field_mapping = getattr(fv.batch_source, "field_mapping", None) if field_mapping: @@ -1443,6 +1472,60 @@ def _get_source_path(self, source: DataSource, config: RepoConfig) -> str: uri = FileSource.get_uri_for_file_path(repo_path, source.path) return uri + def _resolve_source_dataset( + self, + source: DataSource, + config: RepoConfig, + columns: Optional[List[str]] = None, + ): + """Returns a ray.data.Dataset for a FileSource or RaySource. + + Args: + source: A FileSource or RaySource descriptor. + config: The Feast repo configuration. + columns: Optional list of columns to project. For FileSource the + list is pushed down to ``read_parquet`` as a read-time + optimisation. For RaySource the full dataset is loaded first + and then ``select_columns`` is applied, because most Ray Data + readers do not support column pushdown. + + Returns: + A ray.data.Dataset ready for transformation or point-in-time joins. + + Raises: + ValueError: If source is not a supported DataSource type. + """ + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + RaySource, + ) + + if isinstance(source, RaySource): + ds = load_ray_dataset_from_source(source) + if columns: + # Post-load column selection — only keep columns that actually + # exist in the dataset to avoid KeyErrors on sparse sources. + available = set(ds.schema().names) if ds.schema() else set() + safe_cols = [c for c in columns if c in available] + if safe_cols: + ds = ds.select_columns(safe_cols) + return ds + + if isinstance(source, FileSource): + # Legacy path: Parquet via ray_wrapper — push columns down at read + # time so that only the required columns are deserialised. + ray_wrapper = get_ray_wrapper() + source_path = self._get_source_path(source, config) + return ray_wrapper.read_parquet(source_path, columns=columns) + + raise ValueError( + f"Unsupported source type '{type(source).__name__}'. " + f"Use FileSource (Parquet) or RaySource " + f"(images, HuggingFace, CSV, JSON, binary files, MongoDB, and more)." + ) + def _optimize_dataset_for_operation(self, ds: Dataset, operation: str) -> Dataset: """Optimize dataset for specific operations.""" if self._resource_manager is None: @@ -1488,10 +1571,36 @@ def offline_write_batch( if not ray_config.enable_ray_logging: RayOfflineStore._suppress_ray_logging() - assert isinstance(feature_view.batch_source, FileSource) + + from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + RaySource, + ) + + batch_source = feature_view.batch_source + if isinstance(batch_source, RaySource): + if not batch_source.path: + raise NotImplementedError( + f"offline_write_batch is not supported for RaySource '{batch_source.name}' " + f"with reader_type='{batch_source.reader_type}' because it has no writable " + f"file path (e.g. HuggingFace, MongoDB, SQL sources are read-only). " + f"Use a RaySource with reader_type='parquet' and a local or remote path to " + f"enable offline writes." + ) + batch_source_path = batch_source.path + feature_path = batch_source_path + elif isinstance(batch_source, FileSource): + batch_source_path = batch_source.file_options.uri + feature_path = FileSource.get_uri_for_file_path( + repo_path, batch_source_path + ) + else: + raise ValueError( + f"offline_write_batch does not support source type " + f"'{type(batch_source).__name__}'." + ) validation_result = _safe_validate_schema( - config, feature_view.batch_source, table.column_names, "offline_write_batch" + config, batch_source, table.column_names, "offline_write_batch" ) if validation_result: @@ -1503,9 +1612,6 @@ def offline_write_batch( logger.info("Reordering table columns to match expected schema") table = table.select(expected_columns) - batch_source_path = feature_view.batch_source.file_options.uri - feature_path = FileSource.get_uri_for_file_path(repo_path, batch_source_path) - ray_wrapper = get_ray_wrapper() ds = ray_wrapper.from_arrow(table) @@ -1661,7 +1767,7 @@ def _load_and_filter_dataset( @staticmethod def _load_and_filter_dataset_ray( - source_path: str, + source_path: Optional[str], data_source: DataSource, join_key_columns: List[str], feature_name_columns: List[str], @@ -1669,26 +1775,90 @@ def _load_and_filter_dataset_ray( created_timestamp_column: Optional[str], start_date: Optional[datetime], end_date: Optional[datetime], + *, + pre_loaded_ds: Optional[Dataset] = None, ) -> Dataset: + """Load (or accept a pre-loaded) Ray Dataset then apply the shared + filter / transform pipeline. + + When ``pre_loaded_ds`` is supplied the parquet-read and column-projection + steps are skipped; time-range filtering is applied inline so that the + same pipeline covers both ``FileSource`` (path-based) and exotic + ``RaySource`` types (HuggingFace, SQL, MongoDB) whose data is already + loaded by ``load_ray_dataset_from_source``. + """ try: field_mapping = getattr(data_source, "field_mapping", None) - if not feature_name_columns: - columns_to_read = None + if pre_loaded_ds is not None: + ds = pre_loaded_ds + + # Normalise timestamps and apply time-range filter inside + # map_batches so that ds.schema() is NEVER called eagerly. + # Column-existence checks are deferred to each batch so that + # exotic sources whose timestamp column is synthesised inside a + # downstream UDF (e.g. HuggingFace image datasets) are handled + # gracefully: normalization and filtering are simply skipped for + # batches that do not yet contain the column. + _ts_field = timestamp_field + _created_ts = created_timestamp_column + _s_date = ( + make_tzaware(start_date) + if start_date and start_date.tzinfo is None + else start_date + ) + _e_date = ( + make_tzaware(end_date) + if end_date and end_date.tzinfo is None + else end_date + ) + + def _norm_and_filter(batch: pd.DataFrame) -> pd.DataFrame: + batch = make_df_tzaware(batch) + for col in [ + c for c in [_ts_field, _created_ts] if c and c in batch.columns + ]: + batch[col] = ( + pd.to_datetime(batch[col], utc=True, errors="coerce") + .dt.floor("s") + .astype("datetime64[ns, UTC]") + ) + if _ts_field and _ts_field in batch.columns: + if _s_date and _e_date: + batch = batch[ + (batch[_ts_field] >= _s_date) + & (batch[_ts_field] <= _e_date) + ] + elif _s_date: + batch = batch[batch[_ts_field] >= _s_date] + elif _e_date: + batch = batch[batch[_ts_field] <= _e_date] + return batch + + ds = ds.map_batches(_norm_and_filter, batch_format="pandas") else: - columns_to_read = list( - set(join_key_columns + feature_name_columns + [timestamp_field]) + if not feature_name_columns: + columns_to_read = None + else: + columns_to_read = list( + set(join_key_columns + feature_name_columns + [timestamp_field]) + ) + if created_timestamp_column: + columns_to_read.append(created_timestamp_column) + + if source_path is None: + raise ValueError( + "_load_and_filter_dataset_ray requires source_path when " + "pre_loaded_ds is not provided" + ) + ds = RayOfflineStore._create_filtered_dataset( + source_path, + timestamp_field, + start_date, + end_date, + columns=columns_to_read, ) - if created_timestamp_column: - columns_to_read.append(created_timestamp_column) - ds = RayOfflineStore._create_filtered_dataset( - source_path, - timestamp_field, - start_date, - end_date, - columns=columns_to_read, - ) if field_mapping: ds = apply_field_mapping(ds, field_mapping) timestamp_field_mapped = ( @@ -1729,7 +1899,7 @@ def _load_and_filter_dataset_ray( return ds except Exception as e: - raise RuntimeError(f"Failed to load data from {source_path}: {e}") + raise RuntimeError(f"Failed to load/filter dataset: {e}") @staticmethod def _pull_latest_processing_ray( @@ -1768,26 +1938,29 @@ def _pull_latest_processing_ray( if created_timestamp_column_mapped: timestamp_columns.append(created_timestamp_column_mapped) - def deduplicate_batch(batch: pd.DataFrame) -> pd.DataFrame: - if batch.empty: - return batch - - existing_timestamp_columns = [ - col for col in timestamp_columns if col in batch.columns - ] + available_join_keys = [k for k in join_key_columns if k in ds.schema().names] + if not available_join_keys: + return ds - sort_columns = join_key_columns + existing_timestamp_columns - if sort_columns: - batch = batch.sort_values( - sort_columns, - ascending=[True] * len(join_key_columns) - + [False] * len(existing_timestamp_columns), + # groupby().map_groups() co-locates ALL rows for the same entity in a + # single UDF call, guaranteeing correct deduplication regardless of how + # Ray partitions the dataset. sort + map_batches is NOT safe because Ray + # can place the same entity's rows in different partitions after a sort, + # causing duplicates to survive. + def _keep_latest_in_group(group: pd.DataFrame) -> pd.DataFrame: + if group.empty: + return group + existing_ts_cols = [c for c in timestamp_columns if c in group.columns] + if existing_ts_cols: + group = group.sort_values( + existing_ts_cols, + ascending=[False] * len(existing_ts_cols), ) - batch = batch.drop_duplicates(subset=join_key_columns, keep="first") - - return batch + return group.drop_duplicates(subset=available_join_keys, keep="first") - return ds.map_batches(deduplicate_batch, batch_format="pandas") + return ds.groupby(available_join_keys).map_groups( + _keep_latest_in_group, batch_format="pandas" + ) @staticmethod def pull_latest_from_table_or_query( @@ -1803,6 +1976,54 @@ def pull_latest_from_table_or_query( store = RayOfflineStore() store._init_ray(config) + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + RaySource, + ) + + if isinstance(data_source, RaySource): + # Filtering only requires a timestamp_field; deduplication additionally + # requires join_key_columns. These are intentionally separate so that + # a feature view with a timestamp but no entities (join_key_columns=[]) + # still gets time-range filtering applied — matching the FileSource path. + # Sources with neither (e.g. HuggingFace image datasets where a + # RayTransformation UDF synthesises all Feast columns) are returned raw. + has_timestamp = bool(timestamp_field) + + def _load_ray_source_dataset(): + raw_ds = load_ray_dataset_from_source(data_source) + if not has_timestamp: + return raw_ds + filtered_ds = store._load_and_filter_dataset_ray( + None, + data_source, + join_key_columns, + feature_name_columns, + timestamp_field, + created_timestamp_column, + start_date, + end_date, + pre_loaded_ds=raw_ds, + ) + field_mapping = getattr(data_source, "field_mapping", None) + # _pull_latest_processing_ray already handles empty join_key_columns + # by returning the dataset unchanged (no dedup without entity keys). + return store._pull_latest_processing_ray( + filtered_ds, + join_key_columns, + timestamp_field, + created_timestamp_column, + field_mapping, + ) + + return RayRetrievalJob( + _load_ray_source_dataset, + staging_location=config.offline_store.storage_path, + config=config.offline_store, + ) + source_path = store._get_source_path(data_source, config) def _load_ray_dataset(): @@ -1867,6 +2088,40 @@ def pull_all_from_table_or_query( store = RayOfflineStore() store._init_ray(config) + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + RaySource, + ) + + if isinstance(data_source, RaySource): + # pull_all only needs a timestamp_field to filter by time — join keys + # are not required (no deduplication step, unlike pull_latest). + has_timestamp = bool(timestamp_field) + + def _load_ray_source_all(): + raw_ds = load_ray_dataset_from_source(data_source) + if not has_timestamp: + return raw_ds + return store._load_and_filter_dataset_ray( + None, + data_source, + join_key_columns, + feature_name_columns, + timestamp_field, + created_timestamp_column, + start_date, + end_date, + pre_loaded_ds=raw_ds, + ) + + return RayRetrievalJob( + _load_ray_source_all, + staging_location=config.offline_store.storage_path, + config=config.offline_store, + ) + source_path = store._get_source_path(data_source, config) fs, path_in_fs = fsspec.core.url_to_fs(source_path) @@ -2067,8 +2322,10 @@ def get_historical_features( # Non-entity mode: derive entity set from feature sources within a bounded time window # Preserves distinct (entity_keys, event_timestamp) combinations for proper PIT joins # This handles cases where multiple transactions per entity ID exist - start_date, end_date = _compute_non_entity_dates_ray( - feature_views, kwargs.get("start_date"), kwargs.get("end_date") + start_date, end_date = compute_non_entity_date_range( + feature_views, + start_date=kwargs.get("start_date"), + end_date=kwargs.get("end_date"), ) per_view_entity_ds: List[Dataset] = [] all_join_keys: List[str] = [] @@ -2183,20 +2440,25 @@ def get_historical_features( fv, config, is_materialization=False ) - # Read from the resolved data source - source_path = store._get_source_path(source_info.data_source, config) - + # Read from the resolved data source — works for both FileSource + # and RaySource. Column pushdown is applied for FileSource; for + # RaySource select_columns is applied post-load inside + # _resolve_source_dataset. if not source_info.has_transformation: required_feature_columns = set( original_join_keys + requested_feats + [timestamp_field] ) if created_col: required_feature_columns.add(created_col) - feature_ds = ray_wrapper.read_parquet( - source_path, columns=list(required_feature_columns) + feature_ds = store._resolve_source_dataset( + source_info.data_source, + config, + columns=list(required_feature_columns), ) else: - feature_ds = ray_wrapper.read_parquet(source_path) + feature_ds = store._resolve_source_dataset( + source_info.data_source, config + ) # Apply transformation if available if source_info.has_transformation and source_info.transformation_func: diff --git a/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_offline_store_reader.py b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_offline_store_reader.py new file mode 100644 index 00000000000..ecea76842a2 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_offline_store_reader.py @@ -0,0 +1,126 @@ +import logging +from typing import Any + +from feast.infra.ray_initializer import get_ray_wrapper + +logger = logging.getLogger(__name__) + + +def load_ray_dataset_from_source(source: Any) -> Any: + """Loads a ray.data.Dataset from a RaySource descriptor. + + All ray.data loading logic for RaySource lives here, in the offline store + layer. The RaySource descriptor carries only metadata (reader_type, path, + reader_options); it contains no loading logic itself. + + This follows the same pattern as SparkOfflineStore, which reads + SparkSource.file_format and calls spark.read.format(fmt).load(path) — the + source describes what to read, the store decides how. + + Every reader type is dispatched through get_ray_wrapper() so that: + - Local / GCS-connected mode → StandardRayWrapper → direct ray.data call + - KubeRay / Ray Client mode → CodeFlareRayWrapper → @ray.remote dispatch + + This ensures ray.data operations always run on the cluster, never on a thin + Ray Client driver where they are not supported. + + Path semantics for file-backed reader types (``parquet``, ``csv``, …): + - Remote URIs (``s3://``, ``gs://``, ``hdfs://``) are passed through unchanged; + Ray Data resolves them natively. + - Absolute local paths are passed through unchanged. + - Relative paths are passed through unchanged and resolved by each Ray worker + relative to its own working directory. This is intentional for shared + storage setups (e.g. a PVC mounted at the same path on every node) where + the path is meaningful to the workers, not to the driver. Unlike + ``FileSource``, ``RaySource`` data is always read on workers, never on the + driver, so driver-side ``repo_path`` resolution would produce incorrect + absolute paths on remote workers. + + Args: + source: A RaySource instance. + + Returns: + A ray.data.Dataset (or RemoteDatasetProxy for KubeRay mode) produced by + the reader indicated by source.reader_type. + + Raises: + ValueError: If source.reader_type is not a recognised reader type. + ImportError: If a reader-specific dependency (e.g. datasets) is missing. + """ + reader_type = source.reader_type + path = source.path or "" + opts = source.reader_options or {} + + logger.debug( + "RayOfflineStore: reading RaySource '%s' (reader_type=%s, path=%r)", + source.name, + reader_type, + path, + ) + + ray_wrapper = get_ray_wrapper() + + if reader_type == "parquet": + return ray_wrapper.read_parquet(path, **opts) + + if reader_type == "csv": + return ray_wrapper.read_csv(path, **opts) + + if reader_type == "json": + return ray_wrapper.read_json(path, **opts) + + if reader_type == "text": + return ray_wrapper.read_text(path, **opts) + + if reader_type == "images": + return ray_wrapper.read_images(path, **opts) + + if reader_type == "binary_files": + return ray_wrapper.read_binary_files(path, **opts) + + if reader_type == "tfrecords": + return ray_wrapper.read_tfrecords(path, **opts) + + if reader_type == "webdataset": + return ray_wrapper.read_webdataset(path, **opts) + + if reader_type == "huggingface": + dataset_name = opts.get("dataset_name") or path + split = opts.get("split", "train") + extra = { + k: v + for k, v in opts.items() + if k not in ("dataset_name", "split", "trust_remote_code") + } + return ray_wrapper.from_huggingface(dataset_name, split=split, **extra) + + if reader_type == "mongo": + return ray_wrapper.read_mongo( + uri=opts["uri"], + database=opts["database"], + collection=opts["collection"], + **{ + k: v + for k, v in opts.items() + if k not in ("uri", "database", "collection") + }, + ) + + if reader_type == "sql": + # Pass connection_url as a plain string so it is serialisable across + # the Ray object store boundary (CodeFlareRayWrapper rebuilds the + # connection_factory on the remote worker). + return ray_wrapper.read_sql( + sql=opts["sql"], + connection_url=opts["connection_url"], + **{k: v for k, v in opts.items() if k not in ("sql", "connection_url")}, + ) + + from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + SUPPORTED_READER_TYPES, + ) + + raise ValueError( + f"Unknown reader_type '{reader_type}' on RaySource '{source.name}'. " + f"Supported types: {sorted(SUPPORTED_READER_TYPES)}" + ) diff --git a/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_source.py b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_source.py new file mode 100644 index 00000000000..a8bfa2af2ef --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_source.py @@ -0,0 +1,283 @@ +import json +import logging +from typing import Any, Callable, Dict, Iterable, Optional, Tuple + +from feast.data_source import DataSource +from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto +from feast.repo_config import RepoConfig +from feast.type_map import pa_to_feast_value_type +from feast.value_type import ValueType + +logger = logging.getLogger(__name__) + +SUPPORTED_READER_TYPES = ( + "parquet", + "csv", + "json", + "text", + "images", + "binary_files", + "tfrecords", + "webdataset", + "huggingface", + "mongo", + "sql", +) + + +class RaySource(DataSource): + """A RaySource object defines a data source that a RayOfflineStore can use. + + RaySource supports any format that ray.data can read: image directories, HuggingFace datasets, + binary files, JSON, CSV, MongoDB, WebDataset shards, and more. + + The source stores only metadata (reader_type, path, reader_options). All + data-loading logic lives in the RayOfflineStore, which reads reader_type and + dispatches to the appropriate ray.data.read_*() or ray.data.from_*() call. + + Supported reader types: + parquet ray.data.read_parquet(path) + csv ray.data.read_csv(path) + json ray.data.read_json(path) + text ray.data.read_text(path) + images ray.data.read_images(path) + binary_files ray.data.read_binary_files(path) + tfrecords ray.data.read_tfrecords(path) + webdataset ray.data.read_webdataset(path) + huggingface ray.data.from_huggingface(dataset_name, split=...) + mongo ray.data.read_mongo(uri, database, collection) + sql ray.data.read_sql(sql, connection_factory) + + Examples: + >>> # Directory of PNG images + >>> source = RaySource( + ... name="cheque_images", + ... reader_type="images", + ... path="s3://bucket/cheques/", + ... timestamp_field="event_timestamp", + ... ) + + >>> # HuggingFace dataset + >>> source = RaySource( + ... name="cheque_hf", + ... reader_type="huggingface", + ... reader_options={ + ... "dataset_name": "cheques_sample_data", + ... "split": "test", + ... }, + ... timestamp_field="event_timestamp", + ... ) + """ + + def source_type(self) -> DataSourceProto.SourceType.ValueType: + return DataSourceProto.CUSTOM_SOURCE + + def __init__( + self, + *, + name: str, + reader_type: str, + path: Optional[str] = None, + reader_options: Optional[Dict[str, Any]] = None, + created_timestamp_column: Optional[str] = None, + field_mapping: Optional[Dict[str, str]] = None, + description: Optional[str] = "", + tags: Optional[Dict[str, str]] = None, + owner: Optional[str] = "", + timestamp_field: Optional[str] = None, + ): + """Creates a RaySource object. + + Args: + name: The name of the data source, which should be unique within a project. + reader_type: The ray.data reader to use. One of: parquet, csv, json, text, + images, binary_files, tfrecords, webdataset, huggingface, mongo, sql. + RayOfflineStore dispatches on this value to call the matching + ray.data.read_*() or ray.data.from_*() function. + path: File path or directory for file-based reader types (parquet, csv, + json, text, images, binary_files, tfrecords, webdataset). Not required + for huggingface, mongo, or sql. + reader_options: Reader-type-specific connection parameters as a + JSON-serializable dict. Examples: + huggingface: {"dataset_name": "org/name", "split": "train"} + mongo: {"uri": "mongodb://host", "database": "db", + "collection": "col"} + sql: {"sql": "SELECT …", "connection_url": "sqlite:///…"} + created_timestamp_column: Timestamp column indicating when the row + was created, used for deduplicating rows. + field_mapping: A dictionary mapping of column names in this data + source to feature names in a feature table or view. + description: A human-readable description. + tags: A dictionary of key-value pairs to store arbitrary metadata. + owner: The owner of the DataSource, typically the email of the primary + maintainer. + timestamp_field: Event timestamp field used for point-in-time joins of + feature values. + """ + if reader_type not in SUPPORTED_READER_TYPES: + raise ValueError( + f"'reader_type' must be one of {SUPPORTED_READER_TYPES}, " + f"got '{reader_type}'." + ) + + super().__init__( + name=name, + timestamp_field=timestamp_field, + created_timestamp_column=created_timestamp_column, + field_mapping=field_mapping, + description=description, + tags=tags, + owner=owner, + ) + + self.ray_source_options = RaySourceOptions( + reader_type=reader_type, + path=path or "", + reader_options=reader_options or {}, + ) + + @property + def reader_type(self) -> str: + """Returns the ray.data reader type of this data source.""" + return self.ray_source_options.reader_type + + @property + def path(self) -> str: + """Returns the path of this data source.""" + return self.ray_source_options.path + + @property + def reader_options(self) -> Dict[str, Any]: + """Returns the reader-specific options of this data source.""" + return self.ray_source_options.reader_options + + @staticmethod + def from_proto(data_source: DataSourceProto) -> Any: + """Creates a RaySource from a protobuf representation. + + Args: + data_source: A protobuf representation of a DataSource. + + Returns: + A RaySource object. + """ + assert data_source.type == DataSourceProto.CUSTOM_SOURCE + config = json.loads(data_source.custom_options.configuration) + return RaySource( + name=data_source.name, + reader_type=config["reader_type"], + path=config.get("path") or None, + reader_options=config.get("reader_options") or None, + field_mapping=dict(data_source.field_mapping), + timestamp_field=data_source.timestamp_field or None, + created_timestamp_column=data_source.created_timestamp_column or None, + description=data_source.description, + tags=dict(data_source.tags), + owner=data_source.owner, + ) + + def _to_proto_impl(self) -> DataSourceProto: + data_source_proto = DataSourceProto( + name=self.name, + type=DataSourceProto.CUSTOM_SOURCE, + data_source_class_type=( + "feast.infra.offline_stores.contrib.ray_offline_store" + ".ray_source.RaySource" + ), + field_mapping=self.field_mapping, + description=self.description, + tags=self.tags, + owner=self.owner, + custom_options=DataSourceProto.CustomSourceOptions( + configuration=json.dumps( + { + "reader_type": self.reader_type, + "path": self.path, + "reader_options": self.reader_options, + } + ).encode() + ), + ) + data_source_proto.timestamp_field = self.timestamp_field + data_source_proto.created_timestamp_column = self.created_timestamp_column + return data_source_proto + + def validate(self, config: RepoConfig) -> None: + pass + + @staticmethod + def source_datatype_to_feast_value_type() -> Callable[[str], ValueType]: + return pa_to_feast_value_type + + def get_table_column_names_and_types( + self, config: RepoConfig + ) -> Iterable[Tuple[str, str]]: + # Return an empty list so that inference.py skips schema/entity inference + # for RaySource during feast apply. Schema is resolved at materialisation + # time by RayOfflineStore when it reads the actual Ray Dataset. + return [] + + def get_table_query_string(self) -> str: + """Returns a string that can be used to reference this source.""" + parts = [f"reader_type={self.reader_type!r}"] + if self.path: + parts.append(f"path={self.path!r}") + if self.reader_options: + parts.append(f"reader_options={self.reader_options!r}") + return f"RaySource({', '.join(parts)})" + + def __eq__(self, other): + if not isinstance(other, RaySource): + raise TypeError("Comparisons should only involve RaySource class objects.") + base_eq = super().__eq__(other) + if not base_eq: + return False + return ( + self.reader_type == other.reader_type + and self.path == other.path + and self.reader_options == other.reader_options + ) + + def __hash__(self): + return super().__hash__() + + +class RaySourceOptions: + """Options specific to a RaySource.""" + + def __init__( + self, + reader_type: str, + path: str, + reader_options: Dict[str, Any], + ): + self._reader_type = reader_type + self._path = path + self._reader_options = reader_options + + @property + def reader_type(self) -> str: + """Returns the ray.data reader type.""" + return self._reader_type + + @reader_type.setter + def reader_type(self, reader_type: str) -> None: + self._reader_type = reader_type + + @property + def path(self) -> str: + """Returns the file path or directory.""" + return self._path + + @path.setter + def path(self, path: str) -> None: + self._path = path + + @property + def reader_options(self) -> Dict[str, Any]: + """Returns the reader-specific options dict.""" + return self._reader_options + + @reader_options.setter + def reader_options(self, reader_options: Dict[str, Any]) -> None: + self._reader_options = reader_options diff --git a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py index af83d303504..8c7e657b257 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py +++ b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark.py @@ -1,9 +1,11 @@ +import json import os import tempfile import uuid import warnings from dataclasses import asdict, dataclass -from datetime import datetime, timedelta, timezone +from datetime import date, datetime, timezone +from datetime import time as dt_time from typing import ( TYPE_CHECKING, Any, @@ -33,6 +35,7 @@ from pyspark.sql import SparkSession from feast import FeatureView, OnDemandFeatureView +from feast.batch_feature_view import BatchFeatureView from feast.data_source import DataSource from feast.dataframe import DataFrameEngine, FeastDataFrame from feast.errors import EntitySQLEmptyResults, InvalidEntityType @@ -49,10 +52,21 @@ ) from feast.infra.offline_stores.offline_utils import get_timestamp_filter_sql from feast.infra.registry.base_registry import BaseRegistry +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage from feast.type_map import spark_schema_to_np_dtypes -from feast.utils import _get_fields_with_aliases +from feast.utils import _get_fields_with_aliases, compute_non_entity_date_range # Make sure spark warning doesn't raise more than once. warnings.simplefilter("once", RuntimeWarning) @@ -183,8 +197,11 @@ def get_historical_features( # This makes date-range retrievals possible without enumerating entities upfront; sources remain bounded by time. non_entity_mode = entity_df is None if non_entity_mode: - # Why: derive bounded time window without requiring entities; uses max TTL fallback to constrain scans. - start_date, end_date = _compute_non_entity_dates(feature_views, kwargs) + start_date, end_date = compute_non_entity_date_range( + feature_views, + start_date=kwargs.get("start_date"), + end_date=kwargs.get("end_date"), + ) entity_df_event_timestamp_range = (start_date, end_date) # Build query contexts so we can reuse entity names and per-view table info consistently. @@ -257,6 +274,10 @@ def get_historical_features( entity_df_event_timestamp_range, ) + query_context = _apply_bfv_transformations( + spark_session, feature_views, query_context + ) + spark_query_context = [ SparkFeatureViewQueryContext( **asdict(context), @@ -384,12 +405,18 @@ def pull_all_from_table_or_query( timestamp_fields = [timestamp_field] if created_timestamp_column: timestamp_fields.append(created_timestamp_column) - (fields_with_aliases, aliases) = _get_fields_with_aliases( - fields=join_key_columns + feature_name_columns + timestamp_fields, - field_mappings=data_source.field_mapping, - ) - fields_with_alias_string = ", ".join(fields_with_aliases) + if feature_name_columns: + (fields_with_aliases, _) = _get_fields_with_aliases( + fields=join_key_columns + feature_name_columns + timestamp_fields, + field_mappings=data_source.field_mapping, + ) + fields_with_alias_string = ", ".join(fields_with_aliases) + else: + # Empty feature_name_columns signals "read all source columns". + # Used by BatchFeatureView with TransformationMode.PYTHON/ray/pandas where + # the UDF computes output features from raw input — don't project upfront. + fields_with_alias_string = "*" from_expression = data_source.get_table_query_string() timestamp_filter = get_timestamp_filter_sql( @@ -409,6 +436,494 @@ def pull_all_from_table_or_query( config=config, ) + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + assert isinstance(data_source, SparkSource) + + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + from_expression = data_source.get_table_query_string() + ts_filter = get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + tz=timezone.utc, + quote_fields=False, + ) + ts_clause = ts_filter if ts_filter else "1=1" + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + if numeric_features: + results.extend( + _spark_sql_numeric_stats( + spark_session, + from_expression, + numeric_features, + ts_clause, + histogram_bins, + ) + ) + + for col_name in categorical_features: + results.append( + _spark_sql_categorical_stats( + spark_session, + from_expression, + col_name, + ts_clause, + top_n, + ) + ) + + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + assert isinstance(data_source, SparkSource) + + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + from_expression = data_source.get_table_query_string() + q_ts = f"`{timestamp_field}`" + sql = f"SELECT MAX({q_ts}) AS max_ts FROM {from_expression} AS _src" + row = spark_session.sql(sql).collect() + if not row or row[0][0] is None: + return None + val = row[0][0] + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + if isinstance(val, date): + return datetime.combine(val, dt_time.min, tzinfo=timezone.utc) + return pandas.to_datetime(val, utc=True).to_pydatetime() + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + for stmt in _SPARK_MONITORING_DDL_STATEMENTS: + spark_session.sql(stmt) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + table, columns, pk_columns = monitoring_table_meta(metric_type) + pdf_new = pd.DataFrame([{c: m.get(c) for c in columns} for m in metrics]) + pdf_new = _spark_normalize_histogram_column(pdf_new) + + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + if spark_session.catalog.tableExists(table): + pdf_old = spark_session.table(table).toPandas() + pdf_merged = _spark_pandas_upsert(pdf_old, pdf_new, pk_columns) + else: + pdf_merged = pdf_new + + spark_session.createDataFrame(pdf_merged).write.mode("overwrite").saveAsTable( + table + ) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + table, columns, _ = monitoring_table_meta(metric_type) + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + if not spark_session.catalog.tableExists(table): + return [] + + from pyspark.sql import functions as F + + df = spark_session.table(table) + if project: + df = df.filter(F.col("project_id") == project) + if filters: + for key, value in filters.items(): + if value is not None: + df = df.filter(F.col(key) == value) + if start_date is not None and "metric_date" in df.columns: + df = df.filter(F.col("metric_date") >= F.lit(start_date)) + if end_date is not None and "metric_date" in df.columns: + df = df.filter(F.col("metric_date") <= F.lit(end_date)) + + order_col = "metric_date" if "metric_date" in df.columns else "job_id" + rows = df.orderBy(order_col).collect() + return _spark_rows_to_metric_dicts(rows, columns) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, SparkOfflineStoreConfig) + spark_session = get_spark_session_or_start_new_with_repoconfig( + store_config=config.offline_store + ) + if not spark_session.catalog.tableExists(MON_TABLE_FEATURE): + return + + pdf = spark_session.table(MON_TABLE_FEATURE).toPandas() + if pdf is None: + return + mask = (pdf["project_id"] == project) & (pdf["is_baseline"] == True) # noqa: E712 + if feature_view_name is not None: + mask &= pdf["feature_view_name"] == feature_view_name + if feature_name is not None: + mask &= pdf["feature_name"] == feature_name + if data_source_type is not None: + mask &= pdf["data_source_type"] == data_source_type + + pdf.loc[mask, "is_baseline"] = False + spark_session.createDataFrame(pdf).write.mode("overwrite").saveAsTable( + MON_TABLE_FEATURE + ) + + +_SPARK_MONITORING_DDL_STATEMENTS = [ + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE} ( + project_id STRING NOT NULL, + feature_view_name STRING NOT NULL, + feature_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOLEAN NOT NULL, + feature_type STRING NOT NULL, + row_count BIGINT, + null_count BIGINT, + null_rate DOUBLE, + mean DOUBLE, + stddev DOUBLE, + min_val DOUBLE, + max_val DOUBLE, + p50 DOUBLE, + p75 DOUBLE, + p90 DOUBLE, + p95 DOUBLE, + p99 DOUBLE, + histogram STRING +) USING PARQUET +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_VIEW} ( + project_id STRING NOT NULL, + feature_view_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOLEAN NOT NULL, + total_row_count BIGINT, + total_features INT, + features_with_nulls INT, + avg_null_rate DOUBLE, + max_null_rate DOUBLE +) USING PARQUET +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_SERVICE} ( + project_id STRING NOT NULL, + feature_service_name STRING NOT NULL, + metric_date DATE NOT NULL, + granularity STRING NOT NULL, + data_source_type STRING NOT NULL, + computed_at TIMESTAMP NOT NULL, + is_baseline BOOLEAN NOT NULL, + total_feature_views INT, + total_features INT, + avg_null_rate DOUBLE, + max_null_rate DOUBLE +) USING PARQUET +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_JOB} ( + job_id STRING NOT NULL, + project_id STRING NOT NULL, + feature_view_name STRING, + job_type STRING NOT NULL, + status STRING NOT NULL, + parameters STRING, + metric_date DATE NOT NULL, + started_at TIMESTAMP, + completed_at TIMESTAMP, + error_message STRING, + result_summary STRING +) USING PARQUET +""", +] + + +def _spark_normalize_histogram_column(pdf: pd.DataFrame) -> pd.DataFrame: + if "histogram" not in pdf.columns: + return pdf + out = pdf.copy() + + def _ser(x: Any) -> Any: + if x is None: + return None + if isinstance(x, str): + return x + return json.dumps(x) + + out["histogram"] = out["histogram"].map(_ser) + return out + + +def _spark_pandas_upsert( + pdf_old: pd.DataFrame, + pdf_new: pd.DataFrame, + pk_columns: List[str], +) -> pd.DataFrame: + if pdf_old.empty: + return pdf_new + old_idx = pdf_old.set_index(pk_columns) + new_idx = pdf_new.set_index(pk_columns) + kept = old_idx.loc[~old_idx.index.isin(new_idx.index)] + kept_df = kept.reset_index() + return pd.concat([kept_df, pdf_new], ignore_index=True) + + +def _spark_sql_numeric_stats( + spark_session: SparkSession, + from_expression: str, + feature_names: List[str], + ts_clause: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + select_parts = ["COUNT(*)"] + for col in feature_names: + q = f"`{col}`" + c = f"CAST({q} AS DOUBLE)" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_APPROX({c}, 0.50)", + f"PERCENTILE_APPROX({c}, 0.75)", + f"PERCENTILE_APPROX({c}, 0.90)", + f"PERCENTILE_APPROX({c}, 0.95)", + f"PERCENTILE_APPROX({c}, 0.99)", + ] + ) + + query = ( + f"SELECT {', '.join(select_parts)} " + f"FROM {from_expression} AS _src WHERE {ts_clause}" + ) + rows = spark_session.sql(query).collect() + if not rows or rows[0] is None: + return [empty_numeric_metric(n) for n in feature_names] + + row = rows[0] + row_count = int(row[0] or 0) + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = int(row[base] or 0) + null_count = row_count - non_null + + min_val = opt_float(row[base + 3]) + max_val = opt_float(row[base + 4]) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[base + 1]), + "stddev": opt_float(row[base + 2]), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(row[base + 5]), + "p75": opt_float(row[base + 6]), + "p90": opt_float(row[base + 7]), + "p95": opt_float(row[base + 8]), + "p99": opt_float(row[base + 9]), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _spark_sql_numeric_histogram( + spark_session, + from_expression, + col, + ts_clause, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _spark_sql_numeric_histogram( + spark_session: SparkSession, + from_expression: str, + col_name: str, + ts_clause: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = f"`{col_name}`" + + if min_val == max_val: + sql = ( + f"SELECT COUNT(*) FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_clause}" + ) + cnt = int(spark_session.sql(sql).collect()[0][0] or 0) + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + bin_width = (max_val - min_val) / bins + cast_col = f"CAST({q_col} AS DOUBLE)" + inner = ( + f"CASE WHEN {min_val} = {max_val} THEN 1 " + f"ELSE LEAST(GREATEST(FLOOR(({cast_col} - {min_val}) / {bin_width}) + 1, 1), {bins}) " + f"END AS bucket" + ) + + query = ( + f"SELECT bucket, COUNT(*) AS cnt FROM (" + f" SELECT {inner} " + f" FROM {from_expression} AS _src " + f" WHERE {q_col} IS NOT NULL AND {ts_clause}" + f") AS _b WHERE bucket IS NOT NULL " + f"GROUP BY bucket ORDER BY bucket" + ) + hrows = spark_session.sql(query).collect() + counts = [0] * bins + for hr in hrows: + bucket = int(hr[0] or 0) + cnt = int(hr[1] or 0) + if 1 <= bucket <= bins: + counts[bucket - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _spark_sql_categorical_stats( + spark_session: SparkSession, + from_expression: str, + col_name: str, + ts_clause: str, + top_n: int, +) -> Dict[str, Any]: + q_col = f"`{col_name}`" + + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expression} AS _src WHERE {ts_clause}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" CAST({q_col} AS STRING) AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} ORDER BY cnt DESC LIMIT {int(top_n)}" + ) + + rows = spark_session.sql(query).collect() + if not rows: + return empty_categorical_metric(col_name) + + row_count = int(rows[0][0] or 0) + null_count = int(rows[0][1] or 0) + unique_count = int(rows[0][2] or 0) + + top_entries = [{"value": r[3], "count": int(r[4] or 0)} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +def _spark_rows_to_metric_dicts( + rows: List[Any], + columns: List[str], +) -> List[Dict[str, Any]]: + out: List[Dict[str, Any]] = [] + for r in rows: + d = r.asDict() + rec = {c: d.get(c) for c in columns} + out.append(normalize_monitoring_row(rec)) + return out + class SparkRetrievalJob(RetrievalJob): def __init__( @@ -468,21 +983,50 @@ def _to_arrow_via_staging(self) -> pyarrow.Table: if not parquet_paths: return pyarrow.table({}) - normalized_paths = self._normalize_staging_paths(parquet_paths) - dataset = ds.dataset(normalized_paths, format="parquet") + pa_fs, stripped_paths = self._resolve_staging_filesystem(parquet_paths) + dataset = ds.dataset(stripped_paths, format="parquet", filesystem=pa_fs) return dataset.to_table() - def _normalize_staging_paths(self, paths: List[str]) -> List[str]: - """Normalize staging paths for PyArrow datasets.""" + def _resolve_staging_filesystem( + self, paths: List[str] + ) -> Tuple[Optional[pyarrow.fs.FileSystem], List[str]]: + """Return (pyarrow filesystem, prefix-stripped paths) for staging URIs.""" + sample = paths[0] + + import pyarrow.fs as pafs + + if sample.startswith("s3://") or sample.startswith("s3a://"): + endpoint = os.environ.get("AWS_ENDPOINT_URL_S3") or os.environ.get( + "AWS_S3_ENDPOINT", "" + ) + region = getattr( + self._config.offline_store, "region", None + ) or os.environ.get("AWS_DEFAULT_REGION", "us-east-1") + kwargs: Dict[str, Any] = {"region": region} + if endpoint: + kwargs["endpoint_override"] = ( + endpoint.rstrip("/") + .removeprefix("https://") + .removeprefix("http://") + ) + kwargs["scheme"] = "https" if endpoint.startswith("https") else "http" + fs = pafs.S3FileSystem(**kwargs) + stripped = [p.removeprefix("s3a://").removeprefix("s3://") for p in paths] + return fs, stripped + + if sample.startswith("gs://"): + fs = pafs.GcsFileSystem() + stripped = [p[len("gs://") :] for p in paths] + return fs, stripped + + # Local paths normalized = [] - for path in paths: - if path.startswith("file://"): - normalized.append(path[len("file://") :]) - elif "://" in path: - normalized.append(path) + for p in paths: + if p.startswith("file://"): + normalized.append(p[len("file://") :]) else: - normalized.append(path) - return normalized + normalized.append(p) + return None, normalized def to_feast_df( self, @@ -509,20 +1053,33 @@ def persist( ): """ Run the retrieval and persist the results in the same offline store used for read. - Please note the persisting is done only within the scope of the spark session for local warehouse directory. + Supports both table-based and path-based SparkSource configurations. + For table-based: persists via saveAsTable (remote warehouse) or createOrReplaceTempView (local). + For path-based: writes directly to the specified path in the given file format. """ assert isinstance(storage, SavedDatasetSparkStorage) + table_name = storage.spark_options.table - if not table_name: - raise ValueError("Cannot persist, table_name is not defined") - if self._has_remote_warehouse_in_config(): - file_format = storage.spark_options.file_format + path = storage.spark_options.path + file_format = storage.spark_options.file_format + + if path: if not file_format: - self.to_spark_df().write.saveAsTable(table_name) + file_format = "parquet" + write_mode = "overwrite" if allow_overwrite else "error" + self.to_spark_df().write.format(file_format).mode(write_mode).save(path) + elif table_name: + if self._has_remote_warehouse_in_config(): + if not file_format: + self.to_spark_df().write.saveAsTable(table_name) + else: + self.to_spark_df().write.format(file_format).saveAsTable(table_name) else: - self.to_spark_df().write.format(file_format).saveAsTable(table_name) + self.to_spark_df().createOrReplaceTempView(table_name) else: - self.to_spark_df().createOrReplaceTempView(table_name) + raise ValueError( + "Cannot persist: either 'table' or 'path' must be specified in SavedDatasetSparkStorage" + ) def _has_remote_warehouse_in_config(self) -> bool: """ @@ -619,29 +1176,6 @@ def get_spark_session_or_start_new_with_repoconfig( return spark_session -def _compute_non_entity_dates( - feature_views: List[FeatureView], kwargs: Dict[str, Any] -) -> Tuple[datetime, datetime]: - # Why: bounds the scan window when no entity_df is provided using explicit dates or max TTL fallback. - start_date_opt = cast(Optional[datetime], kwargs.get("start_date")) - end_date_opt = cast(Optional[datetime], kwargs.get("end_date")) - end_date: datetime = end_date_opt or datetime.now(timezone.utc) - - if start_date_opt is None: - max_ttl_seconds = 0 - for fv in feature_views: - if fv.ttl and isinstance(fv.ttl, timedelta): - max_ttl_seconds = max(max_ttl_seconds, int(fv.ttl.total_seconds())) - start_date: datetime = ( - end_date - timedelta(seconds=max_ttl_seconds) - if max_ttl_seconds > 0 - else end_date - timedelta(days=30) - ) - else: - start_date = start_date_opt - return (start_date, end_date) - - def _gather_all_entities( fv_query_contexts: List[offline_utils.FeatureViewQueryContext], ) -> List[str]: @@ -727,6 +1261,62 @@ def _entity_schema_keys_from( ) +def _apply_bfv_transformations( + spark_session: SparkSession, + feature_views: List[FeatureView], + query_contexts: List[offline_utils.FeatureViewQueryContext], +) -> List[offline_utils.FeatureViewQueryContext]: + """ + For BatchFeatureViews with a UDF, read the raw source into a Spark DataFrame, + invoke the transformation, register the result as a temp view, and replace the + table_subquery in the query context so the PIT join reads transformed data. + """ + from dataclasses import replace + + from feast.feature_view_utils import ( + get_transformation_function, + has_transformation, + resolve_feature_view_source_with_fallback, + ) + + fv_by_name = {fv.projection.name_to_use(): fv for fv in feature_views} + + updated_contexts = [] + for ctx in query_contexts: + fv = fv_by_name.get(ctx.name) + if ( + fv is not None + and isinstance(fv, BatchFeatureView) + and has_transformation(fv) + ): + udf = get_transformation_function(fv) + if udf is not None: + source_info = resolve_feature_view_source_with_fallback(fv) + source_query = source_info.data_source.get_table_query_string() + + timestamp_filter = get_timestamp_filter_sql( + start_date=ctx.min_event_timestamp, + end_date=ctx.max_event_timestamp, + timestamp_field=ctx.timestamp_field, + tz=timezone.utc, + quote_fields=False, + ) + source_df = spark_session.sql( + f"SELECT * FROM {source_query} WHERE {timestamp_filter}" + ) + + transformed_df = udf(source_df) + + tmp_view_name = "feast_bfv_" + uuid.uuid4().hex + transformed_df.createOrReplaceTempView(tmp_view_name) + + ctx = replace(ctx, table_subquery=tmp_view_name) + + updated_contexts.append(ctx) + + return updated_contexts + + def _get_entity_df_event_timestamp_range( entity_df: Union[pd.DataFrame, str], entity_df_event_timestamp_col: str, diff --git a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark_source.py b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark_source.py index cd41921e56a..d94a14123c7 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark_source.py +++ b/sdk/python/feast/infra/offline_stores/contrib/spark_offline_store/spark_source.py @@ -453,3 +453,14 @@ def to_data_source(self) -> DataSource: file_format=self.spark_options.file_format, table_format=self.spark_options.table_format, ) + + @staticmethod + def from_data_source(data_source: DataSource) -> "SavedDatasetSparkStorage": + assert isinstance(data_source, SparkSource) + return SavedDatasetSparkStorage( + table=data_source.table, + query=data_source.query, + path=data_source.path, + file_format=data_source.file_format, + table_format=data_source.table_format, + ) diff --git a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py index 33190bd4635..0f77d6e18fc 100644 --- a/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py +++ b/sdk/python/feast/infra/offline_stores/contrib/trino_offline_store/trino.py @@ -1,6 +1,15 @@ +import logging import uuid from datetime import date, datetime -from typing import Any, Dict, List, Literal, Optional, Tuple, Union +from typing import ( + Any, + Dict, + List, + Literal, + Optional, + Tuple, + Union, +) import numpy as np import pandas as pd @@ -37,6 +46,8 @@ from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage +logger = logging.getLogger(__name__) + class BasicAuthModel(FeastConfigBaseModel): username: StrictStr @@ -183,6 +194,7 @@ def __init__( full_feature_names: bool, on_demand_feature_views: Optional[List[OnDemandFeatureView]] = None, metadata: Optional[RetrievalMetadata] = None, + temp_table: Optional[str] = None, ): self._query = query self._client = client @@ -190,6 +202,8 @@ def __init__( self._full_feature_names = full_feature_names self._on_demand_feature_views = on_demand_feature_views or [] self._metadata = metadata + self._temp_table = temp_table + self._cleaned_up = False @property def full_feature_names(self) -> bool: @@ -199,11 +213,29 @@ def full_feature_names(self) -> bool: def on_demand_feature_views(self) -> List[OnDemandFeatureView]: return self._on_demand_feature_views + def _drop_temp_table(self) -> None: + if self._cleaned_up or not self._temp_table: + return + self._cleaned_up = True + try: + self._client.execute_query(f"DROP TABLE IF EXISTS {self._temp_table}") + except Exception: + logger.exception( + "Failed to drop temporary entity table %s", + self._temp_table, + ) + + def __del__(self) -> None: + self._drop_temp_table() + def _to_df_internal(self, timeout: Optional[int] = None) -> pd.DataFrame: """Return dataset as Pandas DataFrame synchronously including on demand transforms""" - results = self._client.execute_query(query_text=self._query) - self.pyarrow_schema = results.pyarrow_schema - return results.to_dataframe() + try: + results = self._client.execute_query(query_text=self._query) + self.pyarrow_schema = results.pyarrow_schema + return results.to_dataframe() + finally: + self._drop_temp_table() def _to_arrow_internal(self, timeout: Optional[int] = None) -> pyarrow.Table: """Return payrrow dataset as synchronously including on demand transforms""" @@ -234,8 +266,11 @@ def to_trino( destination_table = f"{self._client.catalog}.{self._config.offline_store.dataset}.historical_{today}_{rand_id}" # TODO: Implement the timeout logic - query = f"CREATE TABLE {destination_table} AS ({self._query})" - self._client.execute_query(query_text=query) + try: + create_query = f"CREATE TABLE {destination_table} AS ({self._query})" + self._client.execute_query(query_text=create_query) + finally: + self._drop_temp_table() return destination_table def persist( @@ -372,11 +407,12 @@ def get_historical_features( ) # Generate the Trino SQL query from the query context + entity_table_ref = table_reference if type(entity_df) is str: - table_reference = f"({entity_df})" + entity_table_ref = f"({entity_df})" query = offline_utils.build_point_in_time_query( query_context, - left_table_query_string=table_reference, + left_table_query_string=entity_table_ref, entity_df_event_timestamp_col=entity_df_event_timestamp_col, entity_df_columns=entity_schema.keys(), query_template=MULTIPLE_FEATURE_VIEW_POINT_IN_TIME_JOIN, @@ -385,6 +421,7 @@ def get_historical_features( return TrinoRetrievalJob( query=query, + temp_table=table_reference if isinstance(entity_df, pd.DataFrame) else None, client=client, config=config, full_feature_names=full_feature_names, @@ -483,8 +520,6 @@ def _upload_entity_df_and_get_entity_schema( else: raise InvalidEntityType(type(entity_df)) - # TODO: Ensure that the table expires after some time - def _get_trino_client(config: RepoConfig) -> Trino: auth = None diff --git a/sdk/python/feast/infra/offline_stores/dask.py b/sdk/python/feast/infra/offline_stores/dask.py index ddb1efa9262..1a68cdfb69f 100644 --- a/sdk/python/feast/infra/offline_stores/dask.py +++ b/sdk/python/feast/infra/offline_stores/dask.py @@ -1,15 +1,18 @@ +import json import os import uuid -from datetime import datetime, timedelta, timezone +from datetime import date, datetime, timezone from pathlib import Path from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union import dask import dask.dataframe as dd +import numpy as np import pandas as pd import pyarrow +import pyarrow.compute as pc import pyarrow.dataset -import pyarrow.parquet +import pyarrow.parquet as pq import pytz from feast.data_source import DataSource @@ -34,10 +37,20 @@ get_pyarrow_schema_from_batch_source, ) from feast.infra.registry.base_registry import BaseRegistry +from feast.monitoring.monitoring_utils import ( + MONITORING_DIR, + MONITORING_PARQUET_FILES, + monitoring_parquet_meta, + normalize_monitoring_row, + opt_float, +) from feast.on_demand_feature_view import OnDemandFeatureView from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage -from feast.utils import _get_requested_feature_views_to_features_dict, make_tzaware +from feast.utils import ( + _get_requested_feature_views_to_features_dict, + compute_non_entity_date_range, +) # DaskRetrievalJob will cast string objects to string[pyarrow] from dask version 2023.7.1 # This is not the desired behavior for our use case, so we set the convert-string option to False @@ -143,36 +156,14 @@ def get_historical_features( for fv in feature_views: assert isinstance(fv.batch_source, FileSource) - # Allow non-entity mode using start/end timestamps to enable bounded retrievals without an input entity_df. - # This synthesizes a minimal entity_df solely to drive the existing join and metadata plumbing without - # incurring source scans here; actual pushdowns can be layered in follow-ups if needed. - start_date: Optional[datetime] = kwargs.get("start_date", None) - end_date: Optional[datetime] = kwargs.get("end_date", None) non_entity_mode = entity_df is None if non_entity_mode: - # Default end_date to current time (UTC) to keep behavior predictable without extra parameters. - end_date = ( - make_tzaware(end_date) if end_date else datetime.now(timezone.utc) + start_date, end_date = compute_non_entity_date_range( + feature_views, + start_date=kwargs.get("start_date"), + end_date=kwargs.get("end_date"), ) - - # When start_date is not provided, choose a conservative lower bound using max TTL, otherwise fall back. - if start_date is None: - max_ttl_seconds = 0 - for fv in feature_views: - if fv.ttl and isinstance(fv.ttl, timedelta): - max_ttl_seconds = max( - max_ttl_seconds, int(fv.ttl.total_seconds()) - ) - if max_ttl_seconds > 0: - start_date = end_date - timedelta(seconds=max_ttl_seconds) - else: - # Keep default window bounded to avoid unbounded scans by default. - start_date = end_date - timedelta(days=30) - start_date = make_tzaware(start_date) - - # Minimal synthetic entity_df: one timestamp row; join keys are not materialized here on purpose to avoid - # accidental dependence on specific feature view schemas at this layer. entity_df = pd.DataFrame( {DEFAULT_ENTITY_DF_EVENT_TIMESTAMP_COL: [end_date]} ) @@ -396,7 +387,10 @@ def evaluate_func(): df[DUMMY_ENTITY_ID] = DUMMY_ENTITY_VAL columns_to_extract.add(DUMMY_ENTITY_ID) - return df[list(columns_to_extract)].persist() + if feature_name_columns: + df = df[list(columns_to_extract)] + + return df.persist() # When materializing a single feature view, we don't need full feature names. On demand transforms aren't materialized return DaskRetrievalJob( @@ -418,16 +412,23 @@ def evaluate_offline_job( # Create lazy function that is only called from the RetrievalJob object source_df = _read_datasource(data_source, config.repo_path) - source_df = _normalize_timestamp( - source_df, timestamp_field, created_timestamp_column - ) - + # Validate join keys against source columns BEFORE calling _normalize_timestamp. + # _normalize_timestamp ends with df.persist() which initialises Dask's global + # ThreadPoolExecutor. When the process subsequently exits (e.g. after raising + # FeastJoinKeysDuringMaterialization), Python's atexit handler calls + # ThreadPoolExecutor.shutdown(wait=True) which can block indefinitely, hanging + # the subprocess and preventing the parent from reading its output. + # df.columns is derived from the Parquet schema metadata — no computation needed. source_columns = set(source_df.columns) if not set(join_key_columns).issubset(source_columns): raise FeastJoinKeysDuringMaterialization( data_source.path, set(join_key_columns), source_columns ) + source_df = _normalize_timestamp( + source_df, timestamp_field, created_timestamp_column + ) + # try-catch block is added to deal with this issue https://github.com/dask/dask/issues/8939. # TODO(kevjumba): remove try catch when fix is merged upstream in Dask. try: @@ -502,9 +503,10 @@ def evaluate_func(): columns_to_extract.add(DUMMY_ENTITY_ID) # TODO: Decides if we want to field mapping for pull_latest_from_table_or_query # This is default for other offline store. - df = df[list(columns_to_extract)] - df.persist() - return df + if feature_name_columns: + df = df[list(columns_to_extract)] + + return df.persist() # When materializing a single feature view, we don't need full feature names. On demand transforms aren't materialized return DaskRetrievalJob( @@ -590,6 +592,373 @@ def offline_write_batch( writer.write_table(new_table) writer.close() + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + assert isinstance(data_source, FileSource) + + table = _dask_read_batch_arrow(data_source, config.repo_path) + table = _dask_filter_arrow_by_timestamp( + table, timestamp_field, start_date, end_date + ) + + results: List[Dict[str, Any]] = [] + for name, ftype in feature_columns: + if name not in table.column_names: + continue + col = table[name] + if ftype == "numeric": + m = _dask_compute_numeric_metrics(col, histogram_bins) + elif ftype == "categorical": + m = _dask_compute_categorical_metrics(col, top_n) + else: + continue + m["feature_name"] = name + results.append(m) + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + assert isinstance(data_source, FileSource) + + absolute_path = FileSource.get_uri_for_file_path( + repo_path=config.repo_path, + uri=data_source.file_options.uri, + ) + filesystem, path = FileSource.create_filesystem_and_path( + str(absolute_path), data_source.file_options.s3_endpoint_override + ) + try: + t = pq.read_table(path, filesystem=filesystem, columns=[timestamp_field]) + except Exception: + return None + if t.num_rows == 0: + return None + arr = t[timestamp_field] + mx = pc.max(arr) # type: ignore[attr-defined] + val = mx.as_py() + if val is None: + return None + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + if isinstance(val, date): + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + return None + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + base = os.path.join(_dask_monitoring_base(config), MONITORING_DIR) + os.makedirs(base, exist_ok=True) + + tables = [ + monitoring_parquet_meta(t) + for t in ("feature", "feature_view", "feature_service", "job") + ] + for fname, columns, _ in tables: + fpath = _dask_monitoring_path(config, fname) + if not os.path.isfile(fpath): + os.makedirs(os.path.dirname(fpath), exist_ok=True) + pd.DataFrame(columns=columns).to_parquet(fpath, index=False) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + + fname, columns, pk = _dask_mon_table_meta(metric_type) + path = _dask_monitoring_path(config, fname) + _dask_parquet_upsert(path, columns, pk, metrics) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + + fname, columns, _ = _dask_mon_table_meta(metric_type) + path = _dask_monitoring_path(config, fname) + return _dask_parquet_query( + path, columns, project, filters, start_date, end_date + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, DaskOfflineStoreConfig) + + path = _dask_monitoring_path(config, MONITORING_PARQUET_FILES["feature"]) + tab = _dask_read_parquet_if_exists(path) + if tab is None or tab.num_rows == 0: + return + + df = tab.to_pandas() + mask = df["project_id"] == project + if feature_view_name is not None: + mask = mask & (df["feature_view_name"] == feature_view_name) + if feature_name is not None: + mask = mask & (df["feature_name"] == feature_name) + if data_source_type is not None: + mask = mask & (df["data_source_type"] == data_source_type) + mask = mask & (df["is_baseline"].isin([True, 1])) + df.loc[mask, "is_baseline"] = False + pq.write_table(pyarrow.Table.from_pandas(df, preserve_index=False), path) + + +def _dask_monitoring_base(config: RepoConfig) -> str: + base = config.repo_path + return str(base) if base else "." + + +def _dask_monitoring_path(config: RepoConfig, filename: str) -> str: + return os.path.join(_dask_monitoring_base(config), MONITORING_DIR, filename) + + +def _dask_mon_table_meta(metric_type: str): + return monitoring_parquet_meta(metric_type) + + +def _dask_read_parquet_if_exists(path: str) -> Optional[pyarrow.Table]: + if not os.path.isfile(path): + return None + return pq.read_table(path) + + +def _dask_read_batch_arrow( + data_source: FileSource, repo_path: Optional[Path] +) -> pyarrow.Table: + absolute_path = FileSource.get_uri_for_file_path( + repo_path=repo_path, + uri=data_source.file_options.uri, + ) + filesystem, path = FileSource.create_filesystem_and_path( + str(absolute_path), data_source.file_options.s3_endpoint_override + ) + return pq.read_table(path, filesystem=filesystem) + + +def _dask_filter_arrow_by_timestamp( + table: pyarrow.Table, + timestamp_field: str, + start_date: Optional[datetime], + end_date: Optional[datetime], +) -> pyarrow.Table: + if start_date is None and end_date is None: + return table + arr = table[timestamp_field] + mask = None + if start_date is not None: + mask = pc.greater_equal(arr, pyarrow.scalar(start_date)) # type: ignore[attr-defined] + if end_date is not None: + m2 = pc.less_equal(arr, pyarrow.scalar(end_date)) # type: ignore[attr-defined] + mask = m2 if mask is None else pc.and_(mask, m2) # type: ignore[attr-defined] + return table.filter(mask) + + +def _dask_compute_numeric_metrics( + column: pyarrow.ChunkedArray, histogram_bins: int +) -> Dict[str, Any]: + total = len(column) + null_count = column.null_count + result: Dict[str, Any] = { + "feature_type": "numeric", + "row_count": total, + "null_count": null_count, + "null_rate": null_count / total if total > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + valid = pc.drop_null(column) # type: ignore[attr-defined] + if len(valid) == 0: + return result + + float_array = pc.cast(valid, pyarrow.float64()) + result["mean"] = opt_float(pc.mean(float_array).as_py()) # type: ignore[attr-defined] + result["stddev"] = opt_float(pc.stddev(float_array, ddof=1).as_py()) # type: ignore[attr-defined] + + min_max = pc.min_max(float_array) # type: ignore[attr-defined] + result["min_val"] = min_max["min"].as_py() + result["max_val"] = min_max["max"].as_py() + + quantiles = pc.quantile(float_array, q=[0.50, 0.75, 0.90, 0.95, 0.99]) # type: ignore[attr-defined] + q_values = quantiles.to_pylist() + result["p50"] = q_values[0] + result["p75"] = q_values[1] + result["p90"] = q_values[2] + result["p95"] = q_values[3] + result["p99"] = q_values[4] + + np_array = float_array.to_numpy() + counts, bin_edges = np.histogram(np_array, bins=histogram_bins) + result["histogram"] = { + "bins": bin_edges.tolist(), + "counts": counts.tolist(), + "bin_width": float(bin_edges[1] - bin_edges[0]) if len(bin_edges) > 1 else 0, + } + + return result + + +def _dask_compute_categorical_metrics( + column: pyarrow.ChunkedArray, top_n: int +) -> Dict[str, Any]: + total = len(column) + null_count = column.null_count + result: Dict[str, Any] = { + "feature_type": "categorical", + "row_count": total, + "null_count": null_count, + "null_rate": null_count / total if total > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + valid = pc.drop_null(column) # type: ignore[attr-defined] + if len(valid) == 0: + return result + + value_counts = pc.value_counts(valid) # type: ignore[attr-defined] + entries = [ + {"value": vc["values"].as_py(), "count": vc["counts"].as_py()} + for vc in value_counts + ] + entries.sort(key=lambda x: x["count"], reverse=True) + + unique_count = len(entries) + top_entries = entries[:top_n] + other_count = sum(e["count"] for e in entries[top_n:]) + + result["histogram"] = { + "values": top_entries, + "other_count": other_count, + "unique_count": unique_count, + } + + return result + + +def _dask_parquet_upsert( + path: str, + columns: List[str], + pk_cols: List[str], + new_rows: List[Dict[str, Any]], +) -> None: + os.makedirs(os.path.dirname(path), exist_ok=True) + + prepared: List[Dict[str, Any]] = [] + for row in new_rows: + r = dict(row) + if ( + "histogram" in r + and r["histogram"] is not None + and not isinstance(r["histogram"], str) + ): + r["histogram"] = json.dumps(r["histogram"]) + prepared.append(r) + + new_df = pd.DataFrame(prepared, columns=columns) + existing = _dask_read_parquet_if_exists(path) + if existing is not None: + old_df = existing.to_pandas() + combined = pd.concat([old_df, new_df], ignore_index=True) + else: + combined = new_df + + combined = combined.drop_duplicates(subset=pk_cols, keep="last") + table = pyarrow.Table.from_pandas(combined, preserve_index=False) + pq.write_table(table, path) + + +def _dask_parquet_query( + path: str, + columns: List[str], + project: str, + filters: Optional[Dict[str, Any]], + start_date: Optional[date], + end_date: Optional[date], +) -> List[Dict[str, Any]]: + tab = _dask_read_parquet_if_exists(path) + if tab is None or tab.num_rows == 0: + return [] + + df = tab.to_pandas() + if project: + df = df[df["project_id"] == project] + if filters: + for key, value in filters.items(): + if value is not None: + df = df[df[key] == value] + if "metric_date" in df.columns: + if start_date is not None: + df = df[df["metric_date"] >= start_date] + if end_date is not None: + df = df[df["metric_date"] <= end_date] + df = df.sort_values("metric_date", ascending=True) + else: + df = df.sort_values("job_id", ascending=True) + + results = [] + for _, row in df.iterrows(): + record = {c: row.get(c) for c in columns} + normalize_monitoring_row(record) + for key in ("metric_date", "computed_at"): + val = record.get(key) + if ( + val is not None + and not isinstance(val, str) + and hasattr(val, "isoformat") + ): + record[key] = val.isoformat() + results.append(record) + + return results + def _get_entity_df_event_timestamp_range( entity_df: Union[pd.DataFrame, str], diff --git a/sdk/python/feast/infra/offline_stores/duckdb.py b/sdk/python/feast/infra/offline_stores/duckdb.py index e0a69e53c56..bac17217aa3 100644 --- a/sdk/python/feast/infra/offline_stores/duckdb.py +++ b/sdk/python/feast/infra/offline_stores/duckdb.py @@ -1,11 +1,15 @@ +import json import os -from datetime import datetime +from datetime import date, datetime, timezone from pathlib import Path -from typing import Any, Callable, List, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Tuple, Union +import duckdb import ibis import pandas as pd import pyarrow +import pyarrow as pa +import pyarrow.parquet as pq from ibis.expr.types import Table from pydantic import StrictStr @@ -23,14 +27,26 @@ write_logged_features_ibis, ) from feast.infra.offline_stores.offline_store import OfflineStore, RetrievalJob +from feast.infra.offline_stores.offline_utils import get_timestamp_filter_sql from feast.infra.registry.base_registry import BaseRegistry +from feast.monitoring.monitoring_utils import ( + MONITORING_DIR, + MONITORING_PARQUET_FILES, + empty_categorical_metric, + empty_numeric_metric, + monitoring_parquet_meta, + normalize_monitoring_row, + opt_float, +) from feast.repo_config import FeastConfigBaseModel, RepoConfig def _read_data_source(data_source: DataSource, repo_path: str) -> Table: assert isinstance(data_source, FileSource) - if isinstance(data_source.file_format, ParquetFormat): + if isinstance(data_source.file_format, ParquetFormat) or ( + data_source.file_format is None and data_source.path.endswith(".parquet") + ): return ibis.read_parquet(data_source.path) elif isinstance(data_source.file_format, DeltaFormat): if data_source.s3_endpoint_override: @@ -63,7 +79,9 @@ def _write_data_source( ): raise SavedDatasetLocationAlreadyExists(location=file_options.uri) - if isinstance(data_source.file_format, ParquetFormat): + if data_source.file_format is None or isinstance( + data_source.file_format, ParquetFormat + ): if mode == "overwrite": table = table.to_pyarrow() @@ -113,6 +131,318 @@ def _write_data_source( ) +# ------------------------------------------------------------------ # +# DuckDB monitoring (Parquet-backed) +# ------------------------------------------------------------------ # + + +def _duckdb_monitoring_base(config: RepoConfig) -> str: + base = config.repo_path + return str(base) if base else "." + + +def _duckdb_monitoring_path(config: RepoConfig, filename: str) -> str: + return os.path.join(_duckdb_monitoring_base(config), MONITORING_DIR, filename) + + +def _duckdb_parquet_from_expression(config: RepoConfig, data_source: FileSource) -> str: + absolute_path = FileSource.get_uri_for_file_path( + repo_path=_duckdb_monitoring_base(config), + uri=data_source.file_options.uri, + ) + return str(absolute_path).replace("'", "''") + + +def _duckdb_quote_ident(name: str) -> str: + return f'"{name}"' + + +def _duckdb_ts_where(ts_filter: str) -> str: + return f"({ts_filter})" if (ts_filter and ts_filter.strip()) else "1=1" + + +def _duckdb_numeric_stats( + conn: duckdb.DuckDBPyConnection, + from_expr: str, + feature_names: List[str], + ts_filter: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + select_parts = ["COUNT(*)"] + for col in feature_names: + q = _duckdb_quote_ident(col) + c = f"CAST({q} AS DOUBLE)" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY {c})", + ] + ) + + tw = _duckdb_ts_where(ts_filter) + query = f"SELECT {', '.join(select_parts)} FROM {from_expr} AS _src WHERE {tw}" + row = conn.execute(query).fetchone() + + if row is None: + return [empty_numeric_metric(n) for n in feature_names] + + row_count = row[0] + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = row[base] or 0 + null_count = row_count - non_null + + min_val = opt_float(row[base + 3]) + max_val = opt_float(row[base + 4]) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[base + 1]), + "stddev": opt_float(row[base + 2]), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(row[base + 5]), + "p75": opt_float(row[base + 6]), + "p90": opt_float(row[base + 7]), + "p95": opt_float(row[base + 8]), + "p99": opt_float(row[base + 9]), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _duckdb_numeric_histogram( + conn, + from_expr, + col, + ts_filter, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _duckdb_numeric_histogram( + conn: duckdb.DuckDBPyConnection, + from_expr: str, + col_name: str, + ts_filter: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = _duckdb_quote_ident(col_name) + + tw = _duckdb_ts_where(ts_filter) + if min_val == max_val: + row = conn.execute( + f"SELECT COUNT(*) FROM {from_expr} AS _src " + f"WHERE {q_col} IS NOT NULL AND {tw}" + ).fetchone() + cnt = row[0] if row else 0 + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + bin_width = (max_val - min_val) / bins + + query = ( + f"SELECT LEAST(FLOOR((CAST({q_col} AS DOUBLE) - {min_val}) / {bin_width}) + 1, {bins}) AS bucket, " + f"COUNT(*) AS cnt " + f"FROM {from_expr} AS _src " + f"WHERE {q_col} IS NOT NULL AND {tw} " + f"GROUP BY bucket ORDER BY bucket" + ) + rows = conn.execute(query).fetchall() + + counts = [0] * bins + for bucket, cnt in rows: + b = int(bucket) + if 1 <= b <= bins: + counts[b - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _duckdb_categorical_stats( + conn: duckdb.DuckDBPyConnection, + from_expr: str, + col_name: str, + ts_filter: str, + top_n: int, +) -> Dict[str, Any]: + q_col = _duckdb_quote_ident(col_name) + + tw = _duckdb_ts_where(ts_filter) + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expr} AS _src WHERE {tw}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" CAST({q_col} AS VARCHAR) AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} " + f"ORDER BY cnt DESC LIMIT {int(top_n)}" + ) + + rows = conn.execute(query).fetchall() + + if not rows: + return empty_categorical_metric(col_name) + + row_count = rows[0][0] + null_count = rows[0][1] + unique_count = rows[0][2] + + top_entries = [{"value": r[3], "count": r[4]} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +def _duckdb_mon_table_meta(metric_type: str): + return monitoring_parquet_meta(metric_type) + + +def _duckdb_read_parquet_if_exists(path: str) -> Optional[pa.Table]: + if not os.path.isfile(path): + return None + return pq.read_table(path) + + +def _duckdb_parquet_upsert( + path: str, + columns: List[str], + pk_cols: List[str], + new_rows: List[Dict[str, Any]], +) -> None: + os.makedirs(os.path.dirname(path), exist_ok=True) + + prepared: List[Dict[str, Any]] = [] + for row in new_rows: + r = dict(row) + if ( + "histogram" in r + and r["histogram"] is not None + and not isinstance(r["histogram"], str) + ): + r["histogram"] = json.dumps(r["histogram"]) + prepared.append(r) + + new_df = pd.DataFrame(prepared, columns=columns) + existing = _duckdb_read_parquet_if_exists(path) + if existing is not None: + old_df = existing.to_pandas() + combined = pd.concat([old_df, new_df], ignore_index=True) + else: + combined = new_df + + combined = combined.drop_duplicates(subset=pk_cols, keep="last") + table = pa.Table.from_pandas(combined, preserve_index=False) + pq.write_table(table, path) + + +def _duckdb_parquet_query( + path: str, + columns: List[str], + project: str, + filters: Optional[Dict[str, Any]], + start_date: Optional[date], + end_date: Optional[date], +) -> List[Dict[str, Any]]: + tab = _duckdb_read_parquet_if_exists(path) + if tab is None or tab.num_rows == 0: + return [] + + df = tab.to_pandas() + if project: + df = df[df["project_id"] == project] + if filters: + for key, value in filters.items(): + if value is not None: + df = df[df[key] == value] + if "metric_date" in df.columns: + if start_date is not None: + df = df[df["metric_date"] >= start_date] + if end_date is not None: + df = df[df["metric_date"] <= end_date] + df = df.sort_values("metric_date", ascending=True) + else: + df = df.sort_values("job_id", ascending=True) + + results = [] + for _, row in df.iterrows(): + record = {c: row.get(c) for c in columns} + normalize_monitoring_row(record) + for key in ("metric_date", "computed_at"): + val = record.get(key) + if ( + val is not None + and not isinstance(val, str) + and hasattr(val, "isoformat") + ): + record[key] = val.isoformat() + results.append(record) + + return results + + +def _duckdb_sql_from_expression(config: RepoConfig, data_source: FileSource) -> str: + p = _duckdb_parquet_from_expression(config, data_source) + if isinstance(data_source.file_format, ParquetFormat): + return f"read_parquet('{p}')" + if isinstance(data_source.file_format, DeltaFormat): + return f"delta_scan('{p}')" + raise NotImplementedError( + "DuckDB monitoring compute supports Parquet and Delta file sources only." + ) + + class DuckDBOfflineStoreConfig(FeastConfigBaseModel): type: StrictStr = "duckdb" # """ Offline store type selector""" @@ -229,3 +559,155 @@ def write_logged_features( logging_config=logging_config, registry=registry, ) + + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + assert isinstance(data_source, FileSource) + + from_expr = _duckdb_sql_from_expression(config, data_source) + ts_filter = get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + tz=timezone.utc, + cast_style="timestamp", + date_time_separator=" ", + ) + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + conn = duckdb.connect() + if numeric_features: + results.extend( + _duckdb_numeric_stats( + conn, + from_expr, + numeric_features, + ts_filter, + histogram_bins, + ) + ) + for col_name in categorical_features: + results.append( + _duckdb_categorical_stats( + conn, + from_expr, + col_name, + ts_filter, + top_n, + ) + ) + conn.close() + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + assert isinstance(data_source, FileSource) + + from_expr = _duckdb_sql_from_expression(config, data_source) + ts_col = _duckdb_quote_ident(timestamp_field) + conn = duckdb.connect() + row = conn.execute( + f"SELECT MAX({ts_col}) AS m FROM {from_expr} AS _src" + ).fetchone() + conn.close() + + if row is None or row[0] is None: + return None + val = row[0] + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + if isinstance(val, date): + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + return None + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + base = os.path.join(_duckdb_monitoring_base(config), MONITORING_DIR) + os.makedirs(base, exist_ok=True) + + tables = [ + monitoring_parquet_meta(t) + for t in ("feature", "feature_view", "feature_service", "job") + ] + for fname, columns, _ in tables: + path = _duckdb_monitoring_path(config, fname) + if not os.path.isfile(path): + os.makedirs(os.path.dirname(path), exist_ok=True) + pd.DataFrame(columns=columns).to_parquet(path, index=False) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + + fname, columns, pk = _duckdb_mon_table_meta(metric_type) + path = _duckdb_monitoring_path(config, fname) + _duckdb_parquet_upsert(path, columns, pk, metrics) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + + fname, columns, _ = _duckdb_mon_table_meta(metric_type) + path = _duckdb_monitoring_path(config, fname) + return _duckdb_parquet_query( + path, columns, project, filters, start_date, end_date + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, DuckDBOfflineStoreConfig) + + path = _duckdb_monitoring_path(config, MONITORING_PARQUET_FILES["feature"]) + tab = _duckdb_read_parquet_if_exists(path) + if tab is None or tab.num_rows == 0: + return + + df = tab.to_pandas() + mask = df["project_id"] == project + if feature_view_name is not None: + mask = mask & (df["feature_view_name"] == feature_view_name) + if feature_name is not None: + mask = mask & (df["feature_name"] == feature_name) + if data_source_type is not None: + mask = mask & (df["data_source_type"] == data_source_type) + mask = mask & (df["is_baseline"].isin([True, 1])) + df.loc[mask, "is_baseline"] = False + pq.write_table(pa.Table.from_pandas(df, preserve_index=False), path) diff --git a/sdk/python/feast/infra/offline_stores/ibis.py b/sdk/python/feast/infra/offline_stores/ibis.py index 2d0adbfdb73..3aebc4e903e 100644 --- a/sdk/python/feast/infra/offline_stores/ibis.py +++ b/sdk/python/feast/infra/offline_stores/ibis.py @@ -53,8 +53,8 @@ def pull_latest_from_table_or_query_ibis( fields = join_key_columns + feature_name_columns + [timestamp_field] if created_timestamp_column: fields.append(created_timestamp_column) - start_date = start_date.astimezone(tz=timezone.utc) - end_date = end_date.astimezone(tz=timezone.utc) + start_date = start_date.astimezone(tz=timezone.utc).replace(tzinfo=None) + end_date = end_date.astimezone(tz=timezone.utc).replace(tzinfo=None) table = data_source_reader(data_source, str(config.repo_path)) @@ -66,8 +66,8 @@ def pull_latest_from_table_or_query_ibis( table = table.filter( ibis.and_( - table[timestamp_field] >= ibis.literal(start_date), - table[timestamp_field] <= ibis.literal(end_date), + table[timestamp_field].cast("timestamp") >= ibis.literal(start_date), + table[timestamp_field].cast("timestamp") <= ibis.literal(end_date), ) ) @@ -197,7 +197,7 @@ def read_fv( } ) - full_name_prefix = feature_view.projection.name_alias or feature_view.name + full_name_prefix = feature_view.projection.name_to_use() feature_refs = [ fr.split(":")[1] @@ -205,13 +205,16 @@ def read_fv( if fr.startswith(f"{full_name_prefix}:") ] + # Use base name (without version) for column naming + base_name_prefix = feature_view.projection.name_alias or feature_view.name + if full_feature_names: fv_table = fv_table.rename( - {f"{full_name_prefix}__{feature}": feature for feature in feature_refs} + {f"{base_name_prefix}__{feature}": feature for feature in feature_refs} ) feature_refs = [ - f"{full_name_prefix}__{feature}" for feature in feature_refs + f"{base_name_prefix}__{feature}" for feature in feature_refs ] return ( @@ -276,9 +279,9 @@ def pull_all_from_table_or_query_ibis( timestamp_fields.append(created_timestamp_column) fields = join_key_columns + feature_name_columns + timestamp_fields if start_date: - start_date = start_date.astimezone(tz=timezone.utc) + start_date = start_date.astimezone(tz=timezone.utc).replace(tzinfo=None) if end_date: - end_date = end_date.astimezone(tz=timezone.utc) + end_date = end_date.astimezone(tz=timezone.utc).replace(tzinfo=None) table = data_source_reader(data_source, str(config.repo_path)) @@ -290,10 +293,10 @@ def pull_all_from_table_or_query_ibis( table = table.filter( ibis.and_( - table[timestamp_field] >= ibis.literal(start_date) + table[timestamp_field].cast("timestamp") >= ibis.literal(start_date) if start_date else ibis.literal(True), - table[timestamp_field] <= ibis.literal(end_date) + table[timestamp_field].cast("timestamp") <= ibis.literal(end_date) if end_date else ibis.literal(True), ) diff --git a/sdk/python/feast/infra/offline_stores/offline_store.py b/sdk/python/feast/infra/offline_stores/offline_store.py index 5961c1f4292..e8cf5e5c796 100644 --- a/sdk/python/feast/infra/offline_stores/offline_store.py +++ b/sdk/python/feast/infra/offline_stores/offline_store.py @@ -11,9 +11,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import logging +import time import warnings from abc import ABC -from datetime import datetime +from datetime import date, datetime, timedelta, timezone from pathlib import Path from typing import ( TYPE_CHECKING, @@ -70,6 +72,23 @@ def __init__( self.max_event_timestamp = max_event_timestamp +def _extract_retrieval_metadata(job: "RetrievalJob") -> tuple: + """Return ``(feature_view_names, feature_count)`` from a RetrievalJob's metadata.""" + from feast.utils import _parse_feature_ref + + try: + meta = job.metadata + if meta: + feature_count = len(meta.features) + feature_views = list( + {_parse_feature_ref(ref)[0] for ref in meta.features if ":" in ref} + ) + return feature_views, feature_count + except (NotImplementedError, AttributeError): + pass + return [], 0 + + class RetrievalJob(ABC): """A RetrievalJob manages the execution of a query to retrieve data from the offline store.""" @@ -152,19 +171,105 @@ def to_arrow( validation_reference (optional): The validation to apply against the retrieved dataframe. timeout (optional): The query timeout if applicable. """ - features_table = self._to_arrow_internal(timeout=timeout) + start_wall = time.monotonic() + status_label = "success" + row_count = 0 + try: + features_table = self._to_arrow_internal(timeout=timeout) + row_count = features_table.num_rows + except Exception: + status_label = "error" + raise + finally: + try: + from feast import metrics as feast_metrics + + elapsed = time.monotonic() - start_wall + + if feast_metrics._config.offline_features: + feast_metrics.offline_store_request_total.labels( + method="to_arrow", status=status_label + ).inc() + feast_metrics.offline_store_request_latency_seconds.labels( + method="to_arrow" + ).observe(elapsed) + feast_metrics.offline_store_row_count.labels( + method="to_arrow" + ).observe(row_count) + + if feast_metrics._config.audit_logging: + feature_views, feature_count = _extract_retrieval_metadata(self) + end_dt = datetime.now(tz=timezone.utc) + start_dt = end_dt - timedelta(seconds=elapsed) + feast_metrics.emit_offline_audit_log( + method="to_arrow", + feature_views=feature_views, + feature_count=feature_count, + row_count=row_count, + status=status_label, + start_time=start_dt.isoformat(), + end_time=end_dt.isoformat(), + duration_ms=elapsed * 1000, + ) + except Exception: + logging.getLogger(__name__).debug( + "Failed to record offline store metrics", exc_info=True + ) + if self.on_demand_feature_views: + # Build a mapping of ODFV name to requested feature names + # This ensures we only return the features that were explicitly requested + odfv_feature_refs: Dict[str, set[str]] = {} + try: + metadata = self.metadata + except NotImplementedError: + metadata = None + + if metadata and metadata.features: + for feature_ref in metadata.features: + if ":" in feature_ref: + view_name, feature_name = feature_ref.split(":", 1) + # Check if this view_name matches any of the ODFVs + for odfv in self.on_demand_feature_views: + if ( + odfv.name == view_name + or odfv.projection.name_to_use() == view_name + ): + if view_name not in odfv_feature_refs: + odfv_feature_refs[view_name] = set() + # Store the feature name in the format that will appear in transformed_arrow + expected_col_name = ( + f"{odfv.projection.name_to_use()}__{feature_name}" + if self.full_feature_names + else feature_name + ) + odfv_feature_refs[view_name].add(expected_col_name) + for odfv in self.on_demand_feature_views: transformed_arrow = odfv.transform_arrow( features_table, self.full_feature_names ) + # Determine which columns to include from this ODFV + # If we have metadata with requested features, filter to only those + # Otherwise, include all columns (backward compatibility) + requested_features_for_odfv = ( + odfv_feature_refs.get(odfv.name) + if odfv.name in odfv_feature_refs + else odfv_feature_refs.get(odfv.projection.name_to_use()) + ) + for col in transformed_arrow.column_names: if col.startswith("__index"): continue - features_table = features_table.append_column( - col, transformed_arrow[col] - ) + # Only append the column if it was requested, or if we don't have feature metadata + if ( + requested_features_for_odfv is None + or col in requested_features_for_odfv + ): + features_table = features_table.append_column( + col, transformed_arrow[col] + ) if validation_reference: if not flags_helper.is_test(): @@ -217,6 +322,49 @@ def to_tensor( tensor_dict[column] = values return tensor_dict + def to_ray_dataset(self) -> Any: + """Convert the retrieval result to a Ray Dataset. + + This is a first-class method on every ``RetrievalJob`` regardless of + the configured offline store backend: + + * **Ray offline store** – ``RayRetrievalJob`` overrides this method and + returns the underlying ``ray.data.Dataset`` *without* materialising the + result to the driver, keeping the full computation on the cluster. + * **All other offline stores** – the default implementation here pulls + the result to an Arrow table on the driver and converts it via + ``ray.data.from_arrow()``. This is less efficient than the native + Ray path but lets every backend participate in Ray pipelines. + + Example:: + + from feast import FeatureStore + + store = FeatureStore(".") + ds = store.get_historical_features( + entity_df=entity_df, + features=["driver_stats:conv_rate"], + ).to_ray_dataset() + + # Chain Ray Data transforms directly + predictions = ds.map_batches(MyModel, num_gpus=1) + + Returns: + ray.data.Dataset: Dataset containing the retrieved feature rows. + + Raises: + ImportError: If ``ray`` is not installed. Install via + ``pip install 'feast[ray]'``. + """ + try: + import ray.data + except ImportError as e: + raise ImportError( + "Ray is required to call to_ray_dataset(). " + "Install it with: pip install 'feast[ray]'" + ) from e + return ray.data.from_arrow(self.to_arrow()) + def to_sql(self) -> str: """ Return RetrievalJob generated SQL statement if applicable. @@ -474,3 +622,137 @@ def get_table_column_names_and_types_from_data_source( data_source: DataSource object """ return data_source.get_table_column_names_and_types(config=config) + + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + """ + Compute monitoring metrics (stats, percentiles, histograms) directly + in the offline store using its native compute engine. + + Backends that don't support this should leave it unimplemented; + the monitoring service will fall back to Python-based computation. + + Args: + config: The config for the current feature store. + data_source: The data source to compute metrics from. + feature_columns: List of (feature_name, feature_type) where + feature_type is "numeric" or "categorical". + timestamp_field: Column used for time-range filtering. + start_date: Start of the time range. + end_date: End of the time range. + histogram_bins: Number of bins for numeric histograms. + top_n: Number of top values for categorical histograms. + + Returns: + A list of metric dicts, one per feature, matching the format + produced by MetricsCalculator.compute_all. + """ + raise NotImplementedError + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + """ + Return the maximum event timestamp from the data source. + + Used by the monitoring service to determine date ranges for + auto-compute. Backends that don't support this should leave it + unimplemented; the caller will fall back to a full-table scan. + + Args: + config: The config for the current feature store. + data_source: The data source to query. + timestamp_field: The timestamp column name. + + Returns: + The maximum timestamp, or None if no data exists. + """ + raise NotImplementedError + + # ------------------------------------------------------------------ # + # Monitoring metrics storage (native) + # ------------------------------------------------------------------ # + + MONITORING_VALID_GRANULARITIES = ( + "daily", + "weekly", + "biweekly", + "monthly", + "quarterly", + ) + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + """Create the monitoring metrics tables if they do not exist. + + Backends that don't support native monitoring storage should + leave this unimplemented; the monitoring service will raise an + error indicating the backend lacks storage support. + """ + raise NotImplementedError + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + """Persist monitoring metrics (upsert semantics). + + Args: + config: The config for the current feature store. + metric_type: One of "feature", "feature_view", "feature_service". + metrics: List of metric dicts to upsert. + """ + raise NotImplementedError + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + """Read monitoring metrics with optional filtering. + + Args: + config: The config for the current feature store. + project: Feast project name. + metric_type: One of "feature", "feature_view", "feature_service". + filters: Column-value pairs for WHERE clauses. + start_date: Inclusive lower bound on metric_date. + end_date: Inclusive upper bound on metric_date. + + Returns: + List of metric dicts ordered by metric_date ascending. + """ + raise NotImplementedError + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + """Set is_baseline=FALSE for matching feature metric rows. + + Used to ensure only one baseline exists per feature before + writing a new baseline. + """ + raise NotImplementedError diff --git a/sdk/python/feast/infra/offline_stores/offline_utils.py b/sdk/python/feast/infra/offline_stores/offline_utils.py index 0c478adb2c4..fee87dde595 100644 --- a/sdk/python/feast/infra/offline_stores/offline_utils.py +++ b/sdk/python/feast/infra/offline_stores/offline_utils.py @@ -1,3 +1,4 @@ +import logging import uuid from dataclasses import asdict, dataclass from datetime import datetime, timedelta, timezone @@ -21,6 +22,7 @@ from feast.repo_config import RepoConfig from feast.type_map import feast_value_type_to_pa from feast.utils import _get_requested_feature_views_to_features_dict, to_naive_utc +from feast.value_type import ValueType DEFAULT_ENTITY_DF_EVENT_TIMESTAMP_COL = "event_timestamp" @@ -96,6 +98,7 @@ class FeatureViewQueryContext: date_partition_column: Optional[ str ] # this attribute is added because partition pruning affects Athena's query performance. + timestamp_field_type: Optional[str] def get_feature_view_query_context( @@ -158,6 +161,10 @@ def get_feature_view_query_context( feature_view.batch_source.date_partition_column, ) + timestamp_field_type = getattr( + feature_view.batch_source, "timestamp_field_type", "" + ) + max_event_timestamp = to_naive_utc(entity_df_timestamp_range[1]).isoformat() min_event_timestamp = None if feature_view.ttl: @@ -179,6 +186,7 @@ def get_feature_view_query_context( min_event_timestamp=min_event_timestamp, max_event_timestamp=max_event_timestamp, date_partition_column=date_partition_column, + timestamp_field_type=timestamp_field_type or None, ) query_context.append(context) @@ -241,6 +249,37 @@ def get_offline_store_from_config(offline_store_config: Any) -> OfflineStore: return offline_store_class() +_PA_BASIC_TYPES = { + "int32": pa.int32(), + "int64": pa.int64(), + "double": pa.float64(), + "float": pa.float32(), + "string": pa.string(), + "binary": pa.binary(), + "bool": pa.bool_(), + "large_string": pa.large_string(), + "null": pa.null(), +} + + +def _parse_pa_type_str(pa_type_str: str) -> pa.DataType: + """Parse a PyArrow type string to preserve inner element types for nested lists.""" + pa_type_str = pa_type_str.strip() + if pa_type_str.startswith("list"): + inner = pa_type_str[len("list Tuple[pa.Schema, List[str]]: @@ -250,15 +289,12 @@ def get_pyarrow_schema_from_batch_source( pa_schema = [] column_names = [] for column_name, column_type in column_names_and_types: - pa_schema.append( - ( - column_name, - feast_value_type_to_pa( - batch_source.source_datatype_to_feast_value_type()(column_type), - timestamp_unit=timestamp_unit, - ), - ) - ) + value_type = batch_source.source_datatype_to_feast_value_type()(column_type) + if value_type in (ValueType.VALUE_LIST, ValueType.VALUE_SET): + pa_type = _parse_pa_type_str(column_type) + else: + pa_type = feast_value_type_to_pa(value_type, timestamp_unit=timestamp_unit) + pa_schema.append((column_name, pa_type)) column_names.append(column_name) return pa.schema(pa_schema), column_names @@ -310,7 +346,7 @@ def get_timestamp_filter_sql( date_partition_column: Optional[str] = None, tz: Optional[timezone] = None, cast_style: Literal[ - "timestamp", "timestamp_func", "timestamptz", "raw" + "timestamp", "timestamp_func", "timestamptz", "raw", "date_func" ] = "timestamp", date_time_separator: str = "T", quote_fields: bool = True, @@ -325,10 +361,11 @@ def get_timestamp_filter_sql( date_partition_column: optional partition column (for pruning) tz: optional timezone for datetime inputs cast_style: one of: - - "timestamp": TIMESTAMP '...' → Common Sql engine Snowflake, Redshift etc. + - "timestamp": TIMESTAMP '...' → Common Sql engine Snowflake, Redshift etc. - "timestamp_func": TIMESTAMP('...') → BigQuery, Couchbase etc. - "timestamptz": '...'::timestamptz → PostgreSQL - "raw": '...' → no cast, string only + - "date_func": DATE('...') → BigQuery DATE columns date_time_separator: separator for datetime strings (default is "T") (e.g. "2023-10-01T00:00:00" or "2023-10-01 00:00:00") quote_fields: whether to quote the timestamp and partition column names @@ -354,6 +391,9 @@ def format_casted_ts(val: Union[str, datetime]) -> str: return f"TIMESTAMP '{val_str}'" elif cast_style == "timestamp_func": return f"TIMESTAMP('{val_str}')" + elif cast_style == "date_func": + date_str = val_str[:10] if len(val_str) >= 10 else val_str + return f"DATE('{date_str}')" elif cast_style == "timestamptz": return f"'{val_str}'::{cast_style}" else: diff --git a/sdk/python/feast/infra/offline_stores/redshift.py b/sdk/python/feast/infra/offline_stores/redshift.py index 900dfcfab80..ec708ccf798 100644 --- a/sdk/python/feast/infra/offline_stores/redshift.py +++ b/sdk/python/feast/infra/offline_stores/redshift.py @@ -1,6 +1,7 @@ import contextlib +import json import uuid -from datetime import datetime, timezone +from datetime import date, datetime, timezone from pathlib import Path from typing import ( Any, @@ -40,6 +41,17 @@ ) from feast.infra.registry.base_registry import BaseRegistry from feast.infra.utils import aws_utils +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage @@ -378,6 +390,584 @@ def offline_write_batch( fail_if_exists=False, ) + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + assert isinstance(data_source, RedshiftSource) + + from_expression = data_source.get_table_query_string() + ts_filter = get_timestamp_filter_sql( + start_date, + end_date, + timestamp_field, + tz=timezone.utc, + ) + ts_clause = ts_filter if ts_filter else "1=1" + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + if numeric_features: + results.extend( + _redshift_sql_numeric_stats( + config, + from_expression, + numeric_features, + ts_clause, + histogram_bins, + ) + ) + + for col_name in categorical_features: + results.append( + _redshift_sql_categorical_stats( + config, from_expression, col_name, ts_clause, top_n + ) + ) + + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + assert isinstance(data_source, RedshiftSource) + + from_expression = data_source.get_table_query_string() + q_ts = f'"{timestamp_field}"' + sql = f"SELECT MAX({q_ts}) AS max_ts FROM {from_expression} AS _src" + rows = _redshift_execute_fetch_rows(config, sql) + if not rows or not rows[0]: + return None + val = _redshift_field_value(rows[0][0]) + if val is None: + return None + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + return parser.parse(str(val)) + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + for stmt in _REDSHIFT_MONITORING_DDL_STATEMENTS: + _redshift_execute_statement(config, stmt) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + table, columns, pk_columns = monitoring_table_meta(metric_type) + for row in metrics: + _redshift_merge_metric_row(config, table, columns, pk_columns, row) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + _, columns, _ = monitoring_table_meta(metric_type) + return _redshift_mon_query( + config, metric_type, columns, project, filters, start_date, end_date + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, RedshiftOfflineStoreConfig) + parts = [ + f"project_id = {_redshift_sql_literal(project)}", + "is_baseline = TRUE", + ] + if feature_view_name is not None: + parts.append( + f"feature_view_name = {_redshift_sql_literal(feature_view_name)}" + ) + if feature_name is not None: + parts.append(f"feature_name = {_redshift_sql_literal(feature_name)}") + if data_source_type is not None: + parts.append( + f"data_source_type = {_redshift_sql_literal(data_source_type)}" + ) + where_sql = " AND ".join(parts) + sql = f"UPDATE {MON_TABLE_FEATURE} SET is_baseline = FALSE WHERE {where_sql}" + _redshift_execute_statement(config, sql) + + +_REDSHIFT_MONITORING_DDL_STATEMENTS = [ + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE} ( + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255) NOT NULL, + feature_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + feature_type VARCHAR(50) NOT NULL, + row_count BIGINT, + null_count BIGINT, + null_rate DOUBLE PRECISION, + mean DOUBLE PRECISION, + stddev DOUBLE PRECISION, + min_val DOUBLE PRECISION, + max_val DOUBLE PRECISION, + p50 DOUBLE PRECISION, + p75 DOUBLE PRECISION, + p90 DOUBLE PRECISION, + p95 DOUBLE PRECISION, + p99 DOUBLE PRECISION, + histogram VARCHAR(65535), + PRIMARY KEY (project_id, feature_view_name, feature_name, + metric_date, granularity, data_source_type) +); +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_VIEW} ( + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + total_row_count BIGINT, + total_features INTEGER, + features_with_nulls INTEGER, + avg_null_rate DOUBLE PRECISION, + max_null_rate DOUBLE PRECISION, + PRIMARY KEY (project_id, feature_view_name, metric_date, + granularity, data_source_type) +); +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_FEATURE_SERVICE} ( + project_id VARCHAR(255) NOT NULL, + feature_service_name VARCHAR(255) NOT NULL, + metric_date DATE NOT NULL, + granularity VARCHAR(20) NOT NULL DEFAULT 'daily', + data_source_type VARCHAR(50) NOT NULL DEFAULT 'batch', + computed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_baseline BOOLEAN NOT NULL DEFAULT FALSE, + total_feature_views INTEGER, + total_features INTEGER, + avg_null_rate DOUBLE PRECISION, + max_null_rate DOUBLE PRECISION, + PRIMARY KEY (project_id, feature_service_name, metric_date, + granularity, data_source_type) +); +""", + f""" +CREATE TABLE IF NOT EXISTS {MON_TABLE_JOB} ( + job_id VARCHAR(36) NOT NULL, + project_id VARCHAR(255) NOT NULL, + feature_view_name VARCHAR(255), + job_type VARCHAR(50) NOT NULL, + status VARCHAR(20) NOT NULL DEFAULT 'pending', + parameters VARCHAR(65535), + metric_date DATE NOT NULL, + started_at TIMESTAMPTZ, + completed_at TIMESTAMPTZ, + error_message VARCHAR(65535), + result_summary VARCHAR(65535), + PRIMARY KEY (job_id) +); +""", +] + + +def _redshift_execute_statement(config: RepoConfig, sql: str) -> str: + client = aws_utils.get_redshift_data_client(config.offline_store.region) + return aws_utils.execute_redshift_statement( + client, + config.offline_store.cluster_id, + config.offline_store.workgroup, + config.offline_store.database, + config.offline_store.user, + sql, + ) + + +def _redshift_get_statement_pages( + client: Any, statement_id: str +) -> Tuple[List[Dict[str, Any]], List[List[Dict[str, Any]]]]: + column_metadata: List[Dict[str, Any]] = [] + all_records: List[List[Dict[str, Any]]] = [] + next_token: Optional[str] = None + while True: + kwargs: Dict[str, Any] = {"Id": statement_id} + if next_token: + kwargs["NextToken"] = next_token + resp = client.get_statement_result(**kwargs) + if not column_metadata: + column_metadata = resp.get("ColumnMetadata", []) + all_records.extend(resp.get("Records", [])) + next_token = resp.get("NextToken") + if not next_token: + break + return column_metadata, all_records + + +def _redshift_execute_fetch_rows( + config: RepoConfig, sql: str +) -> List[List[Dict[str, Any]]]: + client = aws_utils.get_redshift_data_client(config.offline_store.region) + sid = aws_utils.execute_redshift_statement( + client, + config.offline_store.cluster_id, + config.offline_store.workgroup, + config.offline_store.database, + config.offline_store.user, + sql, + ) + _, records = _redshift_get_statement_pages(client, sid) + return records + + +def _redshift_field_value(field: Dict[str, Any]) -> Any: + if field.get("isNull"): + return None + if "stringValue" in field: + return field["stringValue"] + if "longValue" in field: + return field["longValue"] + if "doubleValue" in field: + return field["doubleValue"] + if "booleanValue" in field: + return field["booleanValue"] + return None + + +def _redshift_sql_literal(val: Any) -> str: + if val is None: + return "NULL" + if isinstance(val, bool): + return "TRUE" if val else "FALSE" + if isinstance(val, (int, float)) and not isinstance(val, bool): + return str(val) + if isinstance(val, date) and not isinstance(val, datetime): + return f"DATE '{val.isoformat()}'" + if isinstance(val, datetime): + s = val.isoformat(sep=" ", timespec="seconds") + return f"TIMESTAMP '{s}'" + s = str(val).replace("'", "''") + return f"'{s}'" + + +def _redshift_merge_metric_row( + config: RepoConfig, + table: str, + columns: List[str], + pk_columns: List[str], + row: Dict[str, Any], +) -> None: + non_pk = [c for c in columns if c not in pk_columns] + client = aws_utils.get_redshift_data_client(config.offline_store.region) + + select_parts = ", ".join( + f"{_redshift_sql_literal_for_column(c, row.get(c))} AS {c}" for c in columns + ) + on_clause = " AND ".join(f"t.{c} = s.{c}" for c in pk_columns) + update_set = ", ".join(f"{c} = s.{c}" for c in non_pk) + insert_cols = ", ".join(columns) + insert_vals = ", ".join(f"s.{c}" for c in columns) + + merge_sql = f""" +MERGE INTO {table} AS t +USING (SELECT {select_parts}) AS s +ON {on_clause} +WHEN MATCHED THEN UPDATE SET {update_set} +WHEN NOT MATCHED THEN INSERT ({insert_cols}) VALUES ({insert_vals}) +""".strip() + aws_utils.execute_redshift_statement( + client, + config.offline_store.cluster_id, + config.offline_store.workgroup, + config.offline_store.database, + config.offline_store.user, + merge_sql, + ) + + +def _redshift_sql_literal_for_column(column: str, val: Any) -> str: + if val is None: + return "NULL" + if column == "histogram" and val is not None: + dumped = json.dumps(val).replace("'", "''") + return f"'{dumped}'" + return _redshift_sql_literal(val) + + +def _redshift_mon_query( + config: RepoConfig, + metric_type: str, + columns: List[str], + project: str, + filters: Optional[Dict[str, Any]], + start_date: Optional[date], + end_date: Optional[date], +) -> List[Dict[str, Any]]: + table, _, _ = monitoring_table_meta(metric_type) + conditions: list = [] + if project: + conditions.append(f"project_id = {_redshift_sql_literal(project)}") + if filters: + for key, value in filters.items(): + if value is not None: + conditions.append(f'"{key}" = {_redshift_sql_literal(value)}') + if start_date: + conditions.append(f"metric_date >= DATE '{start_date.isoformat()}'") + if end_date: + conditions.append(f"metric_date <= DATE '{end_date.isoformat()}'") + where_sql = " AND ".join(conditions) if conditions else "TRUE" + col_sql = ", ".join(f'"{c}"' for c in columns) + order_col = "metric_date" if "metric_date" in columns else "job_id" + sql = ( + f'SELECT {col_sql} FROM "{table}" WHERE {where_sql} ORDER BY "{order_col}" ASC' + ) + + client = aws_utils.get_redshift_data_client(config.offline_store.region) + sid = aws_utils.execute_redshift_statement( + client, + config.offline_store.cluster_id, + config.offline_store.workgroup, + config.offline_store.database, + config.offline_store.user, + sql, + ) + meta, rows = _redshift_get_statement_pages(client, sid) + col_names = [c["name"] for c in meta] + out: List[Dict[str, Any]] = [] + for rec in rows: + record = {col_names[i]: _redshift_field_value(rec[i]) for i in range(len(rec))} + out.append(normalize_monitoring_row(record)) + return out + + +def _redshift_sql_numeric_stats( + config: RepoConfig, + from_expression: str, + feature_names: List[str], + ts_clause: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + select_parts = ["COUNT(*)"] + for col in feature_names: + q = f'"{col}"' + c = f"CAST({q} AS DOUBLE PRECISION)" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY {c})", + ] + ) + + query = ( + f"SELECT {', '.join(select_parts)} " + f"FROM {from_expression} AS _src WHERE {ts_clause}" + ) + rows = _redshift_execute_fetch_rows(config, query) + if not rows or not rows[0]: + return [empty_numeric_metric(n) for n in feature_names] + + row = rows[0] + row_count = int(_redshift_field_value(row[0]) or 0) + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = int(_redshift_field_value(row[base]) or 0) + null_count = row_count - non_null + + min_val = opt_float(_redshift_field_value(row[base + 3])) + max_val = opt_float(_redshift_field_value(row[base + 4])) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(_redshift_field_value(row[base + 1])), + "stddev": opt_float(_redshift_field_value(row[base + 2])), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(_redshift_field_value(row[base + 5])), + "p75": opt_float(_redshift_field_value(row[base + 6])), + "p90": opt_float(_redshift_field_value(row[base + 7])), + "p95": opt_float(_redshift_field_value(row[base + 8])), + "p99": opt_float(_redshift_field_value(row[base + 9])), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _redshift_sql_numeric_histogram( + config, + from_expression, + col, + ts_clause, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _redshift_sql_numeric_histogram( + config: RepoConfig, + from_expression: str, + col_name: str, + ts_clause: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + if min_val == max_val: + sql = ( + f"SELECT COUNT(*) FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_clause}" + ) + r = _redshift_execute_fetch_rows(config, sql) + cnt = int(_redshift_field_value(r[0][0]) or 0) if r and r[0] else 0 + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + bin_width = (max_val - min_val) / bins + cast_col = f"CAST({q_col} AS DOUBLE PRECISION)" + + inner = ( + f"CASE WHEN {min_val} = {max_val} THEN 1 " + f"ELSE LEAST(GREATEST(FLOOR(({cast_col} - {min_val}) / {bin_width}) + 1, 1), {bins}) " + f"END AS bucket" + ) + + query = ( + f"SELECT bucket, COUNT(*) AS cnt FROM (" + f" SELECT {inner} " + f" FROM {from_expression} AS _src " + f" WHERE {q_col} IS NOT NULL AND {ts_clause}" + f") AS _b WHERE bucket IS NOT NULL " + f"GROUP BY bucket ORDER BY bucket" + ) + hrows = _redshift_execute_fetch_rows(config, query) + counts = [0] * bins + for hr in hrows: + bucket = int(_redshift_field_value(hr[0]) or 0) + cnt = int(_redshift_field_value(hr[1]) or 0) + if 1 <= bucket <= bins: + counts[bucket - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _redshift_sql_categorical_stats( + config: RepoConfig, + from_expression: str, + col_name: str, + ts_clause: str, + top_n: int, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expression} AS _src WHERE {ts_clause}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" CAST({q_col} AS VARCHAR(65535)) AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} ORDER BY cnt DESC LIMIT {int(top_n)}" + ) + + rows = _redshift_execute_fetch_rows(config, query) + if not rows: + return empty_categorical_metric(col_name) + + row_count = int(_redshift_field_value(rows[0][0]) or 0) + null_count = int(_redshift_field_value(rows[0][1]) or 0) + unique_count = int(_redshift_field_value(rows[0][2]) or 0) + + top_entries = [ + { + "value": _redshift_field_value(r[3]), + "count": int(_redshift_field_value(r[4]) or 0), + } + for r in rows + ] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + class RedshiftRetrievalJob(RetrievalJob): def __init__( diff --git a/sdk/python/feast/infra/offline_stores/remote.py b/sdk/python/feast/infra/offline_stores/remote.py index e0a1df573d4..a32774ad085 100644 --- a/sdk/python/feast/infra/offline_stores/remote.py +++ b/sdk/python/feast/infra/offline_stores/remote.py @@ -12,7 +12,7 @@ import pyarrow.parquet from pyarrow import Schema from pyarrow._flight import FlightCallOptions, FlightDescriptor, Ticket -from pydantic import StrictInt, StrictStr +from pydantic import Field, StrictInt, StrictStr from feast import OnDemandFeatureView from feast.arrow_error_handler import arrow_client_error_handling_decorator @@ -42,6 +42,10 @@ class FeastFlightClient(fl.FlightClient): + def __init__(self, *args, connection_retries: int = 3, **kwargs): + super().__init__(*args, **kwargs) + self._connection_retries = max(0, connection_retries) + @arrow_client_error_handling_decorator def get_flight_info( self, descriptor: FlightDescriptor, options: FlightCallOptions = None @@ -71,7 +75,12 @@ def list_actions(self, options: FlightCallOptions = None): def build_arrow_flight_client( - scheme: str, host: str, port, auth_config: AuthConfig, cert: str = "" + scheme: str, + host: str, + port, + auth_config: AuthConfig, + cert: str = "", + connection_retries: int = 3, ): arrow_scheme = "grpc+tcp" if scheme == "https": @@ -88,10 +97,17 @@ def build_arrow_flight_client( if auth_config.type != AuthType.NONE.value: middlewares = [FlightAuthInterceptorFactory(auth_config)] return FeastFlightClient( - f"{arrow_scheme}://{host}:{port}", middleware=middlewares, **kwargs + f"{arrow_scheme}://{host}:{port}", + middleware=middlewares, + connection_retries=connection_retries, + **kwargs, ) - return FeastFlightClient(f"{arrow_scheme}://{host}:{port}", **kwargs) + return FeastFlightClient( + f"{arrow_scheme}://{host}:{port}", + connection_retries=connection_retries, + **kwargs, + ) class RemoteOfflineStoreConfig(FeastConfigBaseModel): @@ -109,6 +125,9 @@ class RemoteOfflineStoreConfig(FeastConfigBaseModel): """ str: Path to the public certificate when the offline server starts in TLS(SSL) mode. This may be needed if the offline server started with a self-signed certificate, typically this file ends with `*.crt`, `*.cer`, or `*.pem`. If type is 'remote', then this configuration is needed to connect to remote offline server in TLS mode. """ + connection_retries: int = Field(default=3, ge=0) + """ int: Number of retries for transient Arrow Flight errors with exponential backoff (default 3). """ + class RemoteRetrievalJob(RetrievalJob): def __init__( @@ -207,6 +226,7 @@ def get_historical_features( port=config.offline_store.port, auth_config=config.auth_config, cert=config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) feature_view_names = [fv.name for fv in feature_views] @@ -229,6 +249,10 @@ def get_historical_features( if end_date is not None: api_parameters["end_date"] = end_date.isoformat() + if isinstance(entity_df, str): + api_parameters["entity_df_sql"] = entity_df + entity_df = None + return RemoteRetrievalJob( client=client, api=OfflineStore.get_historical_features.__name__, @@ -257,6 +281,7 @@ def pull_all_from_table_or_query( port=config.offline_store.port, auth_config=config.auth_config, cert=config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) api_parameters = { @@ -295,6 +320,7 @@ def pull_latest_from_table_or_query( config.offline_store.port, config.auth_config, cert=config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) api_parameters = { @@ -334,6 +360,7 @@ def write_logged_features( config.offline_store.port, config.auth_config, config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) api_parameters = { @@ -364,6 +391,7 @@ def offline_write_batch( config.offline_store.port, config.auth_config, config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) feature_view_names = [feature_view.name] @@ -396,6 +424,7 @@ def validate_data_source( config.offline_store.port, config.auth_config, config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) api_parameters = { @@ -421,6 +450,7 @@ def get_table_column_names_and_types_from_data_source( config.offline_store.port, config.auth_config, config.offline_store.cert, + connection_retries=config.offline_store.connection_retries, ) api_parameters = { @@ -444,12 +474,12 @@ def get_table_column_names_and_types_from_data_source( def _create_retrieval_metadata( - feature_refs: List[str], entity_df: Optional[pd.DataFrame] = None + feature_refs: List[str], entity_df: Optional[Union[pd.DataFrame, str]] = None ): - if entity_df is None: + if entity_df is None or isinstance(entity_df, str): return RetrievalMetadata( features=feature_refs, - keys=[], # No entity keys when no entity_df provided + keys=[], min_event_timestamp=None, max_event_timestamp=None, ) diff --git a/sdk/python/feast/infra/offline_stores/snowflake.py b/sdk/python/feast/infra/offline_stores/snowflake.py index 7226c908d13..05ed82a1aae 100644 --- a/sdk/python/feast/infra/offline_stores/snowflake.py +++ b/sdk/python/feast/infra/offline_stores/snowflake.py @@ -3,7 +3,8 @@ import os import uuid import warnings -from datetime import datetime, timezone +from datetime import date, datetime, timezone +from decimal import Decimal from functools import reduce from pathlib import Path from typing import ( @@ -50,6 +51,17 @@ write_pandas, write_parquet, ) +from feast.monitoring.monitoring_utils import ( + MON_TABLE_FEATURE, + MON_TABLE_FEATURE_SERVICE, + MON_TABLE_FEATURE_VIEW, + MON_TABLE_JOB, + empty_categorical_metric, + empty_numeric_metric, + monitoring_table_meta, + normalize_monitoring_row, + opt_float, +) from feast.repo_config import FeastConfigBaseModel, RepoConfig from feast.saved_dataset import SavedDatasetStorage from feast.types import ( @@ -421,6 +433,252 @@ def offline_write_batch( auto_create_table=True, ) + @staticmethod + def compute_monitoring_metrics( + config: RepoConfig, + data_source: DataSource, + feature_columns: List[Tuple[str, str]], + timestamp_field: str, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + histogram_bins: int = 20, + top_n: int = 10, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + assert isinstance(data_source, SnowflakeSource) + + from_expression = data_source.get_table_query_string() + from_expression = _qualify_snowflake_from_expression( + config, data_source, from_expression + ) + ts_filter = ( + get_timestamp_filter_sql( + start_date, end_date, timestamp_field, tz=timezone.utc + ) + or "1=1" + ) + + numeric_features = [n for n, t in feature_columns if t == "numeric"] + categorical_features = [n for n, t in feature_columns if t == "categorical"] + results: List[Dict[str, Any]] = [] + + with GetSnowflakeConnection(config.offline_store) as conn: + if numeric_features: + results.extend( + _snowflake_sql_numeric_stats( + conn, + from_expression, + numeric_features, + ts_filter, + histogram_bins, + ) + ) + + for col_name in categorical_features: + results.append( + _snowflake_sql_categorical_stats( + conn, from_expression, col_name, ts_filter, top_n + ) + ) + + return results + + @staticmethod + def get_monitoring_max_timestamp( + config: RepoConfig, + data_source: DataSource, + timestamp_field: str, + ) -> Optional[datetime]: + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + assert isinstance(data_source, SnowflakeSource) + + from_expression = data_source.get_table_query_string() + from_expression = _qualify_snowflake_from_expression( + config, data_source, from_expression + ) + + with GetSnowflakeConnection(config.offline_store) as conn: + cursor = execute_snowflake_statement( + conn, + f'SELECT MAX("{timestamp_field}") FROM {from_expression} AS _src', + ) + row = cursor.fetchone() + + if row is None or row[0] is None: + return None + val = row[0] + if isinstance(val, pd.Timestamp): + val = val.to_pydatetime() + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + return datetime.combine(val, datetime.min.time(), tzinfo=timezone.utc) + + @staticmethod + def ensure_monitoring_tables(config: RepoConfig) -> None: + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + + fq_feature = _snowflake_monitoring_table_fqn(config, MON_TABLE_FEATURE) + fq_view = _snowflake_monitoring_table_fqn(config, MON_TABLE_FEATURE_VIEW) + fq_service = _snowflake_monitoring_table_fqn(config, MON_TABLE_FEATURE_SERVICE) + + ddl_feature = f""" + CREATE TABLE IF NOT EXISTS {fq_feature} ( + "project_id" VARCHAR(255) NOT NULL, + "feature_view_name" VARCHAR(255) NOT NULL, + "feature_name" VARCHAR(255) NOT NULL, + "metric_date" DATE NOT NULL, + "granularity" VARCHAR(20) NOT NULL DEFAULT 'daily', + "data_source_type" VARCHAR(50) NOT NULL DEFAULT 'batch', + "computed_at" TIMESTAMP_TZ NOT NULL DEFAULT CURRENT_TIMESTAMP(), + "is_baseline" BOOLEAN NOT NULL DEFAULT FALSE, + "feature_type" VARCHAR(50) NOT NULL, + "row_count" BIGINT, + "null_count" BIGINT, + "null_rate" DOUBLE, + "mean" DOUBLE, + "stddev" DOUBLE, + "min_val" DOUBLE, + "max_val" DOUBLE, + "p50" DOUBLE, + "p75" DOUBLE, + "p90" DOUBLE, + "p95" DOUBLE, + "p99" DOUBLE, + "histogram" VARIANT, + PRIMARY KEY ("project_id", "feature_view_name", "feature_name", + "metric_date", "granularity", "data_source_type") + ) + """ + ddl_view = f""" + CREATE TABLE IF NOT EXISTS {fq_view} ( + "project_id" VARCHAR(255) NOT NULL, + "feature_view_name" VARCHAR(255) NOT NULL, + "metric_date" DATE NOT NULL, + "granularity" VARCHAR(20) NOT NULL DEFAULT 'daily', + "data_source_type" VARCHAR(50) NOT NULL DEFAULT 'batch', + "computed_at" TIMESTAMP_TZ NOT NULL DEFAULT CURRENT_TIMESTAMP(), + "is_baseline" BOOLEAN NOT NULL DEFAULT FALSE, + "total_row_count" BIGINT, + "total_features" INTEGER, + "features_with_nulls" INTEGER, + "avg_null_rate" DOUBLE, + "max_null_rate" DOUBLE, + PRIMARY KEY ("project_id", "feature_view_name", "metric_date", + "granularity", "data_source_type") + ) + """ + ddl_service = f""" + CREATE TABLE IF NOT EXISTS {fq_service} ( + "project_id" VARCHAR(255) NOT NULL, + "feature_service_name" VARCHAR(255) NOT NULL, + "metric_date" DATE NOT NULL, + "granularity" VARCHAR(20) NOT NULL DEFAULT 'daily', + "data_source_type" VARCHAR(50) NOT NULL DEFAULT 'batch', + "computed_at" TIMESTAMP_TZ NOT NULL DEFAULT CURRENT_TIMESTAMP(), + "is_baseline" BOOLEAN NOT NULL DEFAULT FALSE, + "total_feature_views" INTEGER, + "total_features" INTEGER, + "avg_null_rate" DOUBLE, + "max_null_rate" DOUBLE, + PRIMARY KEY ("project_id", "feature_service_name", "metric_date", + "granularity", "data_source_type") + ) + """ + + fq_job = _snowflake_monitoring_table_fqn(config, MON_TABLE_JOB) + ddl_job = f""" + CREATE TABLE IF NOT EXISTS {fq_job} ( + "job_id" VARCHAR(36) NOT NULL, + "project_id" VARCHAR(255) NOT NULL, + "feature_view_name" VARCHAR(255), + "job_type" VARCHAR(50) NOT NULL, + "status" VARCHAR(20) NOT NULL DEFAULT 'pending', + "parameters" VARCHAR, + "metric_date" DATE NOT NULL, + "started_at" TIMESTAMP_TZ, + "completed_at" TIMESTAMP_TZ, + "error_message" VARCHAR, + "result_summary" VARCHAR, + PRIMARY KEY ("job_id") + ) + """ + + with GetSnowflakeConnection(config.offline_store) as conn: + execute_snowflake_statement(conn, ddl_feature) + execute_snowflake_statement(conn, ddl_view) + execute_snowflake_statement(conn, ddl_service) + execute_snowflake_statement(conn, ddl_job) + + @staticmethod + def save_monitoring_metrics( + config: RepoConfig, + metric_type: str, + metrics: List[Dict[str, Any]], + ) -> None: + if not metrics: + return + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + + table, columns, pk_columns = monitoring_table_meta(metric_type) + _snowflake_mon_merge_upsert( + config.offline_store, table, columns, pk_columns, metrics + ) + + @staticmethod + def query_monitoring_metrics( + config: RepoConfig, + project: str, + metric_type: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + + _, columns, _ = monitoring_table_meta(metric_type) + return _snowflake_mon_query( + config.offline_store, + metric_type, + columns, + project, + filters, + start_date, + end_date, + ) + + @staticmethod + def clear_monitoring_baseline( + config: RepoConfig, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> None: + assert isinstance(config.offline_store, SnowflakeOfflineStoreConfig) + + fq_table = _snowflake_monitoring_table_fqn(config, MON_TABLE_FEATURE) + conditions = [f'"project_id" = {_snowflake_sql_literal(project)}'] + if feature_view_name: + conditions.append( + f'"feature_view_name" = {_snowflake_sql_literal(feature_view_name)}' + ) + if feature_name: + conditions.append( + f'"feature_name" = {_snowflake_sql_literal(feature_name)}' + ) + if data_source_type: + conditions.append( + f'"data_source_type" = {_snowflake_sql_literal(data_source_type)}' + ) + conditions.append('"is_baseline" = TRUE') + + sql = f'UPDATE {fq_table} SET "is_baseline" = FALSE WHERE ' + " AND ".join( + conditions + ) + + with GetSnowflakeConnection(config.offline_store) as conn: + execute_snowflake_statement(conn, sql) + class SnowflakeRetrievalJob(RetrievalJob): def __init__( @@ -640,6 +898,335 @@ def _get_file_names_from_copy_into(self, cursor, native_export_path) -> List[str ] +# ------------------------------------------------------------------ # +# Snowflake monitoring SQL push-down & storage helpers +# ------------------------------------------------------------------ # + + +def _escape_snowflake_sql_string(value: str) -> str: + return value.replace("'", "''") + + +def _snowflake_sql_literal(val: Any) -> str: + if val is None: + return "NULL" + if isinstance(val, bool): + return "TRUE" if val else "FALSE" + if isinstance(val, (int, float)) and not isinstance(val, bool): + if isinstance(val, float) and (np.isnan(val) or np.isinf(val)): + return "NULL" + return str(val) + if isinstance(val, Decimal): + return str(val) + if isinstance(val, date) and not isinstance(val, datetime): + return f"DATE '{val.isoformat()}'" + if isinstance(val, datetime): + dt = val if val.tzinfo else val.replace(tzinfo=timezone.utc) + return f"TIMESTAMP_TZ '{dt.isoformat()}'" + if isinstance(val, str): + return f"'{_escape_snowflake_sql_string(val)}'" + return f"'{_escape_snowflake_sql_string(str(val))}'" + + +def _qualify_snowflake_from_expression( + config: RepoConfig, + data_source: SnowflakeSource, + from_expression: str, +) -> str: + if not data_source.database and not data_source.schema and data_source.table: + return ( + f'"{config.offline_store.database}"."{config.offline_store.schema_}".' + f"{from_expression}" + ) + if not data_source.database and data_source.schema and data_source.table: + return f'"{config.offline_store.database}".{from_expression}' + return from_expression + + +def _snowflake_monitoring_table_fqn( + config: RepoConfig, + table_name: str, +) -> str: + os = config.offline_store + assert isinstance(os, SnowflakeOfflineStoreConfig) + return f'"{os.database}"."{os.schema_}"."{table_name}"' + + +def _snowflake_sql_numeric_histogram( + conn: SnowflakeConnection, + from_expression: str, + col_name: str, + ts_filter: str, + bins: int, + min_val: float, + max_val: float, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + if min_val == max_val: + cursor = execute_snowflake_statement( + conn, + f"SELECT COUNT(*) FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_filter}", + ) + row = cursor.fetchone() + cnt = (row or (0,))[0] + return {"bins": [min_val, max_val], "counts": [cnt], "bin_width": 0.0} + + upper = max_val + (max_val - min_val) * 1e-10 + bin_width = (max_val - min_val) / bins + + query = ( + f"SELECT WIDTH_BUCKET(CAST({q_col} AS DOUBLE), {min_val}, {upper}, {bins}) " + f"AS bucket, COUNT(*) AS cnt " + f"FROM {from_expression} AS _src " + f"WHERE {q_col} IS NOT NULL AND {ts_filter} " + f"GROUP BY bucket ORDER BY bucket" + ) + + cursor = execute_snowflake_statement(conn, query) + rows = cursor.fetchall() + + counts = [0] * bins + for bucket, cnt in rows: + if bucket is not None and 1 <= int(bucket) <= bins: + counts[int(bucket) - 1] = cnt + + bin_edges = [min_val + i * bin_width for i in range(bins + 1)] + return { + "bins": [float(b) for b in bin_edges], + "counts": counts, + "bin_width": float(bin_width), + } + + +def _snowflake_sql_numeric_stats( + conn: SnowflakeConnection, + from_expression: str, + feature_names: List[str], + ts_filter: str, + histogram_bins: int, +) -> List[Dict[str, Any]]: + select_parts = ["COUNT(*)"] + for col in feature_names: + q = f'"{col}"' + c = f"CAST({q} AS DOUBLE)" + select_parts.extend( + [ + f"COUNT({q})", + f"AVG({c})", + f"STDDEV_SAMP({c})", + f"MIN({c})", + f"MAX({c})", + f"PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.90) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY {c})", + f"PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY {c})", + ] + ) + + query = ( + f"SELECT {', '.join(select_parts)} " + f"FROM {from_expression} AS _src WHERE {ts_filter}" + ) + + cursor = execute_snowflake_statement(conn, query) + row = cursor.fetchone() + + if row is None: + return [empty_numeric_metric(n) for n in feature_names] + + row_count = row[0] + results: List[Dict[str, Any]] = [] + + for i, col in enumerate(feature_names): + base = 1 + i * 10 + non_null = row[base] or 0 + null_count = row_count - non_null + + min_val = opt_float(row[base + 3]) + max_val = opt_float(row[base + 4]) + + result: Dict[str, Any] = { + "feature_name": col, + "feature_type": "numeric", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": opt_float(row[base + 1]), + "stddev": opt_float(row[base + 2]), + "min_val": min_val, + "max_val": max_val, + "p50": opt_float(row[base + 5]), + "p75": opt_float(row[base + 6]), + "p90": opt_float(row[base + 7]), + "p95": opt_float(row[base + 8]), + "p99": opt_float(row[base + 9]), + "histogram": None, + } + + if min_val is not None and max_val is not None and non_null > 0: + result["histogram"] = _snowflake_sql_numeric_histogram( + conn, + from_expression, + col, + ts_filter, + histogram_bins, + min_val, + max_val, + ) + + results.append(result) + + return results + + +def _snowflake_sql_categorical_stats( + conn: SnowflakeConnection, + from_expression: str, + col_name: str, + ts_filter: str, + top_n: int, +) -> Dict[str, Any]: + q_col = f'"{col_name}"' + + query = ( + f"WITH filtered AS (" + f" SELECT * FROM {from_expression} AS _src WHERE {ts_filter}" + f") " + f"SELECT " + f" (SELECT COUNT(*) FROM filtered) AS row_count, " + f" (SELECT COUNT(*) - COUNT({q_col}) FROM filtered) AS null_count, " + f" (SELECT COUNT(DISTINCT {q_col}) FROM filtered " + f" WHERE {q_col} IS NOT NULL) AS unique_count, " + f" TO_VARCHAR({q_col}) AS value, COUNT(*) AS cnt " + f"FROM filtered WHERE {q_col} IS NOT NULL " + f"GROUP BY {q_col} ORDER BY cnt DESC LIMIT {int(top_n)}" + ) + + cursor = execute_snowflake_statement(conn, query) + rows = cursor.fetchall() + + if not rows: + return empty_categorical_metric(col_name) + + row_count = rows[0][0] + null_count = rows[0][1] + unique_count = rows[0][2] + + top_entries = [{"value": r[3], "count": r[4]} for r in rows] + top_total = sum(e["count"] for e in top_entries) + other_count = (row_count - null_count) - top_total + + return { + "feature_name": col_name, + "feature_type": "categorical", + "row_count": row_count, + "null_count": null_count, + "null_rate": null_count / row_count if row_count > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": { + "values": top_entries, + "other_count": max(other_count, 0), + "unique_count": unique_count, + }, + } + + +def _snowflake_mon_merge_upsert( + offline_store: SnowflakeOfflineStoreConfig, + table: str, + columns: List[str], + pk_columns: List[str], + rows: List[Dict[str, Any]], +) -> None: + fq = f'"{offline_store.database}"."{offline_store.schema_}"."{table}"' + non_pk = [c for c in columns if c not in pk_columns] + + with GetSnowflakeConnection(offline_store) as conn: + for row in rows: + select_parts: List[str] = [] + for col in columns: + val = row.get(col) + if col == "histogram": + if val is not None: + json_str = json.dumps(val) + select_parts.append( + f'PARSE_JSON({_snowflake_sql_literal(json_str)}) AS "{col}"' + ) + else: + select_parts.append(f'NULL AS "{col}"') + else: + select_parts.append(f'{_snowflake_sql_literal(val)} AS "{col}"') + + using = ", ".join(select_parts) + on_parts = [f't."{pk}" = s."{pk}"' for pk in pk_columns] + update_parts = [f't."{c}" = s."{c}"' for c in non_pk] + insert_cols = ", ".join(f'"{c}"' for c in columns) + insert_vals = ", ".join(f's."{c}"' for c in columns) + + sql = ( + f"MERGE INTO {fq} AS t " + f"USING (SELECT {using}) AS s " + f"ON {' AND '.join(on_parts)} " + f"WHEN MATCHED THEN UPDATE SET {', '.join(update_parts)} " + f"WHEN NOT MATCHED THEN INSERT ({insert_cols}) VALUES ({insert_vals})" + ) + + execute_snowflake_statement(conn, sql) + + +def _snowflake_mon_query( + offline_store: SnowflakeOfflineStoreConfig, + metric_type: str, + columns: List[str], + project: str, + filters: Optional[Dict[str, Any]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, +) -> List[Dict[str, Any]]: + table, _, _ = monitoring_table_meta(metric_type) + fq = f'"{offline_store.database}"."{offline_store.schema_}"."{table}"' + + conditions: List[str] = [] + if project: + conditions.append(f'"project_id" = {_snowflake_sql_literal(project)}') + if filters: + for key, value in filters.items(): + if value is not None: + conditions.append(f'"{key}" = {_snowflake_sql_literal(value)}') + + if start_date: + conditions.append(f'"metric_date" >= {_snowflake_sql_literal(start_date)}') + if end_date: + conditions.append(f'"metric_date" <= {_snowflake_sql_literal(end_date)}') + + col_list = ", ".join(f'"{c}"' for c in columns) + where_clause = " AND ".join(conditions) if conditions else "TRUE" + order_col = "metric_date" if "metric_date" in columns else "job_id" + sql = f'SELECT {col_list} FROM {fq} WHERE {where_clause} ORDER BY "{order_col}" ASC' + + with GetSnowflakeConnection(offline_store) as conn: + cursor = execute_snowflake_statement(conn, sql) + rows = cursor.fetchall() + + results: List[Dict[str, Any]] = [] + for row in rows: + record = dict(zip(columns, row)) + results.append(normalize_monitoring_row(record)) + + return results + + def _get_entity_schema( entity_df: Union[pd.DataFrame, str], snowflake_conn: SnowflakeConnection, diff --git a/sdk/python/feast/infra/online_stores/dynamodb.py b/sdk/python/feast/infra/online_stores/dynamodb.py index 814058c77e5..8c940fdc41b 100644 --- a/sdk/python/feast/infra/online_stores/dynamodb.py +++ b/sdk/python/feast/infra/online_stores/dynamodb.py @@ -24,7 +24,7 @@ from pydantic import StrictBool, StrictStr from feast import Entity, FeatureView, utils -from feast.infra.online_stores.helpers import compute_entity_id +from feast.infra.online_stores.helpers import compute_entity_id, compute_versioned_name from feast.infra.online_stores.online_store import OnlineStore from feast.infra.supported_async_methods import SupportedAsyncMethods from feast.infra.utils.aws_utils import dynamo_write_items_async @@ -206,12 +206,10 @@ async def _get_aiodynamodb_client( return self._aioboto_client async def _aiodynamodb_close(self): - if self._aioboto_client: - await self._aioboto_client.close() - self._aioboto_client = None if self._aioboto_context_stack: await self._aioboto_context_stack.aclose() self._aioboto_context_stack = None + self._aioboto_client = None if self._aioboto_session: self._aioboto_session = None @@ -238,18 +236,45 @@ def _table_tags(online_config, table_instance) -> list[dict[str, str]]: @staticmethod def _update_tags(dynamodb_client, table_name: str, new_tags: list[dict[str, str]]): + """Update DynamoDB table tags using a diff-based approach. + + Instead of removing all tags and re-adding them (which is vulnerable to + the eventual-consistency window between UntagResource and TagResource), + this method computes the minimal set of changes needed: + + - Only removes tags that are no longer present in new_tags. + - Only adds/updates tags whose value has changed or that are new. + + This avoids the race condition described in + https://github.com/feast-dev/feast/issues/6418 where calling + TagResource immediately after UntagResource can leave a table with no + tags due to DynamoDB's asynchronous tag operations. + """ table_arn = dynamodb_client.describe_table(TableName=table_name)["Table"][ "TableArn" ] current_tags = dynamodb_client.list_tags_of_resource(ResourceArn=table_arn)[ "Tags" ] - if current_tags: - remove_keys = [tag["Key"] for tag in current_tags] - dynamodb_client.untag_resource(ResourceArn=table_arn, TagKeys=remove_keys) - if new_tags: - dynamodb_client.tag_resource(ResourceArn=table_arn, Tags=new_tags) + current_tag_map = {tag["Key"]: tag["Value"] for tag in current_tags} + new_tag_map = {tag["Key"]: tag["Value"] for tag in new_tags} + + # Remove only tags that are no longer in new_tags + keys_to_remove = [k for k in current_tag_map if k not in new_tag_map] + # Add / update only tags whose value is new or has changed + tags_to_add = [ + {"Key": k, "Value": v} + for k, v in new_tag_map.items() + if current_tag_map.get(k) != v + ] + + if keys_to_remove: + dynamodb_client.untag_resource( + ResourceArn=table_arn, TagKeys=keys_to_remove + ) + if tags_to_add: + dynamodb_client.tag_resource(ResourceArn=table_arn, Tags=tags_to_add) def update( self, @@ -504,7 +529,7 @@ def online_read( # For single batch, no parallelization overhead needed if len(batches) == 1: batch_entity_ids = self._to_resource_batch_get_payload( - online_config, table_name, batches[0] + online_config, table_name, batches[0], requested_features ) response = dynamodb_resource.batch_get_item(RequestItems=batch_entity_ids) return self._process_batch_get_response(table_name, response, batches[0]) @@ -520,7 +545,7 @@ def online_read( def fetch_batch(batch: List[str]) -> Dict[str, Any]: batch_entity_ids = self._to_client_batch_get_payload( - online_config, table_name, batch + online_config, table_name, batch, requested_features ) return dynamodb_client.batch_get_item(RequestItems=batch_entity_ids) @@ -599,7 +624,7 @@ def to_tbl_resp(raw_client_response): if not batch: break entity_id_batch = self._to_client_batch_get_payload( - online_config, table_name, batch + online_config, table_name, batch, requested_features ) batches.append(batch) entity_id_batches.append(entity_id_batch) @@ -760,21 +785,56 @@ def _to_entity_ids(config: RepoConfig, entity_keys: List[EntityKeyProto]): ] @staticmethod - def _to_resource_batch_get_payload(online_config, table_name, batch): - return { - table_name: { - "Keys": [{"entity_id": entity_id} for entity_id in batch], - "ConsistentRead": online_config.consistent_reads, - } + def _to_resource_batch_get_payload( + online_config, table_name, batch, requested_features=None + ): + payload: Dict[str, Any] = { + "Keys": [{"entity_id": entity_id} for entity_id in batch], + "ConsistentRead": online_config.consistent_reads, } + projection = DynamoDBOnlineStore._build_projection_expression( + requested_features + ) + if projection: + payload["ProjectionExpression"] = projection["ProjectionExpression"] + payload["ExpressionAttributeNames"] = projection["ExpressionAttributeNames"] + return {table_name: payload} @staticmethod - def _to_client_batch_get_payload(online_config, table_name, batch): + def _to_client_batch_get_payload( + online_config, table_name, batch, requested_features=None + ): + payload: Dict[str, Any] = { + "Keys": [{"entity_id": {"S": entity_id}} for entity_id in batch], + "ConsistentRead": online_config.consistent_reads, + } + projection = DynamoDBOnlineStore._build_projection_expression( + requested_features + ) + if projection: + payload["ProjectionExpression"] = projection["ProjectionExpression"] + payload["ExpressionAttributeNames"] = projection["ExpressionAttributeNames"] + return {table_name: payload} + + @staticmethod + def _build_projection_expression( + requested_features: Optional[List[str]], + ) -> Optional[Dict[str, Any]]: + if not requested_features: + return None + attr_names: Dict[str, str] = { + "#entity_id": "entity_id", + "#event_ts": "event_ts", + "#vals": "values", + } + projections = ["#entity_id", "#event_ts"] + for i, feat in enumerate(requested_features): + alias = f"#feat{i}" + attr_names[alias] = feat + projections.append(f"#vals.{alias}") return { - table_name: { - "Keys": [{"entity_id": {"S": entity_id}} for entity_id in batch], - "ConsistentRead": online_config.consistent_reads, - } + "ProjectionExpression": ", ".join(projections), + "ExpressionAttributeNames": attr_names, } def update_online_store( @@ -1154,8 +1214,11 @@ def _initialize_dynamodb_resource( def _get_table_name( online_config: DynamoDBOnlineStoreConfig, config: RepoConfig, table: FeatureView ) -> str: + table_name = compute_versioned_name( + table, config.registry.enable_online_feature_view_versioning + ) return online_config.table_name_template.format( - project=config.project, table_name=table.name + project=config.project, table_name=table_name ) diff --git a/sdk/python/feast/infra/online_stores/elasticsearch_online_store/elasticsearch.py b/sdk/python/feast/infra/online_stores/elasticsearch_online_store/elasticsearch.py index 7e8e533281d..b78d003ac25 100644 --- a/sdk/python/feast/infra/online_stores/elasticsearch_online_store/elasticsearch.py +++ b/sdk/python/feast/infra/online_stores/elasticsearch_online_store/elasticsearch.py @@ -279,8 +279,7 @@ def retrieve_online_documents( requested_features: List[str], embedding: List[float], top_k: int, - *args, - **kwargs, + distance_metric: Optional[str] = None, ) -> List[ Tuple[ Optional[datetime], @@ -349,6 +348,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], diff --git a/sdk/python/feast/infra/online_stores/faiss_online_store.py b/sdk/python/feast/infra/online_stores/faiss_online_store.py index 4b666f60f40..dfa7d6c376b 100644 --- a/sdk/python/feast/infra/online_stores/faiss_online_store.py +++ b/sdk/python/feast/infra/online_stores/faiss_online_store.py @@ -8,6 +8,7 @@ from feast import Entity, FeatureView, RepoConfig from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.online_stores.helpers import compute_table_id from feast.infra.online_stores.online_store import OnlineStore from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto @@ -43,16 +44,21 @@ def teardown(self): self.entity_keys = {} +def _table_id(project: str, table: FeatureView, enable_versioning: bool = False) -> str: + return compute_table_id(project, table, enable_versioning) + + class FaissOnlineStore(OnlineStore): - _index: Optional[faiss.IndexIVFFlat] = None - _in_memory_store: InMemoryStore = InMemoryStore() - _config: Optional[FaissOnlineStoreConfig] = None _logger: logging.Logger = logging.getLogger(__name__) - def _get_index(self, config: RepoConfig) -> faiss.IndexIVFFlat: - if self._index is None or self._config is None: - raise ValueError("Index is not initialized") - return self._index + def __init__(self): + super().__init__() + self._indices: Dict[str, faiss.IndexIVFFlat] = {} + self._in_memory_stores: Dict[str, InMemoryStore] = {} + self._config: Optional[FaissOnlineStoreConfig] = None + + def _get_index(self, table_key: str) -> Optional[faiss.IndexIVFFlat]: + return self._indices.get(table_key) def update( self, @@ -63,23 +69,31 @@ def update( entities_to_keep: Sequence[Entity], partial: bool, ): - feature_views = tables_to_keep - if not feature_views: - return - - feature_names = [f.name for f in feature_views[0].features] - dimension = len(feature_names) - self._config = FaissOnlineStoreConfig(**config.online_store.dict()) - if self._index is None or not partial: - quantizer = faiss.IndexFlatL2(dimension) - self._index = faiss.IndexIVFFlat(quantizer, dimension, self._config.nlist) - self._index.train( - np.random.rand(self._config.nlist * 100, dimension).astype(np.float32) - ) - self._in_memory_store = InMemoryStore() + versioning = config.registry.enable_online_feature_view_versioning + + for table in tables_to_delete: + table_key = _table_id(config.project, table, versioning) + self._indices.pop(table_key, None) + self._in_memory_stores.pop(table_key, None) + + for table in tables_to_keep: + table_key = _table_id(config.project, table, versioning) + feature_names = [f.name for f in table.features] + dimension = len(feature_names) + + if table_key not in self._indices or not partial: + quantizer = faiss.IndexFlatL2(dimension) + index = faiss.IndexIVFFlat(quantizer, dimension, self._config.nlist) + index.train( + np.random.rand(self._config.nlist * 100, dimension).astype( + np.float32 + ) + ) + self._indices[table_key] = index + self._in_memory_stores[table_key] = InMemoryStore() - self._in_memory_store.update(feature_names, {}) + self._in_memory_stores[table_key].update(feature_names, {}) def teardown( self, @@ -87,8 +101,13 @@ def teardown( tables: Sequence[FeatureView], entities: Sequence[Entity], ): - self._index = None - self._in_memory_store.teardown() + versioning = config.registry.enable_online_feature_view_versioning + for table in tables: + table_key = _table_id(config.project, table, versioning) + self._indices.pop(table_key, None) + store = self._in_memory_stores.pop(table_key, None) + if store is not None: + store.teardown() def online_read( self, @@ -97,7 +116,12 @@ def online_read( entity_keys: List[EntityKeyProto], requested_features: Optional[List[str]] = None, ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: - if self._index is None: + versioning = config.registry.enable_online_feature_view_versioning + table_key = _table_id(config.project, table, versioning) + index = self._get_index(table_key) + in_memory_store = self._in_memory_stores.get(table_key) + + if index is None or in_memory_store is None: return [(None, None)] * len(entity_keys) results: List[Tuple[Optional[datetime], Optional[Dict[str, Any]]]] = [] @@ -105,15 +129,15 @@ def online_read( serialized_key = serialize_entity_key( entity_key, config.entity_key_serialization_version ).hex() - idx = self._in_memory_store.entity_keys.get(serialized_key, -1) + idx = in_memory_store.entity_keys.get(serialized_key, -1) if idx == -1: results.append((None, None)) else: - feature_vector = self._index.reconstruct(int(idx)) + feature_vector = index.reconstruct(int(idx)) feature_dict = { name: ValueProto(double_val=value) for name, value in zip( - self._in_memory_store.feature_names, feature_vector + in_memory_store.feature_names, feature_vector ) } results.append((None, feature_dict)) @@ -128,8 +152,16 @@ def online_write_batch( ], progress: Optional[Callable[[int], Any]], ) -> None: - if self._index is None: - self._logger.warning("Index is not initialized. Skipping write operation.") + versioning = config.registry.enable_online_feature_view_versioning + table_key = _table_id(config.project, table, versioning) + index = self._get_index(table_key) + in_memory_store = self._in_memory_stores.get(table_key) + + if index is None or in_memory_store is None: + self._logger.warning( + "Index for table '%s' is not initialized. Skipping write operation.", + table_key, + ) return feature_vectors = [] @@ -142,7 +174,7 @@ def online_write_batch( feature_vector = np.array( [ feature_dict[name].double_val - for name in self._in_memory_store.feature_names + for name in in_memory_store.feature_names ], dtype=np.float32, ) @@ -153,21 +185,17 @@ def online_write_batch( feature_vectors_array = np.array(feature_vectors) existing_indices = [ - self._in_memory_store.entity_keys.get(sk, -1) for sk in serialized_keys + in_memory_store.entity_keys.get(sk, -1) for sk in serialized_keys ] mask = np.array(existing_indices) != -1 if np.any(mask): - self._index.remove_ids( - np.array([idx for idx in existing_indices if idx != -1]) - ) + index.remove_ids(np.array([idx for idx in existing_indices if idx != -1])) - new_indices = np.arange( - self._index.ntotal, self._index.ntotal + len(feature_vectors_array) - ) - self._index.add(feature_vectors_array) + new_indices = np.arange(index.ntotal, index.ntotal + len(feature_vectors_array)) + index.add(feature_vectors_array) for sk, idx in zip(serialized_keys, new_indices): - self._in_memory_store.entity_keys[sk] = idx + in_memory_store.entity_keys[sk] = idx if progress: progress(len(data)) @@ -176,7 +204,7 @@ def retrieve_online_documents( self, config: RepoConfig, table: FeatureView, - requested_featres: List[str], + requested_features: List[str], embedding: List[float], top_k: int, distance_metric: Optional[str] = None, @@ -189,12 +217,16 @@ def retrieve_online_documents( Optional[ValueProto], ] ]: - if self._index is None: + versioning = config.registry.enable_online_feature_view_versioning + table_key = _table_id(config.project, table, versioning) + index = self._get_index(table_key) + + if index is None: self._logger.warning("Index is not initialized. Returning empty result.") return [] query_vector = np.array(embedding, dtype=np.float32).reshape(1, -1) - distances, indices = self._index.search(query_vector, top_k) + distances, indices = index.search(query_vector, top_k) results: List[ Tuple[ @@ -209,7 +241,7 @@ def retrieve_online_documents( if idx == -1: continue - feature_vector = self._index.reconstruct(int(idx)) + feature_vector = index.reconstruct(int(idx)) timestamp = Timestamp() timestamp.GetCurrentTime() @@ -237,5 +269,4 @@ async def online_read_async( entity_keys: List[EntityKeyProto], requested_features: Optional[List[str]] = None, ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: - # Implement async read if needed raise NotImplementedError("Async read is not implemented for FaissOnlineStore") diff --git a/sdk/python/feast/infra/online_stores/helpers.py b/sdk/python/feast/infra/online_stores/helpers.py index b657bd44d00..59ef9185c1f 100644 --- a/sdk/python/feast/infra/online_stores/helpers.py +++ b/sdk/python/feast/infra/online_stores/helpers.py @@ -70,3 +70,20 @@ def _to_naive_utc(ts: datetime) -> datetime: return ts else: return ts.astimezone(tz=timezone.utc).replace(tzinfo=None) + + +def compute_versioned_name(table: Any, enable_versioning: bool = False) -> str: + """Return the table name with a ``_v{N}`` suffix when versioning is enabled.""" + name = table.name + if enable_versioning: + version = getattr(table.projection, "version_tag", None) + if version is None: + version = getattr(table, "current_version_number", None) + if version is not None and version > 0: + name = f"{table.name}_v{version}" + return name + + +def compute_table_id(project: str, table: Any, enable_versioning: bool = False) -> str: + """Build the online-store table name, appending a version suffix when versioning is enabled.""" + return f"{project}_{compute_versioned_name(table, enable_versioning)}" diff --git a/sdk/python/feast/infra/online_stores/milvus_online_store/milvus.py b/sdk/python/feast/infra/online_stores/milvus_online_store/milvus.py index fb812f82b7b..94edfd8e376 100644 --- a/sdk/python/feast/infra/online_stores/milvus_online_store/milvus.py +++ b/sdk/python/feast/infra/online_stores/milvus_online_store/milvus.py @@ -1,9 +1,10 @@ import base64 +import logging from datetime import datetime from pathlib import Path from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union -from pydantic import StrictStr +from pydantic import StrictStr, field_validator from pymilvus import ( CollectionSchema, DataType, @@ -18,6 +19,7 @@ deserialize_entity_key, serialize_entity_key, ) +from feast.infra.online_stores.helpers import compute_table_id from feast.infra.online_stores.online_store import OnlineStore from feast.infra.online_stores.vector_store import VectorStoreConfig from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto @@ -42,6 +44,8 @@ to_naive_utc, ) +logger = logging.getLogger(__name__) + PROTO_TO_MILVUS_TYPE_MAPPING: Dict[ValueType, DataType] = { PROTO_VALUE_TO_VALUE_TYPE_MAP["bytes_val"]: DataType.VARCHAR, ValueType.IMAGE_BYTES: DataType.VARCHAR, @@ -111,6 +115,14 @@ class MilvusOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig): nlist: Optional[int] = 128 username: Optional[StrictStr] = "" password: Optional[StrictStr] = "" + varchar_max_length: Optional[int] = 65535 + + @field_validator("varchar_max_length") + @classmethod + def validate_varchar_max_length(cls, v): + if v is not None and not (1 <= v <= 65535): + raise ValueError(f"varchar_max_length must be between 1 and 65535, got {v}") + return v class MilvusOnlineStore(OnlineStore): @@ -121,8 +133,10 @@ class MilvusOnlineStore(OnlineStore): _collections: Dictionary to cache Milvus collections. """ - client: Optional[MilvusClient] = None - _collections: Dict[str, Any] = {} + def __init__(self): + super().__init__() + self.client: Optional[MilvusClient] = None + self._collections: Dict[str, Any] = {} def _get_db_path(self, config: RepoConfig) -> str: assert ( @@ -140,11 +154,13 @@ def _connect(self, config: RepoConfig) -> MilvusClient: if not self.client: if config.provider == "local" and config.online_store.path: db_path = self._get_db_path(config) - print(f"Connecting to Milvus in local mode using {db_path}") + logger.info("Connecting to Milvus in local mode using %s", db_path) self.client = MilvusClient(db_path) else: - print( - f"Connecting to Milvus remotely at {config.online_store.host}:{config.online_store.port}" + logger.info( + "Connecting to Milvus remotely at %s:%s", + config.online_store.host, + config.online_store.port, ) self.client = MilvusClient( uri=f"{config.online_store.host}:{config.online_store.port}", @@ -159,16 +175,18 @@ def _get_or_create_collection( ) -> Dict[str, Any]: self.client = self._connect(config) vector_field_dict = {k.name: k for k in table.schema if k.vector_index} - collection_name = _table_id(config.project, table) + collection_name = _table_id( + config.project, table, config.registry.enable_online_feature_view_versioning + ) if collection_name not in self._collections: # Create a composite key by combining entity fields composite_key_name = _get_composite_key_name(table) - + varchar_max_length = int(config.online_store.varchar_max_length or 65535) fields = [ FieldSchema( name=composite_key_name, dtype=DataType.VARCHAR, - max_length=512, + max_length=varchar_max_length, is_primary=True, ), FieldSchema(name="event_ts", dtype=DataType.INT64), @@ -195,14 +213,28 @@ def _get_or_create_collection( ) ) else: + if "max_length" in field.tags: + try: + field_max_length = int(field.tags["max_length"]) + except (ValueError, TypeError): + raise ValueError( + f"Field '{field.name}' has invalid max_length tag" + f" '{field.tags['max_length']}': must be an integer." + ) + if not (1 <= field_max_length <= 65535): + raise ValueError( + f"Field '{field.name}' max_length tag must be" + f" between 1 and 65535, got {field_max_length}" + ) + else: + field_max_length = varchar_max_length fields.append( FieldSchema( name=field.name, dtype=DataType.VARCHAR, - max_length=512, + max_length=field_max_length, ) ) - schema = CollectionSchema( fields=fields, description="Feast feature view data" ) @@ -339,10 +371,11 @@ def online_read( table: FeatureView, entity_keys: List[EntityKeyProto], requested_features: Optional[List[str]] = None, - full_feature_names: bool = False, ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: self.client = self._connect(config) - collection_name = _table_id(config.project, table) + collection_name = _table_id( + config.project, table, config.registry.enable_online_feature_view_versioning + ) collection = self._get_or_create_collection(config, table) composite_key_name = _get_composite_key_name(table) @@ -487,18 +520,19 @@ def update( ): self.client = self._connect(config) for table in tables_to_keep: - self._collections = self._get_or_create_collection(config, table) + self._get_or_create_collection(config, table) + # Always drop the base collection plus any "_v{N}" siblings, regardless of + # the current versioning flag. This handles mixed-state repos where + # versioning was toggled on/off across applies and would otherwise leave + # orphan collections behind in Milvus. for table in tables_to_delete: - collection_name = _table_id(config.project, table) - if self._collections.get(collection_name, None): - self.client.drop_collection(collection_name) - self._collections.pop(collection_name, None) + self._drop_all_version_collections(config.project, table) def plan( self, config: RepoConfig, desired_registry_proto: RegistryProto ) -> List[InfraObject]: - raise NotImplementedError + return [] def teardown( self, @@ -507,11 +541,9 @@ def teardown( entities: Sequence[Entity], ): self.client = self._connect(config) + # See update(): drop base + all "_v{N}" siblings to handle mixed-state repos. for table in tables: - collection_name = _table_id(config.project, table) - if self._collections.get(collection_name, None): - self.client.drop_collection(collection_name) - self._collections.pop(collection_name, None) + self._drop_all_version_collections(config.project, table) def retrieve_online_documents_v2( self, @@ -522,6 +554,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -546,7 +579,9 @@ def retrieve_online_documents_v2( k.name: k.dtype for k in table.entity_columns } self.client = self._connect(config) - collection_name = _table_id(config.project, table) + collection_name = _table_id( + config.project, table, config.registry.enable_online_feature_view_versioning + ) collection = self._get_or_create_collection(config, table) if not config.online_store.vector_enabled: raise ValueError("Vector search is not enabled in the online store config") @@ -685,9 +720,8 @@ def retrieve_online_documents_v2( for hit in hits: res = {} res_ts = None - entity_key_bytes = bytes.fromhex( - hit.get("entity", {}).get(composite_key_name, None) - ) + raw_key = hit.get("entity", {}).get(composite_key_name) + entity_key_bytes = bytes.fromhex(raw_key) if raw_key else None entity_key_proto = ( deserialize_entity_key(entity_key_bytes) if entity_key_bytes @@ -744,9 +778,28 @@ def retrieve_online_documents_v2( result_list.append((res_ts, entity_key_proto, res if res else None)) return result_list + def _drop_all_version_collections(self, project: str, table: FeatureView) -> None: + """Drop the base collection and every ``_v{N}`` versioned sibling. + + Mirrors the ``_drop_all_version_tables`` helpers in the MySQL/PostgreSQL + online stores. Always called from ``update`` and ``teardown`` so a + repo that toggles versioning on and off does not leave orphan + collections behind in Milvus. + """ + base = f"{project}_{table.name}" + versioned_prefix = f"{base}_v" + assert self.client is not None, "Milvus client is not initialized" + for collection_name in self.client.list_collections(): + if collection_name == base or ( + collection_name.startswith(versioned_prefix) + and collection_name[len(versioned_prefix) :].isdigit() + ): + self.client.drop_collection(collection_name) + self._collections.pop(collection_name, None) + -def _table_id(project: str, table: FeatureView) -> str: - return f"{project}_{table.name}" +def _table_id(project: str, table: FeatureView, enable_versioning: bool = False) -> str: + return compute_table_id(project, table, enable_versioning) def _get_composite_key_name(table: FeatureView) -> str: diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py index 3e7a3db84c8..d0105607d43 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py @@ -1,28 +1,33 @@ from __future__ import annotations +import time from datetime import datetime from logging import getLogger -from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple +from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union try: from pymongo import AsyncMongoClient, MongoClient, UpdateOne from pymongo.asynchronous.collection import AsyncCollection from pymongo.collection import Collection from pymongo.driver_info import DriverInfo + from pymongo.operations import SearchIndexModel except ImportError as e: from feast.errors import FeastExtrasDependencyImportError raise FeastExtrasDependencyImportError("mongodb", str(e)) import feast.version +from feast.batch_feature_view import BatchFeatureView from feast.entity import Entity from feast.feature_view import FeatureView -from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.key_encoding_utils import deserialize_entity_key, serialize_entity_key from feast.infra.online_stores.online_store import OnlineStore +from feast.infra.online_stores.vector_store import VectorStoreConfig from feast.infra.supported_async_methods import SupportedAsyncMethods from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import FeastConfigBaseModel, RepoConfig +from feast.stream_feature_view import StreamFeatureView from feast.type_map import ( feast_value_type_to_python_type, python_values_to_proto_values, @@ -33,7 +38,7 @@ DRIVER_METADATA = DriverInfo(name="Feast", version=feast.version.get_version()) -class MongoDBOnlineStoreConfig(FeastConfigBaseModel): +class MongoDBOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig): """MongoDB configuration. For a description of kwargs that may be passed to MongoClient, @@ -48,6 +53,11 @@ class MongoDBOnlineStoreConfig(FeastConfigBaseModel): ) collection_suffix: str = "latest" client_kwargs: Dict[str, Any] = {} + # vector_enabled and similarity are inherited from VectorStoreConfig + vector_index_wait_timeout: int = 60 + """Seconds to wait for a newly created Atlas Search index to become READY.""" + vector_index_wait_poll_interval: float = 1.0 + """Seconds between polls when waiting for an Atlas Search index to become READY.""" class MongoDBOnlineStore(OnlineStore): @@ -213,11 +223,135 @@ def online_read( return self._convert_raw_docs_to_proto(ids, docs, table) + def retrieve_online_documents_v2( + self, + config: RepoConfig, + table: FeatureView, + requested_features: List[str], + embedding: Optional[List[float]], + top_k: int, + distance_metric: Optional[str] = None, + query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, + ) -> List[ + Tuple[ + Optional[datetime], + Optional[EntityKeyProto], + Optional[Dict[str, ValueProto]], + ] + ]: + """Retrieve documents via MongoDB Atlas Vector Search ($vectorSearch). + + Uses the ``$vectorSearch`` aggregation stage to find the *top_k* + documents closest to the provided *embedding* vector. The method + expects that an Atlas vector search index has already been created for + the relevant field (see ``update()``). + + Returns a list of 3-tuples ``(event_timestamp, entity_key_proto, + feature_dict)`` where *feature_dict* includes the requested feature + values plus a synthetic ``distance`` key with the vector search score. + """ + if not config.online_store.vector_enabled: + raise ValueError( + "Vector search is not enabled in the online store config. " + "Set vector_enabled=True in MongoDBOnlineStoreConfig." + ) + if embedding is None: + raise ValueError( + "An embedding vector must be provided for MongoDB vector search." + ) + + clxn = self._get_collection(config) + + # Identify the vector field on this feature view + vector_fields = [f for f in table.features if f.vector_index] + if not vector_fields: + raise ValueError( + f"Feature view '{table.name}' has no fields with vector_index=True." + ) + vector_field = vector_fields[0] + path = f"features.{table.name}.{vector_field.name}" + idx_name = self._vector_search_index_name(table.name, vector_field.name) + + # BSON cannot encode numpy float types — ensure native Python floats. + query_vector = [float(v) for v in embedding] + + num_candidates = max(top_k * 10, 100) + pipeline: List[Dict[str, Any]] = [ + { + "$vectorSearch": { + "index": idx_name, + "path": path, + "queryVector": query_vector, + "numCandidates": num_candidates, + "limit": top_k, + } + }, + { + "$addFields": { + "score": {"$meta": "vectorSearchScore"}, + } + }, + ] + + results: List[ + Tuple[ + Optional[datetime], + Optional[EntityKeyProto], + Optional[Dict[str, ValueProto]], + ] + ] = [] + + for doc in clxn.aggregate(pipeline): + # Deserialize entity key + entity_key_bin = doc.get("_id") + entity_key_proto = ( + deserialize_entity_key( + entity_key_bin, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + if entity_key_bin + else None + ) + + # Event timestamp + event_ts = doc.get("event_timestamps", {}).get(table.name) + + # Build feature dict from raw doc values + fv_features = doc.get("features", {}).get(table.name, {}) + + # Convert raw values → ValueProto for each requested feature + feature_dict: Dict[str, ValueProto] = {} + feature_type_map = {f.name: f.dtype.to_value_type() for f in table.features} + + for feat_name in requested_features: + raw_val = fv_features.get(feat_name) + if raw_val is not None: + vtype = feature_type_map.get(feat_name) + if vtype is not None: + protos = python_values_to_proto_values( + [raw_val], feature_type=vtype + ) + feature_dict[feat_name] = protos[0] + else: + # Fall back: try to store as-is + feature_dict[feat_name] = _python_value_to_proto(raw_val) + + # Add distance (vector search score) + score = doc.get("score", 0.0) + feature_dict["distance"] = ValueProto(float_val=float(score)) + + results.append((event_ts, entity_key_proto, feature_dict)) + + return results + def update( self, config: RepoConfig, tables_to_delete: Sequence[FeatureView], - tables_to_keep: Sequence[FeatureView], + tables_to_keep: Sequence[ + Union[BatchFeatureView, StreamFeatureView, FeatureView] + ], entities_to_delete: Sequence[Entity], entities_to_keep: Sequence[Entity], partial: bool, @@ -238,20 +372,32 @@ def update( } We remove any feature views named in tables_to_delete. The Entities are serialized in the _id. No schema needs be adjusted. + + When ``vector_enabled`` is set in the online store config, Atlas Vector + Search indexes are automatically created for feature views containing + fields with ``vector_index=True`` and dropped for deleted feature views. """ if not isinstance(config.online_store, MongoDBOnlineStoreConfig): raise RuntimeError(f"{config.online_store.type = }. It must be mongodb.") + online_config = config.online_store clxn = self._get_collection(repo_config=config) + # --- Remove deleted feature views (data + vector search indexes) --- if tables_to_delete: unset_fields = {} for fv in tables_to_delete: unset_fields[f"features.{fv.name}"] = "" unset_fields[f"event_timestamps.{fv.name}"] = "" - clxn.update_many({}, {"$unset": unset_fields}) + if online_config.vector_enabled: + self._drop_vector_indexes_for_tables(clxn, tables_to_delete) + + # --- Create vector search indexes for kept feature views --- + if online_config.vector_enabled: + self._ensure_vector_indexes(clxn, tables_to_keep, online_config) + # Note: entities_to_delete contains Entity definitions (metadata), not entity instances. # Like other online stores, we don't need to do anything with entities_to_delete here. @@ -286,6 +432,136 @@ async def close(self) -> None: # Helpers # ------------------------------------------------------------------ + # -- Vector Search helpers ------------------------------------------ + + @staticmethod + def _vector_search_index_name(fv_name: str, field_name: str) -> str: + """Canonical Atlas vector search index name for a (feature_view, field) pair.""" + return f"{fv_name}__{field_name}__vs_index" + + @staticmethod + def _vector_search_index_definition( + path: str, + num_dimensions: int, + similarity: str, + ) -> dict: + """Return a vector search index definition for ``SearchIndexModel``.""" + return { + "fields": [ + { + "type": "vector", + "path": path, + "numDimensions": num_dimensions, + "similarity": similarity, + } + ] + } + + @staticmethod + def _wait_for_index_ready( + collection: Collection, + index_name: str, + timeout: int, + poll_interval: float = 1.0, + ) -> None: + """Poll until the named Atlas Search index reaches READY status. + + Raises ``TimeoutError`` if the index does not become queryable + within *timeout* seconds. + """ + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + for idx in collection.list_search_indexes(name=index_name): + if idx.get("status") == "READY" or idx.get("queryable") is True: + return + time.sleep(poll_interval) + raise TimeoutError( + f"Atlas search index '{index_name}' did not reach READY " + f"within {timeout}s. Increase vector_index_wait_timeout in " + f"MongoDBOnlineStoreConfig if the index needs more time." + ) + + def _drop_vector_indexes_for_tables( + self, + collection: Collection, + tables: Sequence[FeatureView], + ) -> None: + """Drop all Atlas vector search indexes belonging to the given feature views.""" + existing = {idx["name"] for idx in collection.list_search_indexes()} + for fv in tables: + for field in fv.features: + idx_name = self._vector_search_index_name(fv.name, field.name) + if idx_name in existing: + logger.info("Dropping vector search index: %s", idx_name) + collection.drop_search_index(idx_name) + + def _ensure_vector_indexes( + self, + collection: Collection, + tables: Sequence[Union[BatchFeatureView, StreamFeatureView, FeatureView]], + online_config: MongoDBOnlineStoreConfig, + ) -> None: + """Create Atlas vector search indexes for vector-indexed fields if they don't exist. + + Currently creates one index per (feature_view, vector_field) pair. + A future optimization could consolidate all vector fields into a + single composite index with multiple field definitions, reducing + cluster-wide index count and memory overhead. See Atlas limits: + hard cap of 2,500 search indexes per cluster; smaller tiers (M10) + may degrade well before that. + """ + db = collection.database + if collection.name not in db.list_collection_names(): + db.create_collection(collection.name) + + existing = {idx["name"] for idx in collection.list_search_indexes()} + + for fv in tables: + vector_fields = [f for f in fv.features if f.vector_index] + for field in vector_fields: + idx_name = self._vector_search_index_name(fv.name, field.name) + if idx_name in existing: + logger.debug("Vector search index '%s' already exists", idx_name) + continue + + path = f"features.{fv.name}.{field.name}" + num_dimensions = field.vector_length + if not num_dimensions: + raise ValueError( + f"Field '{field.name}' in feature view '{fv.name}' has " + f"vector_index=True but vector_length is not set." + ) + + similarity = ( + field.vector_search_metric or online_config.similarity or "cosine" + ) + + definition = self._vector_search_index_definition( + path, num_dimensions, similarity + ) + search_index_model = SearchIndexModel( + definition=definition, + name=idx_name, + type="vectorSearch", + ) + logger.info( + "Creating Atlas vector search index '%s' on path '%s' " + "(dims=%d, similarity=%s)", + idx_name, + path, + num_dimensions, + similarity, + ) + collection.create_search_index(model=search_index_model) + self._wait_for_index_ready( + collection, + idx_name, + online_config.vector_index_wait_timeout, + online_config.vector_index_wait_poll_interval, + ) + + # -- Connection helpers --------------------------------------------- + def _get_client(self, config: RepoConfig): """Returns a connection to the server.""" online_store_config = config.online_store @@ -494,5 +770,20 @@ async def online_write_batch_async( progress(len(data)) -# TODO -# - Vector Search (requires atlas image in testcontainers or similar) +def _python_value_to_proto(value: Any) -> ValueProto: + """Best-effort conversion of a single Python value to ValueProto.""" + if isinstance(value, float): + return ValueProto(float_val=value) + elif isinstance(value, bool): + return ValueProto(bool_val=value) + elif isinstance(value, int): + return ValueProto(int64_val=value) + elif isinstance(value, str): + return ValueProto(string_val=value) + elif isinstance(value, bytes): + return ValueProto(bytes_val=value) + elif isinstance(value, list) and all(isinstance(v, float) for v in value): + proto = ValueProto() + proto.float_list_val.val.extend(value) + return proto + return ValueProto() diff --git a/sdk/python/feast/infra/online_stores/mysql_online_store/mysql.py b/sdk/python/feast/infra/online_stores/mysql_online_store/mysql.py index 2172f3aa359..415184ea248 100644 --- a/sdk/python/feast/infra/online_stores/mysql_online_store/mysql.py +++ b/sdk/python/feast/infra/online_stores/mysql_online_store/mysql.py @@ -10,6 +10,7 @@ from feast import Entity, FeatureView, RepoConfig from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.online_stores.helpers import compute_table_id from feast.infra.online_stores.online_store import OnlineStore from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto @@ -70,6 +71,7 @@ def online_write_batch( cur = conn.cursor() project = config.project + versioning = config.registry.enable_online_feature_view_versioning batch_write = config.online_store.batch_write if not batch_write: @@ -92,6 +94,7 @@ def online_write_batch( table, timestamp, val, + versioning, ) conn.commit() if progress: @@ -124,7 +127,9 @@ def online_write_batch( if len(insert_values) >= batch_size: try: - self._execute_batch(cur, project, table, insert_values) + self._execute_batch( + cur, project, table, insert_values, versioning + ) conn.commit() if progress: progress(len(insert_values)) @@ -135,7 +140,7 @@ def online_write_batch( if insert_values: try: - self._execute_batch(cur, project, table, insert_values) + self._execute_batch(cur, project, table, insert_values, versioning) conn.commit() if progress: progress(len(insert_values)) @@ -143,9 +148,12 @@ def online_write_batch( conn.rollback() raise e - def _execute_batch(self, cur, project, table, insert_values): - sql = f""" - INSERT INTO {_table_id(project, table)} + def _execute_batch( + self, cur, project, table, insert_values, enable_versioning=False + ): + table_name = _table_id(project, table, enable_versioning) + stmt = f""" + INSERT INTO {table_name} (entity_key, feature_name, value, event_ts, created_ts) values (%s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE @@ -154,22 +162,29 @@ def _execute_batch(self, cur, project, table, insert_values): created_ts = VALUES(created_ts); """ try: - cur.executemany(sql, insert_values) + cur.executemany(stmt, insert_values) except Exception as e: - # Log SQL info for debugging without leaking sensitive data first_sample = insert_values[0] if insert_values else None raise RuntimeError( - f"Failed to execute batch insert into table '{_table_id(project, table)}' " + f"Failed to execute batch insert into table '{table_name}' " f"(rows={len(insert_values)}, sample={first_sample}): {e}" ) from e @staticmethod def write_to_table( - created_ts, cur, entity_key_bin, feature_name, project, table, timestamp, val + created_ts, + cur, + entity_key_bin, + feature_name, + project, + table, + timestamp, + val, + enable_versioning=False, ) -> None: cur.execute( f""" - INSERT INTO {_table_id(project, table)} + INSERT INTO {_table_id(project, table, enable_versioning)} (entity_key, feature_name, value, event_ts, created_ts) values (%s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE @@ -204,6 +219,7 @@ def online_read( result: List[Tuple[Optional[datetime], Optional[Dict[str, Any]]]] = [] project = config.project + versioning = config.registry.enable_online_feature_view_versioning for entity_key in entity_keys: entity_key_bin = serialize_entity_key( entity_key, @@ -211,7 +227,7 @@ def online_read( ).hex() cur.execute( - f"SELECT feature_name, value, event_ts FROM {_table_id(project, table)} WHERE entity_key = %s", + f"SELECT feature_name, value, event_ts FROM {_table_id(project, table, versioning)} WHERE entity_key = %s", (entity_key_bin,), ) @@ -243,10 +259,11 @@ def update( conn = self._get_conn(config) cur = conn.cursor() project = config.project + versioning = config.registry.enable_online_feature_view_versioning # We don't create any special state for the entities in this implementation. for table in tables_to_keep: - table_name = _table_id(project, table) + table_name = _table_id(project, table, versioning) index_name = f"{table_name}_ek" cur.execute( f"""CREATE TABLE IF NOT EXISTS {table_name} (entity_key VARCHAR(512), @@ -269,7 +286,10 @@ def update( ) for table in tables_to_delete: - _drop_table_and_index(cur, project, table) + if versioning: + _drop_all_version_tables(cur, project, table) + else: + _drop_table_and_index(cur, _table_id(project, table)) def teardown( self, @@ -280,16 +300,30 @@ def teardown( conn = self._get_conn(config) cur = conn.cursor() project = config.project + versioning = config.registry.enable_online_feature_view_versioning for table in tables: - _drop_table_and_index(cur, project, table) + if versioning: + _drop_all_version_tables(cur, project, table) + else: + _drop_table_and_index(cur, _table_id(project, table)) -def _drop_table_and_index(cur: Cursor, project: str, table: FeatureView) -> None: - table_name = _table_id(project, table) - cur.execute(f"DROP INDEX {table_name}_ek ON {table_name};") +def _drop_table_and_index(cur: Cursor, table_name: str) -> None: cur.execute(f"DROP TABLE IF EXISTS {table_name}") -def _table_id(project: str, table: FeatureView) -> str: - return f"{project}_{table.name}" +def _drop_all_version_tables(cur: Cursor, project: str, table: FeatureView) -> None: + """Drop the base table and all versioned tables (e.g. _v1, _v2, ...).""" + base = f"{project}_{table.name}" + cur.execute( + "SELECT table_name FROM information_schema.tables " + "WHERE table_schema = DATABASE() AND (table_name = %s OR table_name REGEXP %s)", + (base, f"^{base}_v[0-9]+$"), + ) + for (name,) in cur.fetchall(): + _drop_table_and_index(cur, name) + + +def _table_id(project: str, table: FeatureView, enable_versioning: bool = False) -> str: + return compute_table_id(project, table, enable_versioning) diff --git a/sdk/python/feast/infra/online_stores/online_store.py b/sdk/python/feast/infra/online_stores/online_store.py index b77185229d5..87feba3f830 100644 --- a/sdk/python/feast/infra/online_stores/online_store.py +++ b/sdk/python/feast/infra/online_stores/online_store.py @@ -12,12 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. import asyncio +import logging +import time as _time_mod from abc import ABC, abstractmethod from datetime import datetime from typing import Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple, Union +from google.protobuf.timestamp_pb2 import Timestamp + from feast import Entity, utils from feast.batch_feature_view import BatchFeatureView +from feast.errors import VersionedOnlineReadNotSupported from feast.feature_service import FeatureService from feast.feature_view import FeatureView from feast.infra.infra_object import InfraObject @@ -30,6 +35,9 @@ from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import RepoConfig from feast.stream_feature_view import StreamFeatureView +from feast.value_type import ValueType + +logger = logging.getLogger(__name__) class OnlineStore(ABC): @@ -154,6 +162,7 @@ def get_online_features( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: if isinstance(entity_rows, list): columnar: Dict[str, List[Any]] = {k: [] for k in entity_rows[0].keys()} @@ -185,17 +194,157 @@ def get_online_features( native_entity_values=True, ) - for table, requested_features in grouped_refs: - # Get the correct set of entity values with the correct join keys. - table_entity_values, idxs, output_len = utils._get_unique_entities( - table, + # Check for versioned reads on unsupported stores + self._check_versioned_read_support(grouped_refs) + _track_read = False + try: + from feast.metrics import _config as _metrics_config + + _track_read = _metrics_config.online_features + except Exception: + pass + + if _track_read: + import time as _time + + _read_start = _time.monotonic() + + use_precomputed = ( + isinstance(features, FeatureService) + and getattr(features, "precompute_online", False) + and not requested_on_demand_feature_views + ) + + precomputed_ok = False + if use_precomputed and grouped_refs: + assert isinstance(features, FeatureService) + first_table = grouped_refs[0][0] + first_entity_values, first_idxs, output_len = utils._get_unique_entities( + first_table, join_key_values, entity_name_to_join_key_map + ) + entity_key_protos = utils._get_entity_key_protos(first_entity_values) + + blobs = self.read_precomputed_vectors( + config, features.name, project, entity_key_protos + ) + expected_names = self._compute_expected_feature_names( + grouped_refs, full_feature_names + ) + precomputed_ok = self._try_precomputed_fast_path( + blobs, + expected_names, + online_features_response, + full_feature_names, + output_len, + grouped_refs, + registry, + project, + ) + if not precomputed_ok: + raise RuntimeError( + f"FeatureService '{features.name}' has precompute_online=True " + f"but pre-computed vectors could not be read. " + f"Run `feast precompute {features.name}` or materialize to " + f"populate vectors." + ) + + if not precomputed_ok: + self._read_features_per_fv( + config, + grouped_refs, join_key_values, entity_name_to_join_key_map, + online_features_response, + full_feature_names, + include_feature_view_version_metadata, ) + if _track_read: + from feast.metrics import track_online_store_read + + track_online_store_read(_time.monotonic() - _read_start) + + feature_types = self._build_feature_types(grouped_refs) + + if requested_on_demand_feature_views: + utils._augment_response_with_on_demand_transforms( + online_features_response, + feature_refs, + requested_on_demand_feature_views, + full_feature_names, + feature_types=feature_types, + ) + + utils._drop_unneeded_columns( + online_features_response, requested_result_row_names + ) + return OnlineResponse(online_features_response, feature_types=feature_types) + + _versioned_read_supported: Optional[bool] = None + + def _check_versioned_read_support(self, grouped_refs): + """Raise an error if versioned reads are attempted on unsupported stores.""" + if self._versioned_read_supported is None: + self._versioned_read_supported = self._is_versioned_read_supported() + + if self._versioned_read_supported: + return + for table, _ in grouped_refs: + version_tag = getattr(table.projection, "version_tag", None) + if version_tag is not None: + raise VersionedOnlineReadNotSupported( + self.__class__.__name__, version_tag + ) + + def _is_versioned_read_supported(self) -> bool: + """Check if this store type supports versioned reads (resolved once, cached).""" + from feast.infra.online_stores.sqlite import SqliteOnlineStore + + supported_types: list[type] = [SqliteOnlineStore] + for module, cls_name in ( + ("feast.infra.online_stores.mysql_online_store.mysql", "MySQLOnlineStore"), + ( + "feast.infra.online_stores.postgres_online_store.postgres", + "PostgreSQLOnlineStore", + ), + ("feast.infra.online_stores.faiss_online_store", "FaissOnlineStore"), + ("feast.infra.online_stores.redis", "RedisOnlineStore"), + ("feast.infra.online_stores.dynamodb", "DynamoDBOnlineStore"), + ( + "feast.infra.online_stores.milvus_online_store.milvus", + "MilvusOnlineStore", + ), + ): + try: + import importlib + + mod = importlib.import_module(module) + supported_types.append(getattr(mod, cls_name)) + except Exception: + pass + return isinstance(self, tuple(supported_types)) + + def _read_features_per_fv( + self, + config: RepoConfig, + grouped_refs: List, + join_key_values: Dict, + entity_name_to_join_key_map: Dict, + online_features_response, + full_feature_names: bool, + include_feature_view_version_metadata: bool, + ) -> None: + """Read features one feature-view at a time (generic path). + + Subclasses may override to batch reads more efficiently (e.g. Redis + pipeline). + """ + for table, requested_features in grouped_refs: + table_entity_values, idxs, output_len = utils._get_unique_entities( + table, join_key_values, entity_name_to_join_key_map + ) entity_key_protos = utils._get_entity_key_protos(table_entity_values) - # Fetch data for Entities. read_rows = self.online_read( config=config, table=table, @@ -203,33 +352,88 @@ def get_online_features( requested_features=requested_features, ) - feature_data = utils._convert_rows_to_protobuf( - requested_features, read_rows - ) - - # Populate the result_rows with the Features from the OnlineStore inplace. utils._populate_response_from_feature_data( - feature_data, + requested_features, + read_rows, idxs, online_features_response, full_feature_names, - requested_features, table, output_len, + include_feature_view_version_metadata, ) - if requested_on_demand_feature_views: - utils._augment_response_with_on_demand_transforms( + async def _read_features_per_fv_async( + self, + config: RepoConfig, + grouped_refs: List, + join_key_values: Dict, + entity_name_to_join_key_map: Dict, + online_features_response, + full_feature_names: bool, + include_feature_view_version_metadata: bool, + ) -> None: + """Async version of :meth:`_read_features_per_fv`. + + Reads all feature views concurrently via ``asyncio.gather``. + Subclasses may override to batch reads more efficiently. + """ + + async def query_table(table, requested_features): + table_entity_values, idxs, output_len = utils._get_unique_entities( + table, join_key_values, entity_name_to_join_key_map + ) + entity_key_protos = utils._get_entity_key_protos(table_entity_values) + read_rows = await self.online_read_async( + config=config, + table=table, + entity_keys=entity_key_protos, + requested_features=requested_features, + ) + return idxs, read_rows, output_len + + all_responses = await asyncio.gather( + *[ + query_table(table, requested_features) + for table, requested_features in grouped_refs + ] + ) + + for (idxs, read_rows, output_len), (table, requested_features) in zip( + all_responses, grouped_refs + ): + utils._populate_response_from_feature_data( + requested_features, + read_rows, + idxs, online_features_response, - feature_refs, - requested_on_demand_feature_views, full_feature_names, + table, + output_len, + include_feature_view_version_metadata, ) - utils._drop_unneeded_columns( - online_features_response, requested_result_row_names + async def read_precomputed_vectors_async( + self, + config: RepoConfig, + feature_service_name: str, + project: str, + entity_keys: List[EntityKeyProto], + ) -> List[Optional[bytes]]: + """Async version of :meth:`read_precomputed_vectors`. + + The default implementation delegates to the sync method via the event + loop executor. Online stores with native async support should override. + """ + loop = asyncio.get_event_loop() + return await loop.run_in_executor( + None, + self.read_precomputed_vectors, + config, + feature_service_name, + project, + entity_keys, ) - return OnlineResponse(online_features_response) async def get_online_features_async( self, @@ -242,6 +446,7 @@ async def get_online_features_async( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: if isinstance(entity_rows, list): columnar: Dict[str, List[Any]] = {k: [] for k in entity_rows[0].keys()} @@ -273,63 +478,349 @@ async def get_online_features_async( native_entity_values=True, ) - async def query_table(table, requested_features): - # Get the correct set of entity values with the correct join keys. - table_entity_values, idxs, output_len = utils._get_unique_entities( - table, - join_key_values, - entity_name_to_join_key_map, - ) + # Check for versioned reads on unsupported stores + self._check_versioned_read_support(grouped_refs) - entity_key_protos = utils._get_entity_key_protos(table_entity_values) + _track_read = False + try: + from feast.metrics import _config as _metrics_config - # Fetch data for Entities. - read_rows = await self.online_read_async( - config=config, - table=table, - entity_keys=entity_key_protos, - requested_features=requested_features, - ) + _track_read = _metrics_config.online_features + except Exception: + pass - return idxs, read_rows, output_len + if _track_read: + import time as _time - all_responses = await asyncio.gather( - *[ - query_table(table, requested_features) - for table, requested_features in grouped_refs - ] + _read_start = _time.monotonic() + + use_precomputed = ( + isinstance(features, FeatureService) + and getattr(features, "precompute_online", False) + and not requested_on_demand_feature_views ) - for (idxs, read_rows, output_len), (table, requested_features) in zip( - all_responses, grouped_refs - ): - feature_data = utils._convert_rows_to_protobuf( - requested_features, read_rows + precomputed_ok = False + if use_precomputed and grouped_refs: + assert isinstance(features, FeatureService) + first_table = grouped_refs[0][0] + first_entity_values, first_idxs, output_len = utils._get_unique_entities( + first_table, join_key_values, entity_name_to_join_key_map ) + entity_key_protos = utils._get_entity_key_protos(first_entity_values) - # Populate the result_rows with the Features from the OnlineStore inplace. - utils._populate_response_from_feature_data( - feature_data, - idxs, + blobs = await self.read_precomputed_vectors_async( + config, features.name, project, entity_key_protos + ) + expected_names = self._compute_expected_feature_names( + grouped_refs, full_feature_names + ) + precomputed_ok = self._try_precomputed_fast_path( + blobs, + expected_names, online_features_response, full_feature_names, - requested_features, - table, output_len, + grouped_refs, + registry, + project, + ) + if not precomputed_ok: + raise RuntimeError( + f"FeatureService '{features.name}' has precompute_online=True " + f"but pre-computed vectors could not be read. " + f"Run `feast precompute {features.name}` or materialize to " + f"populate vectors." + ) + + if not precomputed_ok: + await self._read_features_per_fv_async( + config, + grouped_refs, + join_key_values, + entity_name_to_join_key_map, + online_features_response, + full_feature_names, + include_feature_view_version_metadata, ) + if _track_read: + from feast.metrics import track_online_store_read + + track_online_store_read(_time.monotonic() - _read_start) + + feature_types = self._build_feature_types(grouped_refs) + if requested_on_demand_feature_views: utils._augment_response_with_on_demand_transforms( online_features_response, feature_refs, requested_on_demand_feature_views, full_feature_names, + feature_types=feature_types, ) utils._drop_unneeded_columns( online_features_response, requested_result_row_names ) - return OnlineResponse(online_features_response) + return OnlineResponse(online_features_response, feature_types=feature_types) + + @staticmethod + def _build_feature_types( + grouped_refs: List, + ) -> Dict[str, ValueType]: + """Build a mapping of feature names to ValueType from grouped feature view refs. + + Includes both bare names and prefixed names (feature_view__feature) so that + lookups succeed regardless of the full_feature_names setting. + """ + feature_types: Dict[str, ValueType] = {} + for table, requested_features in grouped_refs: + table_name = table.projection.name_to_use() + for field in table.features: + if field.name in requested_features: + vtype = field.dtype.to_value_type() + feature_types[field.name] = vtype + feature_types[f"{table_name}__{field.name}"] = vtype + return feature_types + + @staticmethod + def _compute_expected_feature_names( + grouped_refs: List, full_feature_names: bool + ) -> List[str]: + """Derive the deterministic feature name list for schema comparison.""" + names: List[str] = [] + for table, requested_features in grouped_refs: + table_name = table.projection.name_to_use() + for fn in requested_features: + if fn.startswith("_ts:"): + continue + names.append(f"{table_name}__{fn}" if full_feature_names else fn) + return names + + @staticmethod + def _try_precomputed_fast_path( + blobs: List[Optional[bytes]], + expected_feature_names: List[str], + online_features_response: Any, + full_feature_names: bool, + num_rows: int, + grouped_refs: List, + registry: BaseRegistry, + project: str, + ) -> bool: + """Build the response from pre-computed vectors. + + Returns True if the fast path succeeded for ALL entities, False otherwise + (caller should fall back to per-FV reads). + """ + from feast.protos.feast.core.PrecomputedFeatureVector_pb2 import ( + PrecomputedFeatureVector, + ) + from feast.protos.feast.serving.ServingService_pb2 import ( + FieldStatus, + GetOnlineFeaturesResponse, + ) + + for i, blob in enumerate(blobs): + if blob is None: + logger.warning( + "Pre-computed vector blob is None for entity index %d", i + ) + return False + + n_features = len(expected_feature_names) + expected_set = set(expected_feature_names) + + # Pre-compute feature-index-to-FV-name mapping once (not per entity). + feat_fv_names: List[Optional[str]] = [] + for fname in expected_feature_names: + feat_fv_names.append(fname.split("__", 1)[0] if "__" in fname else None) + + # Pre-compute FV TTLs once. + fv_ttls: Dict[str, Optional[int]] = {} + for table, _ in grouped_refs: + ttl = table.ttl + fv_ttls[table.projection.name_to_use()] = ( + int(ttl.total_seconds()) if ttl else None + ) + + # Check if any FV actually has a TTL — skip TTL logic entirely if not. + any_ttl = any(v is not None for v in fv_ttls.values()) + + # Parse all blobs, validate schema, build reorder map. + # Schema is typically identical for all entities, so validate against the + # first and then just verify the rest match the first (not the expected list). + first_stored_names: Optional[List[str]] = None + reorder_map: Optional[List[int]] = None + vectors: List[PrecomputedFeatureVector] = [] + + for blob in blobs: + vec = PrecomputedFeatureVector() + vec.ParseFromString(blob) # type: ignore[arg-type] + vectors.append(vec) + + if first_stored_names is None: + first_stored_names = list(vec.feature_names) + if set(first_stored_names) != expected_set: + logger.warning( + "Pre-computed vector schema mismatch: stored=%s, expected=%s", + first_stored_names, + expected_feature_names, + ) + return False + if first_stored_names != expected_feature_names: + name_to_idx = {n: i for i, n in enumerate(first_stored_names)} + reorder_map = [name_to_idx[n] for n in expected_feature_names] + else: + if ( + len(vec.feature_names) != n_features + or list(vec.feature_names) != first_stored_names + ): + logger.warning( + "Pre-computed vector schema varies across entities at index %d", + len(vectors) - 1, + ) + return False + + PRESENT = FieldStatus.PRESENT + OUTSIDE_MAX_AGE = FieldStatus.OUTSIDE_MAX_AGE + null_value = ValueProto() + null_ts = Timestamp() + + feat_values = [[null_value] * num_rows for _ in range(n_features)] + feat_statuses = [[FieldStatus.NOT_FOUND] * num_rows for _ in range(n_features)] + ts_list = [null_ts] * num_rows + + now_secs = _time_mod.time() if any_ttl else 0.0 + + for row_idx, vec in enumerate(vectors): + ts_list[row_idx] = vec.precomputed_at + + # Build per-FV expiry flags once per entity (not per feature). + fv_expired: Optional[Dict[str, bool]] = None + if any_ttl: + fv_ts_map: Dict[str, Timestamp] = { + fvt.feature_view_name: fvt.event_timestamp + for fvt in vec.fv_timestamps + } + fv_expired = {} + for fv_name, ttl_val in fv_ttls.items(): + if ttl_val is not None: + event_ts = fv_ts_map.get(fv_name) + if event_ts: + event_secs = event_ts.seconds + event_ts.nanos / 1e9 + fv_expired[fv_name] = (now_secs - event_secs) > ttl_val + else: + fv_expired[fv_name] = False + else: + fv_expired[fv_name] = False + + stored_values = vec.values + for out_idx in range(n_features): + src_idx = reorder_map[out_idx] if reorder_map else out_idx + feat_values[out_idx][row_idx] = stored_values[src_idx] + + if fv_expired: + feat_fv = feat_fv_names[out_idx] + if feat_fv and fv_expired.get(feat_fv, False): + feat_statuses[out_idx][row_idx] = OUTSIDE_MAX_AGE + continue + feat_statuses[out_idx][row_idx] = PRESENT + + online_features_response.metadata.feature_names.val.extend( + expected_feature_names + ) + for f_idx in range(n_features): + online_features_response.results.append( + GetOnlineFeaturesResponse.FeatureVector( + values=feat_values[f_idx], + statuses=feat_statuses[f_idx], + event_timestamps=ts_list, + ) + ) + return True + + def write_precomputed_vector( + self, + config: RepoConfig, + feature_service_name: str, + project: str, + entity_key: EntityKeyProto, + vector_bytes: bytes, + ) -> None: + """Write a pre-computed feature vector blob for a single entity. + + Stores the blob as a ``bytes_val`` feature under a synthetic FeatureView + named ``__precomputed__{service_name}``, using the generic + ``online_write_batch`` API so this works for every online store without + store-specific overrides. + """ + from feast.field import Field + from feast.types import Bytes + + synthetic_fv = FeatureView( + name=f"__precomputed__{feature_service_name}", + entities=[], + schema=[Field(name="vector", dtype=Bytes)], + source=None, + ) + val = ValueProto(bytes_val=vector_bytes) + ts = datetime.utcnow() + self.online_write_batch( + config=config, + table=synthetic_fv, + data=[(entity_key, {"vector": val}, ts, None)], + progress=None, + ) + + def read_precomputed_vectors( + self, + config: RepoConfig, + feature_service_name: str, + project: str, + entity_keys: List[EntityKeyProto], + ) -> List[Optional[bytes]]: + """Read pre-computed feature vector blobs for a batch of entities. + + Returns a list aligned with *entity_keys*. Each element is either the + serialized ``PrecomputedFeatureVector`` bytes or ``None`` when no + pre-computed vector exists for that entity. + + Reads from the synthetic FeatureView written by + :meth:`write_precomputed_vector` using the generic ``online_read`` API, + so this works for every online store without store-specific overrides. + """ + from feast.field import Field + from feast.types import Bytes + + synthetic_fv = FeatureView( + name=f"__precomputed__{feature_service_name}", + entities=[], + schema=[Field(name="vector", dtype=Bytes)], + source=None, + ) + try: + rows = self.online_read( + config=config, + table=synthetic_fv, + entity_keys=entity_keys, + requested_features=["vector"], + ) + except Exception: + return [None] * len(entity_keys) + + result: List[Optional[bytes]] = [] + for _ts, feature_dict in rows: + if feature_dict and "vector" in feature_dict: + val = feature_dict["vector"] + if val.HasField("bytes_val"): + result.append(val.bytes_val) + else: + result.append(None) + else: + result.append(None) + return result @abstractmethod def update( @@ -436,6 +927,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], diff --git a/sdk/python/feast/infra/online_stores/postgres_online_store/postgres.py b/sdk/python/feast/infra/online_stores/postgres_online_store/postgres.py index 0f7cb87856f..4a79349e91c 100644 --- a/sdk/python/feast/infra/online_stores/postgres_online_store/postgres.py +++ b/sdk/python/feast/infra/online_stores/postgres_online_store/postgres.py @@ -22,7 +22,7 @@ from feast import Entity, FeatureView, ValueType from feast.infra.key_encoding_utils import get_list_val_str, serialize_entity_key -from feast.infra.online_stores.helpers import _to_naive_utc +from feast.infra.online_stores.helpers import _to_naive_utc, compute_table_id from feast.infra.online_stores.online_store import OnlineStore from feast.infra.online_stores.vector_store import VectorStoreConfig from feast.infra.utils.postgres.connection_utils import ( @@ -152,7 +152,15 @@ def online_write_batch( event_ts = EXCLUDED.event_ts, created_ts = EXCLUDED.created_ts; """ - ).format(sql.Identifier(_table_id(config.project, table))) + ).format( + sql.Identifier( + _table_id( + config.project, + table, + config.registry.enable_online_feature_view_versioning, + ) + ) + ) # Push data into the online store with self._get_conn(config) as conn, conn.cursor() as cur: @@ -214,7 +222,13 @@ def _construct_query_and_params( FROM {} WHERE entity_key = ANY(%s) AND feature_name = ANY(%s); """ ).format( - sql.Identifier(_table_id(config.project, table)), + sql.Identifier( + _table_id( + config.project, + table, + config.registry.enable_online_feature_view_versioning, + ) + ), ) params = (keys, requested_features) else: @@ -224,7 +238,13 @@ def _construct_query_and_params( FROM {} WHERE entity_key = ANY(%s); """ ).format( - sql.Identifier(_table_id(config.project, table)), + sql.Identifier( + _table_id( + config.project, + table, + config.registry.enable_online_feature_view_versioning, + ) + ), ) params = (keys, []) return query, params @@ -304,12 +324,16 @@ def update( ), ) + versioning = config.registry.enable_online_feature_view_versioning for table in tables_to_delete: - table_name = _table_id(project, table) - cur.execute(_drop_table_and_index(table_name)) + if versioning: + _drop_all_version_tables(cur, project, table, schema_name) + else: + table_name = _table_id(project, table) + cur.execute(_drop_table_and_index(table_name)) for table in tables_to_keep: - table_name = _table_id(project, table) + table_name = _table_id(project, table, versioning) if config.online_store.vector_enabled: vector_value_type = "vector" else: @@ -363,11 +387,16 @@ def teardown( entities: Sequence[Entity], ): project = config.project + schema_name = config.online_store.db_schema or config.online_store.user + versioning = config.registry.enable_online_feature_view_versioning try: with self._get_conn(config) as conn, conn.cursor() as cur: for table in tables: - table_name = _table_id(project, table) - cur.execute(_drop_table_and_index(table_name)) + if versioning: + _drop_all_version_tables(cur, project, table, schema_name) + else: + table_name = _table_id(project, table) + cur.execute(_drop_table_and_index(table_name)) conn.commit() except Exception: logging.exception("Teardown failed") @@ -432,7 +461,9 @@ def retrieve_online_documents( ] ] = [] with self._get_conn(config, autocommit=True) as conn, conn.cursor() as cur: - table_name = _table_id(project, table) + table_name = _table_id( + project, table, config.registry.enable_online_feature_view_versioning + ) # Search query template to find the top k items that are closest to the given embedding # SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5; @@ -488,6 +519,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -532,7 +564,11 @@ def retrieve_online_documents_v2( and feature.name in requested_features ] - table_name = _table_id(config.project, table) + table_name = _table_id( + config.project, + table, + config.registry.enable_online_feature_view_versioning, + ) with self._get_conn(config, autocommit=True) as conn, conn.cursor() as cur: query = None @@ -543,50 +579,114 @@ def retrieve_online_documents_v2( tsquery_str = " & ".join(query_string.split()) query = sql.SQL( """ + WITH vector_candidates AS ( + SELECT entity_key, + MIN(vector_value {distance_metric_sql} %s::vector) as distance + FROM {table_name} + WHERE vector_value IS NOT NULL + GROUP BY entity_key + ORDER BY distance + LIMIT {top_k} + ), + text_candidates AS ( + SELECT entity_key, + MAX(ts_rank(to_tsvector('english', value_text), to_tsquery('english', %s))) as text_rank + FROM {table_name} + WHERE feature_name = ANY(%s) + AND to_tsvector('english', value_text) @@ to_tsquery('english', %s) + GROUP BY entity_key + ORDER BY text_rank DESC + LIMIT {top_k} + ), + all_candidates AS ( + SELECT entity_key FROM vector_candidates + UNION + SELECT entity_key FROM text_candidates + ), + scored AS ( + SELECT + ac.entity_key, + COALESCE(vc.distance, + (SELECT MIN(t.vector_value {distance_metric_sql} %s::vector) + FROM {table_name} t + WHERE t.entity_key = ac.entity_key AND t.vector_value IS NOT NULL) + ) as distance, + COALESCE(tc.text_rank, + COALESCE( + (SELECT MAX(ts_rank(to_tsvector('english', ft.value_text), to_tsquery('english', %s))) + FROM {table_name} ft + WHERE ft.entity_key = ac.entity_key AND ft.feature_name = ANY(%s) AND ft.value_text IS NOT NULL), + 0 + ) + ) as text_rank + FROM all_candidates ac + LEFT JOIN vector_candidates vc ON ac.entity_key = vc.entity_key + LEFT JOIN text_candidates tc ON ac.entity_key = tc.entity_key + ORDER BY text_rank DESC, distance + LIMIT {top_k} + ) SELECT - entity_key, - feature_name, - value, - vector_value, - vector_value {distance_metric_sql} %s::vector as distance, - ts_rank(to_tsvector('english', value_text), to_tsquery('english', %s)) as text_rank, - event_ts, - created_ts - FROM {table_name} - WHERE feature_name = ANY(%s) AND to_tsvector('english', value_text) @@ to_tsquery('english', %s) - ORDER BY distance - LIMIT {top_k} + t1.entity_key, + t1.feature_name, + t1.value, + t1.vector_value, + s.distance, + s.text_rank, + t1.event_ts, + t1.created_ts + FROM {table_name} t1 + INNER JOIN scored s ON t1.entity_key = s.entity_key + WHERE t1.feature_name = ANY(%s) + ORDER BY s.text_rank DESC, s.distance """ ).format( distance_metric_sql=sql.SQL(distance_metric_sql), table_name=sql.Identifier(table_name), top_k=sql.Literal(top_k), ) - params = (embedding, tsquery_str, string_fields, tsquery_str) - + params = ( + embedding, + tsquery_str, + string_fields, + tsquery_str, + embedding, + tsquery_str, + string_fields, + requested_features, + ) elif embedding is not None: # Case 2: Vector Search Only query = sql.SQL( """ + WITH vector_matches AS ( + SELECT entity_key, + MIN(vector_value {distance_metric_sql} %s::vector) as distance + FROM {table_name} + WHERE vector_value IS NOT NULL + GROUP BY entity_key + ORDER BY distance + LIMIT {top_k} + ) SELECT - entity_key, - feature_name, - value, - vector_value, - vector_value {distance_metric_sql} %s::vector as distance, - NULL as text_rank, -- Keep consistent columns - event_ts, - created_ts - FROM {table_name} - ORDER BY distance - LIMIT {top_k} + t1.entity_key, + t1.feature_name, + t1.value, + t1.vector_value, + t2.distance, + NULL as text_rank, + t1.event_ts, + t1.created_ts + FROM {table_name} t1 + INNER JOIN vector_matches t2 ON t1.entity_key = t2.entity_key + WHERE t1.feature_name = ANY(%s) + ORDER BY t2.distance """ ).format( distance_metric_sql=sql.SQL(distance_metric_sql), table_name=sql.Identifier(table_name), top_k=sql.Literal(top_k), ) - params = (embedding,) + params = (embedding, requested_features) elif query_string is not None and string_fields: # Case 3: Text Search Only @@ -686,9 +786,10 @@ def retrieve_online_documents_v2( sorted_entities = sorted( entities_dict.values(), key=lambda x: ( - x["vector_distance"] if embedding is not None else x["text_rank"] + (-x["text_rank"], x["vector_distance"]) + if query_string is not None + else (x["vector_distance"],) ), - reverse=(embedding is None), )[:top_k] result: List[ @@ -728,8 +829,8 @@ def retrieve_online_documents_v2( return result -def _table_id(project: str, table: FeatureView) -> str: - return f"{project}_{table.name}" +def _table_id(project: str, table: FeatureView, enable_versioning: bool = False) -> str: + return compute_table_id(project, table, enable_versioning) def _drop_table_and_index(table_name): @@ -742,3 +843,23 @@ def _drop_table_and_index(table_name): sql.Identifier(table_name), sql.Identifier(f"{table_name}_ek"), ) + + +def _drop_all_version_tables( + cur, project: str, table: FeatureView, schema_name: Optional[str] = None +) -> None: + """Drop the base table and all versioned tables (e.g. _v1, _v2, ...).""" + base = f"{project}_{table.name}" + if schema_name: + cur.execute( + "SELECT tablename FROM pg_tables " + "WHERE schemaname = %s AND (tablename = %s OR tablename ~ %s)", + (schema_name, base, f"^{base}_v[0-9]+$"), + ) + else: + cur.execute( + "SELECT tablename FROM pg_tables WHERE tablename = %s OR tablename ~ %s", + (base, f"^{base}_v[0-9]+$"), + ) + for (name,) in cur.fetchall(): + cur.execute(_drop_table_and_index(name)) diff --git a/sdk/python/feast/infra/online_stores/redis.py b/sdk/python/feast/infra/online_stores/redis.py index aeeb540b910..ad9e378a95f 100644 --- a/sdk/python/feast/infra/online_stores/redis.py +++ b/sdk/python/feast/infra/online_stores/redis.py @@ -32,8 +32,15 @@ from pydantic import StrictStr from feast import Entity, FeatureView, RepoConfig, utils -from feast.infra.online_stores.helpers import _mmh3, _redis_key, _redis_key_prefix +from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.online_stores.helpers import ( + _mmh3, + _redis_key, + _redis_key_prefix, + compute_versioned_name, +) from feast.infra.online_stores.online_store import OnlineStore +from feast.infra.supported_async_methods import SupportedAsyncMethods from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import FeastConfigBaseModel @@ -51,6 +58,13 @@ logger = logging.getLogger(__name__) +def _versioned_fv_name(table: FeatureView, config: RepoConfig) -> str: + """Return the feature view name with version suffix when versioning is enabled.""" + return compute_versioned_name( + table, config.registry.enable_online_feature_view_versioning + ) + + class RedisType(str, Enum): redis = "redis" redis_cluster = "redis_cluster" @@ -79,6 +93,11 @@ class RedisOnlineStoreConfig(FeastConfigBaseModel): full_scan_for_deletion: Optional[bool] = True """(Optional) whether to scan for deletion of features""" + skip_dedup: bool = False + """(Optional) Skip timestamp deduplication check on writes for higher throughput. + When True, writes proceed in a single pipeline without reading existing timestamps first. + This may cause older feature values to overwrite newer ones under concurrent writers.""" + class RedisOnlineStore(OnlineStore): """ @@ -96,6 +115,10 @@ class RedisOnlineStore(OnlineStore): None ) + @property + def async_supported(self) -> SupportedAsyncMethods: + return SupportedAsyncMethods(read=True, write=True) + def delete_entity_values(self, config: RepoConfig, join_keys: List[str]): client = self._get_client(config.online_store) deleted_count = 0 @@ -113,27 +136,43 @@ def delete_entity_values(self, config: RepoConfig, join_keys: List[str]): def delete_table(self, config: RepoConfig, table: FeatureView): """ - Delete all rows in Redis for a specific feature view + Delete all rows in Redis for a specific feature view. + + Uses a two-phase pipelined approach to avoid an O(K) synchronous hkeys + call inside the scan loop (N+1 pattern). Args: config: Feast config table: Feature view to delete """ client = self._get_client(config.online_store) - deleted_count = 0 prefix = _redis_key_prefix(table.join_keys) - redis_hash_keys = [_mmh3(f"{table.name}:{f.name}") for f in table.features] - redis_hash_keys.append(bytes(f"_ts:{table.name}", "utf8")) + fv_name = _versioned_fv_name(table, config) + fv_name_bytes = bytes(fv_name, "utf8") + redis_hash_keys = [_mmh3(f"{fv_name}:{f.name}") for f in table.features] + redis_hash_keys.append(bytes(f"_ts:{fv_name}", "utf8")) + # Phase 1: collect all matching entity keys from SCAN (no per-key round trips) + scan_pattern = b"".join([prefix, b"*", config.project.encode("utf8")]) + all_keys = list(client.scan_iter(scan_pattern)) + + if not all_keys: + logger.debug(f"Deleted 0 rows for feature view {fv_name}") + return + + # Phase 2: pipeline hkeys for all collected entity keys (1 round trip) with client.pipeline(transaction=False) as pipe: - for _k in client.scan_iter( - b"".join([prefix, b"*", config.project.encode("utf8")]) - ): - _tables = { - _hk[4:] for _hk in client.hgetall(_k) if _hk.startswith(b"_ts:") - } - if bytes(table.name, "utf8") not in _tables: + for _k in all_keys: + pipe.hkeys(_k) + all_hkeys = pipe.execute() + + # Phase 3: pipeline all deletions based on phase 2 results (1 round trip) + deleted_count = 0 + with client.pipeline(transaction=False) as pipe: + for _k, field_names in zip(all_keys, all_hkeys): + _tables = {_hk[4:] for _hk in field_names if _hk.startswith(b"_ts:")} + if fv_name_bytes not in _tables: continue if len(_tables) == 1: pipe.delete(_k) @@ -142,7 +181,7 @@ def delete_table(self, config: RepoConfig, table: FeatureView): deleted_count += 1 pipe.execute() - logger.debug(f"Deleted {deleted_count} rows for feature view {table.name}") + logger.debug(f"Deleted {deleted_count} rows for feature view {fv_name}") def update( self, @@ -281,8 +320,38 @@ def online_write_batch( client = self._get_client(online_store_config) project = config.project - feature_view = table.name + feature_view = _versioned_fv_name(table, config) ts_key = f"_ts:{feature_view}" + + if online_store_config.skip_dedup: + # Single-pipeline fast path: no timestamp read, directly write all rows. + # Reduces round trips from 2 to 1. Suitable for initial loads or + # append-only pipelines where out-of-order writes are not a concern. + with client.pipeline(transaction=False) as pipe: + for entity_key, values, timestamp, _ in data: + redis_key_bin = _redis_key( + project, + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + aware_ts = utils.make_tzaware(timestamp) + ts = Timestamp() + ts.FromDatetime(aware_ts) + entity_hset: Dict[Any, Any] = {ts_key: ts.SerializeToString()} + for feature_name, val in values.items(): + f_key = _mmh3(f"{feature_view}:{feature_name}") + entity_hset[f_key] = val.SerializeToString() + pipe.hset(redis_key_bin, mapping=entity_hset) + if online_store_config.key_ttl_seconds: + pipe.expire( + name=redis_key_bin, + time=online_store_config.key_ttl_seconds, + ) + results = pipe.execute() + if progress: + progress(len(results)) + return + keys = [] # redis pipelining optimization: send multiple commands to redis server without waiting for every reply with client.pipeline(transaction=False) as pipe: @@ -338,30 +407,123 @@ def online_write_batch( if progress: progress(len(results)) + async def online_write_batch_async( + self, + config: RepoConfig, + table: FeatureView, + data: List[ + Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] + ], + progress: Optional[Callable[[int], Any]], + ) -> None: + """Async version of online_write_batch using the async Redis client.""" + online_store_config = config.online_store + assert isinstance(online_store_config, RedisOnlineStoreConfig) + + client = await self._get_client_async(online_store_config) + project = config.project + + feature_view = _versioned_fv_name(table, config) + ts_key = f"_ts:{feature_view}" + + if online_store_config.skip_dedup: + async with client.pipeline(transaction=False) as pipe: + for entity_key, values, timestamp, _ in data: + redis_key_bin = _redis_key( + project, + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + aware_ts = utils.make_tzaware(timestamp) + ts = Timestamp() + ts.FromDatetime(aware_ts) + entity_hset: Dict[Any, Any] = {ts_key: ts.SerializeToString()} + for feature_name, val in values.items(): + f_key = _mmh3(f"{feature_view}:{feature_name}") + entity_hset[f_key] = val.SerializeToString() + pipe.hset(redis_key_bin, mapping=entity_hset) + if online_store_config.key_ttl_seconds: + pipe.expire( + name=redis_key_bin, + time=online_store_config.key_ttl_seconds, + ) + results = await pipe.execute() + if progress: + progress(len(results)) + return + + keys = [] + async with client.pipeline(transaction=False) as pipe: + for entity_key, _, _, _ in data: + redis_key_bin = _redis_key( + project, + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + keys.append(redis_key_bin) + pipe.hmget(redis_key_bin, ts_key) + prev_event_timestamps = await pipe.execute() + + prev_event_timestamps = [i[0] for i in prev_event_timestamps] + + async with client.pipeline(transaction=False) as pipe: + for redis_key_bin, prev_event_time, (_, values, timestamp, _) in zip( + keys, prev_event_timestamps, data + ): + aware_ts = utils.make_tzaware(timestamp) + ts = Timestamp() + ts.FromDatetime(aware_ts) + new_total_nanos = ts.seconds * 1_000_000_000 + ts.nanos + + if prev_event_time: + prev_ts = Timestamp() + prev_ts.ParseFromString(prev_event_time) + prev_total_nanos = prev_ts.seconds * 1_000_000_000 + prev_ts.nanos + if prev_total_nanos and new_total_nanos <= prev_total_nanos: + if progress: + progress(1) + continue + + entity_hset = {ts_key: ts.SerializeToString()} + for feature_name, val in values.items(): + f_key = _mmh3(f"{feature_view}:{feature_name}") + entity_hset[f_key] = val.SerializeToString() + + pipe.hset(redis_key_bin, mapping=entity_hset) + if online_store_config.key_ttl_seconds: + pipe.expire( + name=redis_key_bin, time=online_store_config.key_ttl_seconds + ) + + results = await pipe.execute() + if progress: + progress(len(results)) + def _generate_redis_keys_for_entities( self, config: RepoConfig, entity_keys: List[EntityKeyProto] ) -> List[bytes]: - keys = [] - for entity_key in entity_keys: - redis_key_bin = _redis_key( - config.project, - entity_key, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - keys.append(redis_key_bin) - return keys + project = config.project + version = config.entity_key_serialization_version + project_bytes = project.encode("utf-8") + return [ + serialize_entity_key(ek, entity_key_serialization_version=version) + + project_bytes + for ek in entity_keys + ] def _generate_hset_keys_for_features( self, feature_view: FeatureView, requested_features: Optional[List[str]] = None, + fv_name_override: Optional[str] = None, ) -> Tuple[List[str], List[str]]: if not requested_features: requested_features = [f.name for f in feature_view.features] - hset_keys = [_mmh3(f"{feature_view.name}:{k}") for k in requested_features] + fv_name = fv_name_override or feature_view.name + hset_keys = [_mmh3(f"{fv_name}:{k}") for k in requested_features] - ts_key = f"_ts:{feature_view.name}" + ts_key = f"_ts:{fv_name}" hset_keys.append(ts_key) requested_features.append(ts_key) @@ -390,9 +552,10 @@ def online_read( client = self._get_client(online_store_config) feature_view = table + fv_name = _versioned_fv_name(table, config) requested_features, hset_keys = self._generate_hset_keys_for_features( - feature_view, requested_features + feature_view, requested_features, fv_name_override=fv_name ) keys = self._generate_redis_keys_for_entities(config, entity_keys) @@ -403,7 +566,7 @@ def online_read( redis_values = pipe.execute() return self._convert_redis_values_to_protobuf( - redis_values, feature_view.name, requested_features + redis_values, fv_name, requested_features ) async def online_read_async( @@ -418,9 +581,10 @@ async def online_read_async( client = await self._get_client_async(online_store_config) feature_view = table + fv_name = _versioned_fv_name(table, config) requested_features, hset_keys = self._generate_hset_keys_for_features( - feature_view, requested_features + feature_view, requested_features, fv_name_override=fv_name ) keys = self._generate_redis_keys_for_entities(config, entity_keys) @@ -430,9 +594,139 @@ async def online_read_async( redis_values = await pipe.execute() return self._convert_redis_values_to_protobuf( - redis_values, feature_view.name, requested_features + redis_values, fv_name, requested_features ) + def _read_features_per_fv( + self, + config: RepoConfig, + grouped_refs, + join_key_values, + entity_name_to_join_key_map, + online_features_response, + full_feature_names: bool, + include_feature_view_version_metadata: bool, + ) -> None: + """Batch all per-FV HMGET commands into a single Redis pipeline.""" + work_items = [] + for table, requested_features in grouped_refs: + table_entity_values, idxs, output_len = utils._get_unique_entities( + table, join_key_values, entity_name_to_join_key_map + ) + entity_key_protos = utils._get_entity_key_protos(table_entity_values) + fv_name = _versioned_fv_name(table, config) + redis_keys = self._generate_redis_keys_for_entities( + config, entity_key_protos + ) + req_features, hset_keys = self._generate_hset_keys_for_features( + table, requested_features, fv_name_override=fv_name + ) + work_items.append( + (table, req_features, fv_name, hset_keys, redis_keys, idxs, output_len) + ) + + if work_items: + client = self._get_client(config.online_store) + with client.pipeline(transaction=False) as pipe: + for _, _, _, hset_keys, redis_keys, _, _ in work_items: + for redis_key in redis_keys: + pipe.hmget(redis_key, hset_keys) + all_results = pipe.execute() + + offset = 0 + for ( + table, + req_features, + fv_name, + _, + redis_keys, + idxs, + output_len, + ) in work_items: + n = len(redis_keys) + redis_values = all_results[offset : offset + n] + offset += n + + read_rows = self._convert_redis_values_to_protobuf( + redis_values, fv_name, req_features + ) + + utils._populate_response_from_feature_data( + req_features, + read_rows, + idxs, + online_features_response, + full_feature_names, + table, + output_len, + include_feature_view_version_metadata, + ) + + async def _read_features_per_fv_async( + self, + config: RepoConfig, + grouped_refs, + join_key_values, + entity_name_to_join_key_map, + online_features_response, + full_feature_names: bool, + include_feature_view_version_metadata: bool, + ) -> None: + """Async version: batch all per-FV HMGET into a single async pipeline.""" + work_items = [] + for table, requested_features in grouped_refs: + table_entity_values, idxs, output_len = utils._get_unique_entities( + table, join_key_values, entity_name_to_join_key_map + ) + entity_key_protos = utils._get_entity_key_protos(table_entity_values) + fv_name = _versioned_fv_name(table, config) + redis_keys = self._generate_redis_keys_for_entities( + config, entity_key_protos + ) + req_features, hset_keys = self._generate_hset_keys_for_features( + table, requested_features, fv_name_override=fv_name + ) + work_items.append( + (table, req_features, fv_name, hset_keys, redis_keys, idxs, output_len) + ) + + if work_items: + client = await self._get_client_async(config.online_store) + async with client.pipeline(transaction=False) as pipe: + for _, _, _, hset_keys, redis_keys, _, _ in work_items: + for redis_key in redis_keys: + pipe.hmget(redis_key, hset_keys) + all_results = await pipe.execute() + + offset = 0 + for ( + table, + req_features, + fv_name, + _, + redis_keys, + idxs, + output_len, + ) in work_items: + n = len(redis_keys) + redis_values = all_results[offset : offset + n] + offset += n + + read_rows = self._convert_redis_values_to_protobuf( + redis_values, fv_name, req_features + ) + + utils._populate_response_from_feature_data( + req_features, + read_rows, + idxs, + online_features_response, + full_feature_names, + table, + output_len, + include_feature_view_version_metadata, + ) + def _get_features_for_entity( self, values: List[ByteString], @@ -459,4 +753,5 @@ def _get_features_for_entity( total_seconds = res_ts.seconds + res_ts.nanos / 1_000_000_000.0 timestamp = datetime.fromtimestamp(total_seconds, tz=timezone.utc) + return timestamp, res diff --git a/sdk/python/feast/infra/online_stores/remote.py b/sdk/python/feast/infra/online_stores/remote.py index 5b5b04c362d..05a6b05dbea 100644 --- a/sdk/python/feast/infra/online_stores/remote.py +++ b/sdk/python/feast/infra/online_stores/remote.py @@ -13,18 +13,39 @@ # limitations under the License. import json import logging +import uuid as uuid_module from collections import defaultdict from datetime import datetime -from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple +from typing import ( + Any, + Callable, + Dict, + List, + Literal, + Mapping, + Optional, + Sequence, + Tuple, + Union, +) import requests from pydantic import StrictStr from feast import Entity, FeatureView, RepoConfig +from feast.feature_service import FeatureService from feast.infra.online_stores.helpers import _to_naive_utc from feast.infra.online_stores.online_store import OnlineStore +from feast.infra.registry.base_registry import BaseRegistry +from feast.online_response import OnlineResponse from feast.permissions.client.http_auth_requests_wrapper import HttpSessionManager +from feast.protos.feast.serving.ServingService_pb2 import ( + FieldStatus, + GetOnlineFeaturesResponse, + GetOnlineFeaturesResponseMetadata, +) from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import RepeatedValue from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import FeastConfigBaseModel from feast.rest_error_handler import rest_error_handling_decorator @@ -38,6 +59,17 @@ logger = logging.getLogger(__name__) +def _json_safe(val: Any) -> Any: + """Convert uuid.UUID objects and sets to JSON-serializable form.""" + if isinstance(val, uuid_module.UUID): + return str(val) + if isinstance(val, set): + return [str(v) if isinstance(v, uuid_module.UUID) else v for v in val] + if isinstance(val, list): + return [str(v) if isinstance(v, uuid_module.UUID) else v for v in val] + return val + + class RemoteOnlineStoreConfig(FeastConfigBaseModel): """Remote Online store config for remote online store""" @@ -94,6 +126,11 @@ def _proto_value_to_transport_value(proto_value: ValueProto) -> Any: if val_attr == "json_list_val": return list(getattr(proto_value, val_attr).val) + # Nested collection types use feast_value_type_to_python_type + # which handles recursive conversion of RepeatedValue protos. + if val_attr in ("list_val", "set_val"): + return feast_value_type_to_python_type(proto_value) + # Map/Struct types are converted to Python dicts by # feast_value_type_to_python_type. Serialise them to JSON strings # so the server-side DataFrame gets VARCHAR columns instead of @@ -103,8 +140,100 @@ def _proto_value_to_transport_value(proto_value: ValueProto) -> Any: if val_attr in ("map_list_val", "struct_list_val"): return [json.dumps(v) for v in feast_value_type_to_python_type(proto_value)] + # UUID types are stored as strings in proto — return them directly + # to avoid feast_value_type_to_python_type converting to uuid.UUID + # objects which are not JSON-serializable. + if val_attr in ("uuid_val", "time_uuid_val"): + return getattr(proto_value, val_attr) + if val_attr in ("uuid_list_val", "time_uuid_list_val"): + return list(getattr(proto_value, val_attr).val) + if val_attr in ("uuid_set_val", "time_uuid_set_val"): + return list(getattr(proto_value, val_attr).val) + return feast_value_type_to_python_type(proto_value) + _STATUS_MAP = { + "PRESENT": FieldStatus.PRESENT, + "NOT_FOUND": FieldStatus.NOT_FOUND, + "NULL_VALUE": FieldStatus.NULL_VALUE, + "OUTSIDE_MAX_AGE": FieldStatus.OUTSIDE_MAX_AGE, + } + + def get_online_features( + self, + config: RepoConfig, + features: Union[List[str], FeatureService], + entity_rows: Union[ + List[Dict[str, Any]], + Mapping[str, Union[Sequence[Any], Sequence[ValueProto], RepeatedValue]], + ], + registry: BaseRegistry, + project: str, + full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, + ) -> OnlineResponse: + assert isinstance(config.online_store, RemoteOnlineStoreConfig) + + if isinstance(entity_rows, list): + columnar: Dict[str, List[Any]] = {k: [] for k in entity_rows[0].keys()} + for entity_row in entity_rows: + for key, value in entity_row.items(): + columnar[key].append(value) + entity_rows = columnar + + entities: Dict[str, List[Any]] = {} + for k, vals in entity_rows.items(): + iterable = vals.val if isinstance(vals, RepeatedValue) else vals + entities[k] = [_json_safe(v) for v in iterable] + + req_body: Dict[str, Any] = { + "entities": entities, + "full_feature_names": full_feature_names, + "include_feature_view_version_metadata": include_feature_view_version_metadata, + } + + if isinstance(features, FeatureService): + req_body["feature_service"] = features.name + else: + req_body["features"] = features + + response = get_remote_online_features(config=config, req_body=req_body) + + if response.status_code != 200: + raise RuntimeError( + f"Failed to get online features: {response.status_code} {response.text}" + ) + + resp_json = response.json() + return self._build_online_response_from_json(resp_json) + + def _build_online_response_from_json( + self, resp_json: Dict[str, Any] + ) -> OnlineResponse: + proto = GetOnlineFeaturesResponse() + + metadata = GetOnlineFeaturesResponseMetadata() + feature_names = resp_json.get("metadata", {}).get("feature_names", []) + metadata.feature_names.val.extend(feature_names) + proto.metadata.CopyFrom(metadata) + + for result in resp_json.get("results", []): + fv = GetOnlineFeaturesResponse.FeatureVector() + for val in result.get("values", []): + if val is None: + fv.values.append(ValueProto()) + else: + protos = python_values_to_proto_values([val]) + fv.values.append(protos[0]) + for status_str in result.get("statuses", []): + fv.statuses.append( + self._STATUS_MAP.get(status_str, FieldStatus.INVALID) + ) + proto.results.append(fv) + + proto.status = True + return OnlineResponse(proto) + def online_write_batch( self, config: RepoConfig, @@ -128,9 +257,8 @@ def online_write_batch( for join_key, entity_value_proto in zip( entity_key_proto.join_keys, entity_key_proto.entity_values ): - columnar_data[join_key].append( - feast_value_type_to_python_type(entity_value_proto) - ) + val = feast_value_type_to_python_type(entity_value_proto) + columnar_data[join_key].append(_json_safe(val)) # Populate feature values – use transport-safe conversion that # preserves JSON strings instead of parsing them into dicts. @@ -183,6 +311,12 @@ def online_read( logger.debug("Able to retrieve the online features from feature server.") response_json = json.loads(response.text) event_ts = self._get_event_ts(response_json) + # Build feature name -> ValueType mapping so we can reconstruct + # complex types (nested collections, sets, etc.) that cannot be + # inferred from raw JSON values alone. + feature_type_map: Dict[str, ValueType] = { + f.name: f.dtype.to_value_type() for f in table.features + } # Iterating over results and converting the API results in column format to row format. result_tuples: List[ Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]] @@ -202,13 +336,16 @@ def online_read( ] == "PRESENT" ): + feature_value_type = feature_type_map.get( + feature_name, ValueType.UNKNOWN + ) message = python_values_to_proto_values( [ response_json["results"][index]["values"][ feature_value_index ] ], - ValueType.UNKNOWN, + feature_value_type, ) feature_values_dict[feature_name] = message[0] else: @@ -301,6 +438,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -465,7 +603,7 @@ def _construct_online_read_api_json_request( for row in entity_keys: entity_key = row.join_keys[0] entity_values.append( - getattr(row.entity_values[0], row.entity_values[0].WhichOneof("val")) + getattr(row.entity_values[0], row.entity_values[0].WhichOneof("val")) # type: ignore[arg-type] ) return { diff --git a/sdk/python/feast/infra/online_stores/sqlite.py b/sdk/python/feast/infra/online_stores/sqlite.py index 1be4141c650..6bba852f0b8 100644 --- a/sdk/python/feast/infra/online_stores/sqlite.py +++ b/sdk/python/feast/infra/online_stores/sqlite.py @@ -42,8 +42,10 @@ serialize_entity_key, serialize_f32, ) +from feast.infra.online_stores.helpers import compute_table_id from feast.infra.online_stores.online_store import OnlineStore from feast.infra.online_stores.vector_store import VectorStoreConfig +from feast.labeling.label_view import LabelView from feast.protos.feast.core.InfraObject_pb2 import InfraObject as InfraObjectProto from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto from feast.protos.feast.core.SqliteTable_pb2 import SqliteTable as SqliteTableProto @@ -174,7 +176,11 @@ def online_write_batch( if created_ts is not None: created_ts = to_naive_utc(created_ts) - table_name = _table_id(project, table) + table_name = _table_id( + project, + table, + config.registry.enable_online_feature_view_versioning, + ) for feature_name, val in values.items(): if config.online_store.vector_enabled: if ( @@ -254,7 +260,7 @@ def online_read( # Fetch all entities in one go cur.execute( f"SELECT entity_key, feature_name, value, event_ts " - f"FROM {_table_id(config.project, table)} " + f"FROM {_table_id(config.project, table, config.registry.enable_online_feature_view_versioning)} " f"WHERE entity_key IN ({','.join('?' * len(entity_keys))}) " f"ORDER BY entity_key", serialized_entity_keys, @@ -294,32 +300,51 @@ def update( conn = self._get_conn(config) project = config.project + versioning = config.registry.enable_online_feature_view_versioning for table in tables_to_keep: conn.execute( - f"CREATE TABLE IF NOT EXISTS {_table_id(project, table)} (entity_key BLOB, feature_name TEXT, value BLOB, vector_value BLOB, event_ts timestamp, created_ts timestamp, PRIMARY KEY(entity_key, feature_name))" + f"CREATE TABLE IF NOT EXISTS {_table_id(project, table, versioning)} (entity_key BLOB, feature_name TEXT, value BLOB, vector_value BLOB, event_ts timestamp, created_ts timestamp, PRIMARY KEY(entity_key, feature_name))" ) conn.execute( - f"CREATE INDEX IF NOT EXISTS {_table_id(project, table)}_ek ON {_table_id(project, table)} (entity_key);" + f"CREATE INDEX IF NOT EXISTS {_table_id(project, table, versioning)}_ek ON {_table_id(project, table, versioning)} (entity_key);" ) for table in tables_to_delete: - conn.execute(f"DROP TABLE IF EXISTS {_table_id(project, table)}") + conn.execute( + f"DROP TABLE IF EXISTS {_table_id(project, table, versioning)}" + ) def plan( self, config: RepoConfig, desired_registry_proto: RegistryProto ) -> List[InfraObject]: project = config.project + versioning = config.registry.enable_online_feature_view_versioning infra_objects: List[InfraObject] = [ SqliteTable( path=self._get_db_path(config), - name=_table_id(project, FeatureView.from_proto(view)), + name=_table_id( + project, + FeatureView.from_proto(view), + versioning, + ), ) for view in [ *desired_registry_proto.feature_views, *desired_registry_proto.stream_feature_views, ] ] + + for lv_proto in desired_registry_proto.label_views: + if lv_proto.spec.online: + lv = LabelView.from_proto(lv_proto) + infra_objects.append( + SqliteTable( + path=self._get_db_path(config), + name=_table_id(project, lv, versioning), + ) + ) + return infra_objects def teardown( @@ -375,7 +400,9 @@ def retrieve_online_documents( # Convert the embedding to a binary format instead of using SerializeToString() query_embedding_bin = serialize_f32(embedding, vector_field_length) - table_name = _table_id(project, table) + table_name = _table_id( + project, table, config.registry.enable_online_feature_view_versioning + ) vector_field = _get_vector_field(table) cur.execute( @@ -464,6 +491,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -499,7 +527,9 @@ def retrieve_online_documents_v2( _get_feature_view_vector_field_metadata(table), "vector_length", 512 ) - table_name = _table_id(config.project, table) + table_name = _table_id( + config.project, table, config.registry.enable_online_feature_view_versioning + ) vector_field = _get_vector_field(table) if online_store.vector_enabled: @@ -699,8 +729,8 @@ def _initialize_conn( return db -def _table_id(project: str, table: FeatureView) -> str: - return f"{project}_{table.name}" +def _table_id(project: str, table: Any, enable_versioning: bool = False) -> str: + return compute_table_id(project, table, enable_versioning) class SqliteTable(InfraObject): diff --git a/sdk/python/feast/infra/passthrough_provider.py b/sdk/python/feast/infra/passthrough_provider.py index 6830929e776..93f38567376 100644 --- a/sdk/python/feast/infra/passthrough_provider.py +++ b/sdk/python/feast/infra/passthrough_provider.py @@ -142,8 +142,8 @@ def plan_infra( def update_infra( self, project: str, - tables_to_delete: Sequence[FeatureView], - tables_to_keep: Sequence[Union[FeatureView, OnDemandFeatureView]], + tables_to_delete: Sequence[BaseFeatureView], + tables_to_keep: Sequence[BaseFeatureView], entities_to_delete: Sequence[Entity], entities_to_keep: Sequence[Entity], partial: bool, @@ -167,8 +167,8 @@ def update_infra( if self.batch_engine: self.batch_engine.update( project, - tables_to_delete, - tables_to_keep, + tables_to_delete, # type: ignore[arg-type] + tables_to_keep, # type: ignore[arg-type] entities_to_delete, entities_to_keep, ) @@ -247,6 +247,7 @@ def get_online_features( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: return self.online_store.get_online_features( config=config, @@ -255,6 +256,7 @@ def get_online_features( registry=registry, project=project, full_feature_names=full_feature_names, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) async def get_online_features_async( @@ -268,6 +270,7 @@ async def get_online_features_async( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: return await self.online_store.get_online_features_async( config=config, @@ -276,6 +279,7 @@ async def get_online_features_async( registry=registry, project=project, full_feature_names=full_feature_names, + include_feature_view_version_metadata=include_feature_view_version_metadata, ) async def online_read_async( @@ -322,6 +326,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List: result = [] if self.online_store: @@ -333,6 +338,7 @@ def retrieve_online_documents_v2( top_k, distance_metric, query_string, + include_feature_view_version_metadata, ) return result @@ -488,8 +494,12 @@ def get_historical_features( def retrieve_saved_dataset( self, config: RepoConfig, dataset: SavedDataset ) -> RetrievalJob: + from feast.utils import _strip_version_from_ref + feature_name_columns = [ - ref.replace(":", "__") if dataset.full_feature_names else ref.split(":")[1] + _strip_version_from_ref(ref).replace(":", "__") + if dataset.full_feature_names + else ref.split(":")[1] for ref in dataset.features ] diff --git a/sdk/python/feast/infra/provider.py b/sdk/python/feast/infra/provider.py index c2879c1e2db..cc0e60f43b4 100644 --- a/sdk/python/feast/infra/provider.py +++ b/sdk/python/feast/infra/provider.py @@ -69,8 +69,8 @@ def async_supported(self) -> ProviderAsyncMethods: def update_infra( self, project: str, - tables_to_delete: Sequence[FeatureView], - tables_to_keep: Sequence[Union[FeatureView, OnDemandFeatureView]], + tables_to_delete: Sequence[BaseFeatureView], + tables_to_keep: Sequence[BaseFeatureView], entities_to_delete: Sequence[Entity], entities_to_keep: Sequence[Entity], partial: bool, @@ -316,6 +316,7 @@ def get_online_features( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: pass @@ -331,6 +332,7 @@ async def get_online_features_async( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: pass @@ -468,6 +470,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], diff --git a/sdk/python/feast/infra/ray_initializer.py b/sdk/python/feast/infra/ray_initializer.py index eea21eaa321..556eb20da66 100644 --- a/sdk/python/feast/infra/ray_initializer.py +++ b/sdk/python/feast/infra/ray_initializer.py @@ -219,6 +219,58 @@ def read_csv(self, path: Union[str, List[str]], **kwargs) -> Any: """Read CSV files using standard Ray.""" return ray.data.read_csv(path, **kwargs) + def read_json(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read JSON/JSONL file(s).""" + return ray.data.read_json(path, **kwargs) + + def read_text(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read plain-text file(s).""" + return ray.data.read_text(path, **kwargs) + + def read_images(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read image files (PNG, JPEG, …) from a directory as numpy arrays.""" + return ray.data.read_images(path, **kwargs) + + def read_binary_files(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read arbitrary binary files; each row has 'path' and 'bytes' columns.""" + return ray.data.read_binary_files(path, **kwargs) + + def read_tfrecords(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read TFRecord file(s).""" + return ray.data.read_tfrecords(path, **kwargs) + + def read_webdataset(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read WebDataset tar shard(s).""" + return ray.data.read_webdataset(path, **kwargs) + + def read_mongo(self, uri: str, database: str, collection: str, **kwargs) -> Any: + """Read from a MongoDB collection.""" + return ray.data.read_mongo( + uri=uri, database=database, collection=collection, **kwargs + ) + + def read_sql(self, sql: str, connection_url: str, **kwargs) -> Any: + """Read from a SQL database. Builds the connection factory from connection_url.""" + import sqlalchemy + + def _connection_factory(): + # raw_connection() returns a DB API2-compliant connection (with .cursor()) + # from the underlying driver. engine.connect() returns a SQLAlchemy 2.0 + # Connection object which does NOT expose .cursor(), failing Ray Data's + # DB API2 compliance check. + return sqlalchemy.create_engine(connection_url).raw_connection() + + return ray.data.read_sql(sql, _connection_factory, **kwargs) + + def from_huggingface( + self, dataset_name: str, split: str = "train", **kwargs + ) -> Any: + """Load a HuggingFace dataset and convert to a Ray Dataset.""" + from datasets import load_dataset + + hf_dataset = load_dataset(dataset_name, split=split, **kwargs) + return ray.data.from_huggingface(hf_dataset) + def from_pandas(self, df: Any) -> Any: """Create dataset from pandas DataFrame using standard Ray.""" return ray.data.from_pandas(df) @@ -235,10 +287,13 @@ def __init__( self, cluster_name: str, namespace: str, - auth_token: str, - auth_server: str, + auth_token: str = "", + auth_server: str = "", skip_tls: bool = False, enable_logging: bool = False, + num_gpus: float = 0, + worker_task_options: Optional[Dict[str, Any]] = None, + runtime_env: Optional[Dict[str, Any]] = None, ): """Initialize CodeFlare Ray wrapper with cluster connection parameters.""" self.cluster_name = cluster_name @@ -247,6 +302,9 @@ def __init__( self.auth_server = auth_server self.skip_tls = skip_tls self.enable_logging = enable_logging + self.num_gpus = num_gpus + self.worker_task_options = worker_task_options or {} + self.extra_runtime_env = runtime_env or {} self.cluster = None # Authenticate and setup Ray connection @@ -254,7 +312,12 @@ def __init__( self._setup_ray_connection() def _authenticate_codeflare(self): - """Authenticate with CodeFlare SDK.""" + """Authenticate with CodeFlare SDK. Skipped for in-cluster pods with no explicit token.""" + if not self.auth_token or not self.auth_server: + logger.info( + "No auth_token/auth_server provided; assuming in-cluster auth via service account" + ) + return try: from codeflare_sdk import TokenAuthentication @@ -288,6 +351,18 @@ def _setup_ray_connection(self): "pip": ["feast"], "env_vars": {"RAY_DISABLE_IMPORT_WARNING": "1"}, } + if self.extra_runtime_env: + extra_pip = self.extra_runtime_env.get("pip", []) + if extra_pip: + runtime_env["pip"] = list( + dict.fromkeys(runtime_env["pip"] + extra_pip) + ) + extra_env_vars = self.extra_runtime_env.get("env_vars", {}) + if extra_env_vars: + runtime_env["env_vars"].update(extra_env_vars) + for k, v in self.extra_runtime_env.items(): + if k not in ("pip", "env_vars"): + runtime_env[k] = v ray.shutdown() @@ -307,54 +382,225 @@ def _setup_ray_connection(self): logger.error(f"Ray connection failed: {e}") raise + def _get_task_options(self, include_gpu: bool = False) -> Dict[str, Any]: + """Build Ray .options() kwargs for a remote task dispatch. + + Always includes the full worker_task_options passthrough dict. + num_gpus is merged in only when include_gpu=True, because I/O + operations (read_parquet, read_csv, from_pandas, from_arrow) are + pure data-movement and must not consume GPU slots. Pass + include_gpu=True only for compute/transformation tasks. + """ + opts: Dict[str, Any] = dict(self.worker_task_options) + if include_gpu and self.num_gpus: + opts["num_gpus"] = self.num_gpus + else: + # Guarantee no GPU slot is consumed for I/O tasks even if the + # caller placed num_gpus inside worker_task_options directly. + opts.pop("num_gpus", None) + return opts + # Ray Data API methods - wrapped in @ray.remote to execute on cluster workers def read_parquet(self, path: Union[str, List[str]], **kwargs) -> Any: """Read parquet files - runs remotely on KubeRay cluster workers.""" from feast.infra.ray_shared_utils import RemoteDatasetProxy @ray.remote - def _remote_read_parquet(file_path, read_kwargs): + def _remote(file_path, read_kwargs): import ray return ray.data.read_parquet(file_path, **read_kwargs) - return RemoteDatasetProxy(_remote_read_parquet.remote(path, kwargs)) + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) def read_csv(self, path: Union[str, List[str]], **kwargs) -> Any: - """Read CSV files - runs remotely on KubeRay cluster workers.""" + """Read CSV files - dispatched via @ray.remote to cluster workers.""" from feast.infra.ray_shared_utils import RemoteDatasetProxy @ray.remote - def _remote_read_csv(file_path, read_kwargs): + def _remote(file_path, read_kwargs): import ray return ray.data.read_csv(file_path, **read_kwargs) - return RemoteDatasetProxy(_remote_read_csv.remote(path, kwargs)) + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_json(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read JSON/JSONL files - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_json(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_text(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read plain-text files - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_text(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_images(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read image directory - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_images(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_binary_files(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read binary files - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_binary_files(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_tfrecords(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read TFRecord files - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_tfrecords(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_webdataset(self, path: Union[str, List[str]], **kwargs) -> Any: + """Read WebDataset shards - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(file_path, read_kwargs): + import ray + + return ray.data.read_webdataset(file_path, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(path, kwargs)) + + def read_mongo(self, uri: str, database: str, collection: str, **kwargs) -> Any: + """Read from MongoDB - dispatched via @ray.remote to cluster workers.""" + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(mongo_uri, db, col, read_kwargs): + import ray + + return ray.data.read_mongo( + uri=mongo_uri, database=db, collection=col, **read_kwargs + ) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(uri, database, collection, kwargs)) + + def read_sql(self, sql: str, connection_url: str, **kwargs) -> Any: + """Read from SQL database - dispatched via @ray.remote to cluster workers. + + Accepts connection_url (str) instead of a connection_factory callable so + the argument is serialisable across the Ray object store boundary. + """ + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(sql_query, conn_url, read_kwargs): + import ray + import sqlalchemy + + def _factory(): + return sqlalchemy.create_engine(conn_url).raw_connection() + + return ray.data.read_sql(sql_query, _factory, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(sql, connection_url, kwargs)) + + def from_huggingface( + self, dataset_name: str, split: str = "train", **kwargs + ) -> Any: + """Load a HuggingFace dataset on a remote Ray worker and return a Ray Dataset. + + The dataset is loaded directly on the worker to avoid serializing + memory-mapped HF Dataset objects across the network and to keep + driver memory usage near zero. + """ + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(ds_name, ds_split, extra_kwargs): + import ray + from datasets import load_dataset + + hf_dataset = load_dataset(ds_name, split=ds_split, **extra_kwargs) + return ray.data.from_huggingface(hf_dataset) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(dataset_name, split, kwargs)) def from_pandas(self, df: Any) -> Any: - """Create dataset from pandas DataFrame - runs remotely on KubeRay cluster workers.""" + """Create dataset from pandas DataFrame - dispatched via @ray.remote.""" from feast.infra.ray_shared_utils import RemoteDatasetProxy @ray.remote - def _remote_from_pandas(dataframe): + def _remote(dataframe): import ray return ray.data.from_pandas(dataframe) - return RemoteDatasetProxy(_remote_from_pandas.remote(df)) + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(df)) def from_arrow(self, table: Any) -> Any: - """Create dataset from Arrow table - runs remotely on KubeRay cluster workers.""" + """Create dataset from Arrow table - dispatched via @ray.remote.""" from feast.infra.ray_shared_utils import RemoteDatasetProxy @ray.remote - def _remote_from_arrow(arrow_table): + def _remote(arrow_table): import ray return ray.data.from_arrow(arrow_table) - return RemoteDatasetProxy(_remote_from_arrow.remote(table)) + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(table)) # Global state tracking @@ -547,10 +793,13 @@ def _initialize_kuberay(config: Any, enable_logging: bool = False) -> None: _ray_wrapper = CodeFlareRayWrapper( cluster_name=kuberay_config["cluster_name"], namespace=kuberay_config["namespace"], - auth_token=kuberay_config["auth_token"], - auth_server=kuberay_config["auth_server"], + auth_token=kuberay_config.get("auth_token", ""), + auth_server=kuberay_config.get("auth_server", ""), skip_tls=kuberay_config.get("skip_tls", False), enable_logging=enable_logging, + num_gpus=getattr(config, "num_gpus", 0) or 0, + worker_task_options=getattr(config, "worker_task_options", None), + runtime_env=kuberay_config.get("runtime_env"), ) logger.info("KubeRay cluster connection established via CodeFlare SDK") diff --git a/sdk/python/feast/infra/ray_shared_utils.py b/sdk/python/feast/infra/ray_shared_utils.py index 9614623294f..1d26074290a 100644 --- a/sdk/python/feast/infra/ray_shared_utils.py +++ b/sdk/python/feast/infra/ray_shared_utils.py @@ -14,14 +14,75 @@ def __init__(self, dataset_ref: Any): """Initialize with a reference to the remote dataset.""" self._dataset_ref = dataset_ref - def map_batches(self, func, **kwargs) -> "RemoteDatasetProxy": - """Execute map_batches remotely on cluster workers.""" + def map_batches( + self, + func, + num_gpus: float = 0, + worker_task_options: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> "RemoteDatasetProxy": + """Execute map_batches remotely on cluster workers. + + Resource options are applied at two levels: + + 1. **Orchestration task** (@ray.remote wrapper) — receives only the + non-compute keys from worker_task_options (runtime_env, max_retries, + scheduling_strategy, memory, …). Compute-scheduling keys + (num_gpus, num_cpus, accelerator_type, resources) are intentionally + excluded: the orchestration task only calls dataset.map_batches() + and holds no GPU/CPU work itself. Including num_gpus here would + waste a GPU slot for the entire operation duration and, on + GPU-constrained clusters, could cause deadlock where the orchestrator + holds a GPU while the data workers queue waiting for the same slots. + + 2. **Data workers** (inside dataset.map_batches) — receives the full + compute-scheduling subset (num_gpus, num_cpus, accelerator_type, + resources). Ray Data propagates these to the actual processing tasks. + + Args: + func: Batch transformation function. + num_gpus: Shorthand GPU count (merged into worker_task_options, + takes precedence). Kept first-class because it also drives + gpu_batch_format selection in the compute engine. + worker_task_options: Arbitrary Ray .options() kwargs (num_cpus, + memory, accelerator_type, resources, runtime_env, + max_retries, …). + **kwargs: Additional map_batches kwargs (batch_format, concurrency). + """ + # Merge num_gpus into worker_task_options; dedicated field takes precedence + opts: Dict[str, Any] = dict(worker_task_options or {}) + if num_gpus: + opts["num_gpus"] = num_gpus + + # Keys accepted by Ray Data's map_batches for per-worker scheduling + _MAP_BATCHES_RESOURCE_KEYS = { + "num_gpus", + "num_cpus", + "accelerator_type", + "resources", + } + + # Data workers get the compute-scheduling subset only + map_resource_kwargs = { + k: v for k, v in opts.items() if k in _MAP_BATCHES_RESOURCE_KEYS + } + + # Orchestration task gets the remainder (non-compute keys only) so it + # never holds GPU/CPU slots it doesn't use + orchestration_opts = { + k: v for k, v in opts.items() if k not in _MAP_BATCHES_RESOURCE_KEYS + } @ray.remote - def _remote_map_batches(dataset, function, batch_kwargs): - return dataset.map_batches(function, **batch_kwargs) + def _remote_map_batches(dataset, function, batch_kwargs, resource_kwargs): + return dataset.map_batches(function, **batch_kwargs, **resource_kwargs) - new_ref = _remote_map_batches.remote(self._dataset_ref, func, kwargs) + remote_fn = ( + _remote_map_batches.options(**orchestration_opts) + if orchestration_opts + else _remote_map_batches + ) + new_ref = remote_fn.remote(self._dataset_ref, func, kwargs, map_resource_kwargs) return RemoteDatasetProxy(new_ref) def filter(self, fn) -> "RemoteDatasetProxy": diff --git a/sdk/python/feast/infra/registry/base_registry.py b/sdk/python/feast/infra/registry/base_registry.py index c4bf1f5979c..09f47caac87 100644 --- a/sdk/python/feast/infra/registry/base_registry.py +++ b/sdk/python/feast/infra/registry/base_registry.py @@ -31,6 +31,7 @@ from feast.feature_service import FeatureService from feast.feature_view import FeatureView from feast.infra.infra_object import Infra +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -41,6 +42,7 @@ FeatureService as FeatureServiceProto, ) from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( OnDemandFeatureView as OnDemandFeatureViewProto, ) @@ -255,7 +257,11 @@ def list_feature_services( # Feature view operations @abstractmethod def apply_feature_view( - self, feature_view: BaseFeatureView, project: str, commit: bool = True + self, + feature_view: BaseFeatureView, + project: str, + commit: bool = True, + no_promote: bool = False, ): """ Registers a single feature view with Feast @@ -264,6 +270,9 @@ def apply_feature_view( feature_view: Feature view that will be registered project: Feast project that this feature view belongs to commit: Whether the change should be persisted immediately + no_promote: If True, save a new version snapshot without promoting + it to the active definition. The new version is accessible only + via explicit @v reads. """ raise NotImplementedError @@ -292,15 +301,32 @@ def _check_conflict(getter, not_found_exc, existing_type: str): # Check StreamFeatureView before FeatureView since StreamFeatureView is a subclass # Note: All getters raise FeatureViewNotFoundException (not type-specific exceptions) - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): _check_conflict( self.get_feature_view, FeatureViewNotFoundException, "FeatureView" ) + _check_conflict( + self.get_stream_feature_view, + FeatureViewNotFoundException, + "StreamFeatureView", + ) _check_conflict( self.get_on_demand_feature_view, FeatureViewNotFoundException, "OnDemandFeatureView", ) + elif isinstance(feature_view, StreamFeatureView): + _check_conflict( + self.get_feature_view, FeatureViewNotFoundException, "FeatureView" + ) + _check_conflict( + self.get_on_demand_feature_view, + FeatureViewNotFoundException, + "OnDemandFeatureView", + ) + _check_conflict( + self.get_label_view, FeatureViewNotFoundException, "LabelView" + ) elif isinstance(feature_view, FeatureView): _check_conflict( self.get_stream_feature_view, @@ -312,6 +338,9 @@ def _check_conflict(getter, not_found_exc, existing_type: str): FeatureViewNotFoundException, "OnDemandFeatureView", ) + _check_conflict( + self.get_label_view, FeatureViewNotFoundException, "LabelView" + ) elif isinstance(feature_view, OnDemandFeatureView): _check_conflict( self.get_feature_view, FeatureViewNotFoundException, "FeatureView" @@ -321,6 +350,9 @@ def _check_conflict(getter, not_found_exc, existing_type: str): FeatureViewNotFoundException, "StreamFeatureView", ) + _check_conflict( + self.get_label_view, FeatureViewNotFoundException, "LabelView" + ) @abstractmethod def delete_feature_view(self, name: str, project: str, commit: bool = True): @@ -361,6 +393,7 @@ def list_stream_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[StreamFeatureView]: """ Retrieve a list of stream feature views from the registry @@ -369,6 +402,7 @@ def list_stream_feature_views( project: Filter stream feature views based on project name allow_cache: Whether to allow returning stream feature views from a cached registry tags: Filter by tags + skip_udf: Skip deserializing UDFs (for metadata-only operations) Returns: List of stream feature views @@ -400,6 +434,7 @@ def list_on_demand_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: """ Retrieve a list of on demand feature views from the registry @@ -408,12 +443,64 @@ def list_on_demand_feature_views( project: Filter on demand feature views based on project name allow_cache: Whether to allow returning on demand feature views from a cached registry tags: Filter by tags + skip_udf: Skip deserializing UDFs (for metadata-only operations) Returns: List of on demand feature views """ raise NotImplementedError + # Label view operations + @abstractmethod + def get_label_view( + self, name: str, project: str, allow_cache: bool = False + ) -> LabelView: + """ + Retrieves a label view. + + Args: + name: Name of label view + project: Feast project that this label view belongs to + allow_cache: Whether to allow returning this label view from a cached registry + + Returns: + Returns either the specified label view, or raises an exception if + none is found + """ + raise NotImplementedError + + @abstractmethod + def list_label_views( + self, + project: str, + allow_cache: bool = False, + tags: Optional[dict[str, str]] = None, + ) -> List[LabelView]: + """ + Retrieve a list of label views from the registry + + Args: + project: Filter label views based on project name + allow_cache: Whether to allow returning label views from a cached registry + tags: Filter by tags + + Returns: + List of label views + """ + raise NotImplementedError + + @abstractmethod + def delete_label_view(self, name: str, project: str, commit: bool = True): + """ + Deletes a label view or raises an exception if not found. + + Args: + name: Name of label view + project: Feast project that this label view belongs to + commit: Whether the change should be persisted immediately + """ + raise NotImplementedError + # regular feature view operations @abstractmethod def get_feature_view( @@ -439,6 +526,7 @@ def list_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[FeatureView]: """ Retrieve a list of feature views from the registry @@ -447,6 +535,7 @@ def list_feature_views( allow_cache: Allow returning feature views from the cached registry project: Filter feature views based on project name tags: Filter by tags + skip_udf: Skip deserializing UDFs (for metadata-only operations) Returns: List of feature views @@ -477,6 +566,7 @@ def list_all_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[BaseFeatureView]: """ Retrieve a list of feature views of all types from the registry @@ -485,16 +575,57 @@ def list_all_feature_views( allow_cache: Allow returning feature views from the cached registry project: Filter feature views based on project name tags: Filter by tags + skip_udf: Skip deserializing UDFs (for metadata-only operations) Returns: List of feature views """ raise NotImplementedError + def list_feature_view_versions( + self, name: str, project: str + ) -> List[Dict[str, Any]]: + """ + List version history for a feature view. + + Args: + name: Name of feature view + project: Feast project that this feature view belongs to + + Returns: + List of version records with version, version_number, feature_view_type, + created_timestamp, and version_id. + """ + raise NotImplementedError( + "list_feature_view_versions is not implemented for this registry" + ) + + def get_feature_view_by_version( + self, name: str, project: str, version_number: int, allow_cache: bool = False + ) -> BaseFeatureView: + """ + Retrieve a feature view snapshot for a specific version number. + + Args: + name: Name of feature view + project: Feast project that this feature view belongs to + version_number: The version number to retrieve + allow_cache: Whether to allow returning from a cached registry + + Returns: + The feature view snapshot at the specified version. + + Raises: + FeatureViewVersionNotFound: if the version doesn't exist. + """ + raise NotImplementedError( + "get_feature_view_by_version is not implemented for this registry" + ) + @abstractmethod def apply_materialization( self, - feature_view: Union[FeatureView, OnDemandFeatureView], + feature_view: Union[FeatureView, OnDemandFeatureView, "LabelView"], project: str, start_date: datetime, end_date: datetime, @@ -864,6 +995,16 @@ def refresh(self, project: Optional[str] = None): """Refreshes the state of the registry cache by fetching the registry state from the remote registry store.""" raise NotImplementedError + def is_cache_valid(self) -> bool: + """Check whether the registry's local cache is still within its TTL. + + Returns True if cached data can be used without a refresh. + Subclasses that support caching should override this. + Registries without caching always return False (every read goes + to the backing store). + """ + return False + # Lineage operations def get_registry_lineage( self, @@ -993,6 +1134,11 @@ def _build_registry_proto( for on_demand_feature_view in on_demand_feature_views: registry.on_demand_feature_views.append(on_demand_feature_view.to_proto()) + # Add all label views + label_views = self.list_label_views(project=project, allow_cache=allow_cache) + for label_view in label_views: + registry.label_views.append(label_view.to_proto()) + # Add all feature services feature_services = self.list_feature_services( project=project, allow_cache=allow_cache @@ -1096,6 +1242,13 @@ def to_dict(self, project: str) -> Dict[str, List[Any]]: ) registry_dict["streamFeatureViews"].append(sfv_dict) + for label_view in sorted( + self.list_label_views(project=project), + key=lambda lv: lv.name, + ): + registry_dict["labelViews"].append( + self._message_to_sorted_dict(label_view.to_proto()) + ) for saved_dataset in sorted( self.list_saved_datasets(project=project), key=lambda item: item.name ): @@ -1127,6 +1280,8 @@ def deserialize_registry_values(serialized_proto, feast_obj_type) -> Any: return StreamFeatureViewProto.FromString(serialized_proto) if feast_obj_type == OnDemandFeatureView: return OnDemandFeatureViewProto.FromString(serialized_proto) + if feast_obj_type == LabelView: + return LabelViewProto.FromString(serialized_proto) if feast_obj_type == FeatureService: return FeatureServiceProto.FromString(serialized_proto) if feast_obj_type == Permission: diff --git a/sdk/python/feast/infra/registry/caching_registry.py b/sdk/python/feast/infra/registry/caching_registry.py index ce346272af9..d7a1f742d6e 100644 --- a/sdk/python/feast/infra/registry/caching_registry.py +++ b/sdk/python/feast/infra/registry/caching_registry.py @@ -5,7 +5,7 @@ from abc import abstractmethod from datetime import timedelta from threading import Lock -from typing import List, Optional +from typing import Any, Dict, List, Optional from feast.base_feature_view import BaseFeatureView from feast.data_source import DataSource @@ -15,6 +15,7 @@ from feast.infra.infra_object import Infra from feast.infra.registry import proto_registry_utils from feast.infra.registry.base_registry import BaseRegistry +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -121,7 +122,7 @@ def get_any_feature_view( @abstractmethod def _list_all_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs: Any ) -> List[BaseFeatureView]: pass @@ -130,13 +131,14 @@ def list_all_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[BaseFeatureView]: if allow_cache: self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_all_feature_views( - self.cached_registry_proto, project, tags + self.cached_registry_proto, project, tags, skip_udf=skip_udf ) - return self._list_all_feature_views(project, tags) + return self._list_all_feature_views(project, tags, skip_udf=skip_udf) @abstractmethod def _get_feature_view(self, name: str, project: str) -> FeatureView: @@ -154,7 +156,7 @@ def get_feature_view( @abstractmethod def _list_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs: Any ) -> List[FeatureView]: pass @@ -163,13 +165,14 @@ def list_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[FeatureView]: if allow_cache: self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_feature_views( - self.cached_registry_proto, project, tags + self.cached_registry_proto, project, tags, skip_udf=skip_udf ) - return self._list_feature_views(project, tags) + return self._list_feature_views(project, tags, skip_udf=skip_udf) @abstractmethod def _get_on_demand_feature_view( @@ -189,7 +192,7 @@ def get_on_demand_feature_view( @abstractmethod def _list_on_demand_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs: Any ) -> List[OnDemandFeatureView]: pass @@ -198,13 +201,14 @@ def list_on_demand_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: if allow_cache: self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_on_demand_feature_views( - self.cached_registry_proto, project, tags + self.cached_registry_proto, project, tags, skip_udf=skip_udf ) - return self._list_on_demand_feature_views(project, tags) + return self._list_on_demand_feature_views(project, tags, skip_udf=skip_udf) @abstractmethod def _get_stream_feature_view(self, name: str, project: str) -> StreamFeatureView: @@ -222,7 +226,7 @@ def get_stream_feature_view( @abstractmethod def _list_stream_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs: Any ) -> List[StreamFeatureView]: pass @@ -231,13 +235,47 @@ def list_stream_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[StreamFeatureView]: if allow_cache: self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_stream_feature_views( + self.cached_registry_proto, project, tags, skip_udf=skip_udf + ) + return self._list_stream_feature_views(project, tags, skip_udf=skip_udf) + + @abstractmethod + def _get_label_view(self, name: str, project: str) -> LabelView: + pass + + def get_label_view( + self, name: str, project: str, allow_cache: bool = False + ) -> LabelView: + if allow_cache: + self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_label_view( + self.cached_registry_proto, name, project + ) + return self._get_label_view(name, project) + + @abstractmethod + def _list_label_views( + self, project: str, tags: Optional[dict[str, str]], **kwargs: Any + ) -> List[LabelView]: + pass + + def list_label_views( + self, + project: str, + allow_cache: bool = False, + tags: Optional[dict[str, str]] = None, + ) -> List[LabelView]: + if allow_cache: + self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_label_views( self.cached_registry_proto, project, tags ) - return self._list_stream_feature_views(project, tags) + return self._list_label_views(project, tags) @abstractmethod def _get_feature_service(self, name: str, project: str) -> FeatureService: @@ -424,6 +462,13 @@ def list_projects( return proto_registry_utils.list_projects(self.cached_registry_proto, tags) return self._list_projects(tags) + def list_feature_view_versions( + self, name: str, project: str + ) -> List[Dict[str, Any]]: + raise NotImplementedError( + "list_feature_view_versions is not implemented for this registry" + ) + def refresh(self, project: Optional[str] = None): try: self.cached_registry_proto = self.proto() @@ -431,32 +476,26 @@ def refresh(self, project: Optional[str] = None): except Exception as e: logger.debug(f"Error while refreshing registry: {e}", exc_info=True) + def is_cache_valid(self) -> bool: + if ( + self.cached_registry_proto is None + or self.cached_registry_proto == RegistryProto() + ): + return False + if ( + not hasattr(self, "cached_registry_proto_created") + or self.cached_registry_proto_created is None + ): + return False + if self.cached_registry_proto_ttl.total_seconds() > 0 and _utc_now() > ( + self.cached_registry_proto_created + self.cached_registry_proto_ttl + ): + return False + return True + def _refresh_cached_registry_if_necessary(self): if self.cache_mode == "sync": - - def is_cache_expired(): - if ( - self.cached_registry_proto is None - or self.cached_registry_proto == RegistryProto() - ): - return True - - # Cache is expired if creation time is None - if ( - not hasattr(self, "cached_registry_proto_created") - or self.cached_registry_proto_created is None - ): - return True - - # Cache is expired if TTL > 0 and current time exceeds creation + TTL - if self.cached_registry_proto_ttl.total_seconds() > 0 and _utc_now() > ( - self.cached_registry_proto_created + self.cached_registry_proto_ttl - ): - return True - - return False - - if is_cache_expired(): + if not self.is_cache_valid(): if not self._refresh_lock.acquire(blocking=False): logger.debug( "Skipping refresh if lock is already held by another thread" diff --git a/sdk/python/feast/infra/registry/proto_registry_utils.py b/sdk/python/feast/infra/registry/proto_registry_utils.py index 26a5b7e1689..de5d199555b 100644 --- a/sdk/python/feast/infra/registry/proto_registry_utils.py +++ b/sdk/python/feast/infra/registry/proto_registry_utils.py @@ -10,6 +10,7 @@ EntityNotFoundException, FeatureServiceNotFoundException, FeatureViewNotFoundException, + FeatureViewVersionNotFound, PermissionObjectNotFoundException, ProjectObjectNotFoundException, SavedDatasetNotFound, @@ -17,6 +18,7 @@ ) from feast.feature_service import FeatureService from feast.feature_view import FeatureView +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -56,15 +58,19 @@ def wrapper( registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]], + **kwargs, ): nonlocal cache_key, cache_value - key = tuple([id(registry_proto), registry_proto.version_id, project, tags]) + kwargs_key = tuple(sorted(kwargs.items())) if kwargs else () + key = tuple( + [id(registry_proto), registry_proto.version_id, project, tags, kwargs_key] + ) if key == cache_key: return cache_value else: - cache_value = func(registry_proto, project, tags) + cache_value = func(registry_proto, project, tags, **kwargs) cache_key = key return cache_value @@ -144,9 +150,66 @@ def get_any_feature_view( ): return OnDemandFeatureView.from_proto(on_demand_feature_view) + for label_view_proto in registry_proto.label_views: + if ( + label_view_proto.spec.name == name + and label_view_proto.spec.project == project + ): + return LabelView.from_proto(label_view_proto) + raise FeatureViewNotFoundException(name, project) +def get_feature_view_by_version( + registry_proto: RegistryProto, name: str, project: str, version_number: int +) -> BaseFeatureView: + """Retrieve a feature view snapshot for a specific version from version history.""" + from feast.protos.feast.core.FeatureView_pb2 import ( + FeatureView as FeatureViewProto, + ) + from feast.protos.feast.core.LabelView_pb2 import ( + LabelView as LabelViewProto, + ) + from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( + OnDemandFeatureView as OnDemandFeatureViewProto, + ) + from feast.protos.feast.core.StreamFeatureView_pb2 import ( + StreamFeatureView as StreamFeatureViewProto, + ) + from feast.version_utils import version_tag + + for record in registry_proto.feature_view_version_history.records: + if ( + record.feature_view_name == name + and record.project_id == project + and record.version_number == version_number + ): + fv: BaseFeatureView + if record.feature_view_type == "feature_view": + fv_proto = FeatureViewProto.FromString(record.feature_view_proto) + fv = FeatureView.from_proto(fv_proto) + elif record.feature_view_type == "stream_feature_view": + sfv_proto = StreamFeatureViewProto.FromString(record.feature_view_proto) + fv = StreamFeatureView.from_proto(sfv_proto) + elif record.feature_view_type == "on_demand_feature_view": + odfv_proto = OnDemandFeatureViewProto.FromString( + record.feature_view_proto + ) + fv = OnDemandFeatureView.from_proto(odfv_proto) + elif record.feature_view_type == "label_view": + lv_proto = LabelViewProto.FromString(record.feature_view_proto) + fv = LabelView.from_proto(lv_proto) + else: + raise ValueError( + f"Unknown feature view type: {record.feature_view_type}" + ) + + fv.current_version_number = version_number + return fv + + raise FeatureViewVersionNotFound(name, version_tag(version_number), project) + + def get_feature_view( registry_proto: RegistryProto, name: str, project: str ) -> FeatureView: @@ -235,31 +298,43 @@ def list_feature_services( @registry_proto_cache_with_tags def list_all_feature_views( - registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] + registry_proto: RegistryProto, + project: str, + tags: Optional[dict[str, str]], + skip_udf: bool = False, ) -> List[BaseFeatureView]: return ( - list_feature_views(registry_proto, project, tags) - + list_stream_feature_views(registry_proto, project, tags) - + list_on_demand_feature_views(registry_proto, project, tags) + list_feature_views(registry_proto, project, tags, skip_udf=skip_udf) + + list_stream_feature_views(registry_proto, project, tags, skip_udf=skip_udf) + + list_on_demand_feature_views(registry_proto, project, tags, skip_udf=skip_udf) + + list_label_views(registry_proto, project, tags) ) @registry_proto_cache_with_tags def list_feature_views( - registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] + registry_proto: RegistryProto, + project: str, + tags: Optional[dict[str, str]], + skip_udf: bool = False, ) -> List[FeatureView]: feature_views: List[FeatureView] = [] for feature_view_proto in registry_proto.feature_views: if feature_view_proto.spec.project == project and utils.has_all_tags( feature_view_proto.spec.tags, tags ): - feature_views.append(FeatureView.from_proto(feature_view_proto)) + feature_views.append( + FeatureView.from_proto(feature_view_proto, skip_udf=skip_udf) + ) return feature_views @registry_proto_cache_with_tags def list_stream_feature_views( - registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] + registry_proto: RegistryProto, + project: str, + tags: Optional[dict[str, str]], + skip_udf: bool = False, ) -> List[StreamFeatureView]: stream_feature_views = [] for stream_feature_view in registry_proto.stream_feature_views: @@ -267,14 +342,17 @@ def list_stream_feature_views( stream_feature_view.spec.tags, tags ): stream_feature_views.append( - StreamFeatureView.from_proto(stream_feature_view) + StreamFeatureView.from_proto(stream_feature_view, skip_udf=skip_udf) ) return stream_feature_views @registry_proto_cache_with_tags def list_on_demand_feature_views( - registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] + registry_proto: RegistryProto, + project: str, + tags: Optional[dict[str, str]], + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: on_demand_feature_views = [] for on_demand_feature_view in registry_proto.on_demand_feature_views: @@ -282,11 +360,36 @@ def list_on_demand_feature_views( on_demand_feature_view.spec.tags, tags ): on_demand_feature_views.append( - OnDemandFeatureView.from_proto(on_demand_feature_view) + OnDemandFeatureView.from_proto( + on_demand_feature_view, skip_udf=skip_udf + ) ) return on_demand_feature_views +def get_label_view(registry_proto: RegistryProto, name: str, project: str) -> LabelView: + for label_view_proto in registry_proto.label_views: + if ( + label_view_proto.spec.name == name + and label_view_proto.spec.project == project + ): + return LabelView.from_proto(label_view_proto) + raise FeatureViewNotFoundException(name, project) + + +@registry_proto_cache_with_tags +def list_label_views( + registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] +) -> List[LabelView]: + label_views = [] + for label_view_proto in registry_proto.label_views: + if label_view_proto.spec.project == project and utils.has_all_tags( + label_view_proto.spec.tags, tags + ): + label_views.append(LabelView.from_proto(label_view_proto)) + return label_views + + @registry_proto_cache_with_tags def list_entities( registry_proto: RegistryProto, project: str, tags: Optional[dict[str, str]] diff --git a/sdk/python/feast/infra/registry/registry.py b/sdk/python/feast/infra/registry/registry.py index ff9c1f405a1..b5066a51836 100644 --- a/sdk/python/feast/infra/registry/registry.py +++ b/sdk/python/feast/infra/registry/registry.py @@ -31,29 +31,38 @@ EntityNotFoundException, FeatureServiceNotFoundException, FeatureViewNotFoundException, + FeatureViewPinConflict, + FeatureViewVersionNotFound, PermissionNotFoundException, ProjectNotFoundException, ProjectObjectNotFoundException, ValidationReferenceNotFound, ) from feast.feature_service import FeatureService -from feast.feature_view import FeatureView +from feast.feature_view import FeatureView, FeatureViewState from feast.importer import import_class from feast.infra.infra_object import Infra from feast.infra.registry import proto_registry_utils from feast.infra.registry.base_registry import BaseRegistry from feast.infra.registry.registry_store import NoopRegistryStore +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.auth_model import AuthConfig, NoAuthConfig from feast.permissions.permission import Permission from feast.project import Project from feast.project_metadata import ProjectMetadata +from feast.protos.feast.core.FeatureViewVersion_pb2 import FeatureViewVersionRecord from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto from feast.repo_config import RegistryConfig from feast.repo_contents import RepoContents from feast.saved_dataset import SavedDataset, ValidationReference from feast.stream_feature_view import StreamFeatureView from feast.utils import _utc_now +from feast.version_utils import ( + generate_version_id, + parse_version, + version_tag, +) REGISTRY_SCHEMA_VERSION = "1" @@ -81,6 +90,7 @@ class FeastObjectType(Enum): FEATURE_VIEW = "feature view" ON_DEMAND_FEATURE_VIEW = "on demand feature view" STREAM_FEATURE_VIEW = "stream feature view" + LABEL_VIEW = "label view" FEATURE_SERVICE = "feature service" PERMISSION = "permission" @@ -103,6 +113,7 @@ def get_objects_from_registry( FeastObjectType.STREAM_FEATURE_VIEW: registry.list_stream_feature_views( project=project, ), + FeastObjectType.LABEL_VIEW: registry.list_label_views(project=project), FeastObjectType.FEATURE_SERVICE: registry.list_feature_services( project=project ), @@ -120,6 +131,7 @@ def get_objects_from_repo_contents( FeastObjectType.FEATURE_VIEW: repo_contents.feature_views, FeastObjectType.ON_DEMAND_FEATURE_VIEW: repo_contents.on_demand_feature_views, FeastObjectType.STREAM_FEATURE_VIEW: repo_contents.stream_feature_views, + FeastObjectType.LABEL_VIEW: repo_contents.label_views, FeastObjectType.FEATURE_SERVICE: repo_contents.feature_services, FeastObjectType.PERMISSION: repo_contents.permissions, } @@ -221,6 +233,12 @@ def __init__( else False ) + self.enable_online_versioning = ( + registry_config.enable_online_feature_view_versioning + if registry_config is not None + else False + ) + self.cache_mode = ( registry_config.cache_mode if registry_config is not None else "sync" ) @@ -372,6 +390,12 @@ def list_data_sources( def apply_data_source( self, data_source: DataSource, project: str, commit: bool = True ): + """Apply a data source to the registry with project-scoped deduplication. + + Filters existing data sources by both name and project (fixes feast-dev/feast#6206), + preserving the original created_timestamp if the source already exists in the + target project. + """ now = _utc_now() if not data_source.created_timestamp: data_source.created_timestamp = now @@ -380,7 +404,10 @@ def apply_data_source( registry = self._prepare_registry_for_changes(project) for idx, existing_data_source_proto in enumerate(registry.data_sources): - if existing_data_source_proto.name == data_source.name: + if ( + existing_data_source_proto.name == data_source.name + and existing_data_source_proto.project == project + ): existing_data_source = DataSource.from_proto(existing_data_source_proto) # Check if the data source has actually changed if existing_data_source == data_source: @@ -409,7 +436,7 @@ def delete_data_source(self, name: str, project: str, commit: bool = True): for idx, data_source_proto in enumerate( self.cached_registry_proto.data_sources ): - if data_source_proto.name == name: + if data_source_proto.name == name and data_source_proto.project == project: del self.cached_registry_proto.data_sources[idx] if commit: self.commit() @@ -470,8 +497,242 @@ def get_entity(self, name: str, project: str, allow_cache: bool = False) -> Enti ) return proto_registry_utils.get_entity(registry_proto, name, project) + def _infer_fv_type_string(self, feature_view) -> str: + if isinstance(feature_view, LabelView): + return "label_view" + elif isinstance(feature_view, StreamFeatureView): + return "stream_feature_view" + elif isinstance(feature_view, FeatureView): + return "feature_view" + elif isinstance(feature_view, OnDemandFeatureView): + return "on_demand_feature_view" + else: + raise ValueError(f"Unexpected feature view type: {type(feature_view)}") + + def _proto_class_for_type(self, fv_type: str): + from feast.protos.feast.core.FeatureView_pb2 import ( + FeatureView as FeatureViewProto, + ) + from feast.protos.feast.core.LabelView_pb2 import ( + LabelView as LabelViewProto, + ) + from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( + OnDemandFeatureView as OnDemandFeatureViewProto, + ) + from feast.protos.feast.core.StreamFeatureView_pb2 import ( + StreamFeatureView as StreamFeatureViewProto, + ) + + if fv_type == "label_view": + return LabelViewProto, LabelView + elif fv_type == "stream_feature_view": + return StreamFeatureViewProto, StreamFeatureView + elif fv_type == "feature_view": + return FeatureViewProto, FeatureView + elif fv_type == "on_demand_feature_view": + return OnDemandFeatureViewProto, OnDemandFeatureView + else: + raise ValueError(f"Unknown feature view type: {fv_type}") + + def _next_version_number(self, name: str, project: str) -> int: + history = self.cached_registry_proto.feature_view_version_history + max_ver = -1 + for record in history.records: + if record.feature_view_name == name and record.project_id == project: + if record.version_number > max_ver: + max_ver = record.version_number + return max_ver + 1 + + def _get_version_record( + self, name: str, project: str, version_number: int + ) -> Optional[FeatureViewVersionRecord]: + history = self.cached_registry_proto.feature_view_version_history + for record in history.records: + if ( + record.feature_view_name == name + and record.project_id == project + and record.version_number == version_number + ): + return record + return None + + def _update_metadata_fields( + self, existing_proto: Any, updated_fv: BaseFeatureView + ) -> None: + """Update non-version-significant fields without creating new version.""" + from feast.feature_view import FeatureView + from feast.labeling.label_view import LabelView + + # Metadata fields + existing_proto.spec.description = updated_fv.description + existing_proto.spec.tags.clear() + existing_proto.spec.tags.update(updated_fv.tags) + existing_proto.spec.owner = updated_fv.owner + if hasattr(existing_proto.spec, "version") and hasattr(updated_fv, "version"): + existing_proto.spec.version = getattr(updated_fv, "version") + + # Configuration fields (FeatureView / LabelView TTL) + if ( + hasattr(existing_proto.spec, "ttl") + and hasattr(updated_fv, "ttl") + and updated_fv.ttl + ): + if isinstance(updated_fv, FeatureView): + ttl_duration = updated_fv.get_ttl_duration() + if ttl_duration: + existing_proto.spec.ttl.CopyFrom(ttl_duration) + elif isinstance(updated_fv, LabelView): + from google.protobuf.duration_pb2 import Duration + + ttl_duration = Duration() + ttl_duration.FromTimedelta(updated_fv.ttl) + existing_proto.spec.ttl.CopyFrom(ttl_duration) + if hasattr(existing_proto.spec, "online") and hasattr(updated_fv, "online"): + existing_proto.spec.online = getattr(updated_fv, "online") + if hasattr(existing_proto.spec, "offline") and hasattr(updated_fv, "offline"): + existing_proto.spec.offline = getattr(updated_fv, "offline") + if hasattr(existing_proto.spec, "enable_validation") and hasattr( + updated_fv, "enable_validation" + ): + existing_proto.spec.enable_validation = getattr( + updated_fv, "enable_validation" + ) + + # Enabled/disabled state + if hasattr(existing_proto.spec, "disabled") and hasattr(updated_fv, "enabled"): + existing_proto.spec.disabled = not getattr(updated_fv, "enabled") + + # Lifecycle state — skip STATE_UNSPECIFIED so that ``feast apply`` + # does not accidentally reset an AVAILABLE_ONLINE view. + if hasattr(existing_proto.meta, "state") and hasattr(updated_fv, "state"): + state_val = getattr(updated_fv, "state") + if ( + isinstance(state_val, FeatureViewState) + and state_val != FeatureViewState.STATE_UNSPECIFIED + ): + existing_proto.meta.state = state_val.to_proto() + + # OnDemandFeatureView configuration + if hasattr(existing_proto.spec, "write_to_online_store") and hasattr( + updated_fv, "write_to_online_store" + ): + existing_proto.spec.write_to_online_store = getattr( + updated_fv, "write_to_online_store" + ) + if hasattr(existing_proto.spec, "singleton") and hasattr( + updated_fv, "singleton" + ): + existing_proto.spec.singleton = getattr(updated_fv, "singleton") + + # LabelView-specific configuration + if hasattr(existing_proto.spec, "labeler_field") and hasattr( + updated_fv, "labeler_field" + ): + existing_proto.spec.labeler_field = updated_fv.labeler_field + if hasattr(existing_proto.spec, "conflict_policy") and hasattr( + updated_fv, "conflict_policy" + ): + existing_proto.spec.conflict_policy = updated_fv.conflict_policy.to_proto() + + if hasattr(existing_proto.spec, "reference_feature_view") and hasattr( + updated_fv, "reference_feature_view" + ): + existing_proto.spec.reference_feature_view = ( + updated_fv.reference_feature_view or "" + ) + + # Data sources (treat as configuration) + if ( + hasattr(existing_proto.spec, "batch_source") + and hasattr(updated_fv, "batch_source") + and updated_fv.batch_source + ): + existing_proto.spec.batch_source.CopyFrom( + updated_fv.batch_source.to_proto() + ) + if ( + hasattr(existing_proto.spec, "stream_source") + and hasattr(updated_fv, "stream_source") + and updated_fv.stream_source + ): + existing_proto.spec.stream_source.CopyFrom( + updated_fv.stream_source.to_proto() + ) + + # Update or clear version pin + if hasattr(existing_proto.meta, "current_version_number") and hasattr( + updated_fv, "current_version_number" + ): + if updated_fv.current_version_number is not None: + existing_proto.meta.current_version_number = ( + updated_fv.current_version_number + ) + else: + # Unpin: reset to proto default (0). + # from_proto interprets cvn=0 with spec.version="latest" as None. + existing_proto.meta.current_version_number = 0 + + # Update timestamp + existing_proto.meta.last_updated_timestamp.FromDatetime(_utc_now()) + + def _save_version_record( + self, + name: str, + project: str, + version_number: int, + fv_type: str, + proto_bytes: bytes, + ): + now = _utc_now() + record = FeatureViewVersionRecord( + feature_view_name=name, + project_id=project, + version_number=version_number, + feature_view_type=fv_type, + feature_view_proto=proto_bytes, + description="", + version_id=generate_version_id(), + ) + record.created_timestamp.FromDatetime(now) + self.cached_registry_proto.feature_view_version_history.records.append(record) + + def list_feature_view_versions( + self, name: str, project: str + ) -> List[Dict[str, Any]]: + history = self.cached_registry_proto.feature_view_version_history + results = [] + for record in history.records: + if record.feature_view_name == name and record.project_id == project: + results.append( + { + "version": version_tag(record.version_number), + "version_number": record.version_number, + "feature_view_type": record.feature_view_type, + "created_timestamp": record.created_timestamp.ToDatetime(), + "version_id": record.version_id, + } + ) + results.sort(key=lambda r: r["version_number"]) + return results + + def get_feature_view_by_version( + self, name: str, project: str, version_number: int, allow_cache: bool = False + ) -> BaseFeatureView: + record = self._get_version_record(name, project, version_number) + if record is None: + raise FeatureViewVersionNotFound(name, version_tag(version_number), project) + proto_class, python_class = self._proto_class_for_type(record.feature_view_type) + snap_proto = proto_class.FromString(record.feature_view_proto) + fv = python_class.from_proto(snap_proto) + fv.current_version_number = version_number + return fv + def apply_feature_view( - self, feature_view: BaseFeatureView, project: str, commit: bool = True + self, + feature_view: BaseFeatureView, + project: str, + commit: bool = True, + no_promote: bool = False, ): feature_view.ensure_valid() @@ -480,14 +741,83 @@ def apply_feature_view( feature_view.created_timestamp = now feature_view.last_updated_timestamp = now + fv_type_str = self._infer_fv_type_string(feature_view) + is_latest, pin_version = parse_version(feature_view.version) + + if not is_latest: + # Explicit version: check if it exists (pin/revert) or not (forward declaration). + # Note: The file registry is last-write-wins for true concurrent races — + # this is a pre-existing limitation for all file registry operations. + # For multi-client environments, use the SQL registry. + record = self._get_version_record(feature_view.name, project, pin_version) + + if record is not None: + # Version exists → pin/revert to that snapshot + # Check that the user hasn't also modified the definition. + # Compare user's FV (with version="latest") against active FV. + self._prepare_registry_for_changes(project) + try: + active_fv = proto_registry_utils.get_any_feature_view( + self.cached_registry_proto, feature_view.name, project + ) + user_fv_copy = feature_view.__copy__() + user_fv_copy.version = "latest" + active_fv.version = "latest" + # Clear metadata that differs due to registry state + user_fv_copy.created_timestamp = active_fv.created_timestamp + user_fv_copy.last_updated_timestamp = ( + active_fv.last_updated_timestamp + ) + user_fv_copy.current_version_number = ( + active_fv.current_version_number + ) + if hasattr(active_fv, "materialization_intervals"): + user_fv_copy.materialization_intervals = ( + active_fv.materialization_intervals + ) + if user_fv_copy != active_fv: + raise FeatureViewPinConflict( + feature_view.name, version_tag(pin_version) + ) + except FeatureViewNotFoundException: + pass + + proto_class, python_class = self._proto_class_for_type( + record.feature_view_type + ) + snap_proto = proto_class.FromString(record.feature_view_proto) + restored_fv = python_class.from_proto(snap_proto) + restored_fv.version = feature_view.version + restored_fv.current_version_number = pin_version + restored_fv.last_updated_timestamp = now + # Apply the restored FV using the standard path below + feature_view = restored_fv + else: + # Version doesn't exist → forward declaration: create it + feature_view.current_version_number = pin_version + feature_view_proto = feature_view.to_proto() + feature_view_proto.spec.project = project + snapshot_proto_bytes = feature_view_proto.SerializeToString() + self._prepare_registry_for_changes(project) + self._save_version_record( + feature_view.name, + project, + pin_version, + fv_type_str, + snapshot_proto_bytes, + ) + # Fall through to apply the FV as active (with current_version_number set) + feature_view_proto = feature_view.to_proto() feature_view_proto.spec.project = project self._prepare_registry_for_changes(project) assert self.cached_registry_proto - self._check_conflicting_feature_view_names(feature_view) + self._check_conflicting_feature_view_names(feature_view, project) existing_feature_views_of_same_type: RepeatedCompositeFieldContainer - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + existing_feature_views_of_same_type = self.cached_registry_proto.label_views + elif isinstance(feature_view, StreamFeatureView): existing_feature_views_of_same_type = ( self.cached_registry_proto.stream_feature_views ) @@ -502,6 +832,7 @@ def apply_feature_view( else: raise ValueError(f"Unexpected feature view type: {type(feature_view)}") + old_proto_bytes = None for idx, existing_feature_view_proto in enumerate( existing_feature_views_of_same_type ): @@ -509,12 +840,22 @@ def apply_feature_view( existing_feature_view_proto.spec.name == feature_view_proto.spec.name and existing_feature_view_proto.spec.project == project ): - if ( - feature_view.__class__.from_proto(existing_feature_view_proto) - == feature_view - ): + existing_feature_view = feature_view.__class__.from_proto( + existing_feature_view_proto + ) + if not feature_view._schema_or_udf_changed(existing_feature_view): + # Update non-version-significant fields in place + self._update_metadata_fields( + existing_feature_view_proto, feature_view + ) + if commit: + self.commit() return else: + old_proto_bytes = existing_feature_view_proto.SerializeToString() + # Save a copy before deletion for no_promote restore + existing_proto_copy = type(existing_feature_view_proto)() + existing_proto_copy.CopyFrom(existing_feature_view_proto) existing_feature_view = type(feature_view).from_proto( existing_feature_view_proto ) @@ -530,6 +871,54 @@ def apply_feature_view( del existing_feature_views_of_same_type[idx] break + # Version history tracking + if is_latest: + if old_proto_bytes is not None: + # FV changed: save old as a version if first time, then save new + next_ver = self._next_version_number(feature_view.name, project) + if next_ver == 0: + self._save_version_record( + feature_view.name, project, 0, fv_type_str, old_proto_bytes + ) + next_ver = 1 + + if no_promote: + # Save version snapshot but keep the old active definition + no_promote_fv = feature_view.__copy__() + no_promote_fv.current_version_number = next_ver + no_promote_proto = no_promote_fv.to_proto() + no_promote_proto.spec.project = project + no_promote_proto_bytes = no_promote_proto.SerializeToString() + self._save_version_record( + feature_view.name, + project, + next_ver, + fv_type_str, + no_promote_proto_bytes, + ) + # Re-insert the old active definition (was deleted above) + existing_feature_views_of_same_type.append(existing_proto_copy) + if commit: + self.commit() + return + + feature_view.current_version_number = next_ver + feature_view_proto = feature_view.to_proto() + feature_view_proto.spec.project = project + new_proto_bytes = feature_view_proto.SerializeToString() + self._save_version_record( + feature_view.name, project, next_ver, fv_type_str, new_proto_bytes + ) + else: + # New FV: save as v0 + feature_view.current_version_number = 0 + feature_view_proto = feature_view.to_proto() + feature_view_proto.spec.project = project + new_proto_bytes = feature_view_proto.SerializeToString() + self._save_version_record( + feature_view.name, project, 0, fv_type_str, new_proto_bytes + ) + existing_feature_views_of_same_type.append(feature_view_proto) if commit: self.commit() @@ -539,12 +928,13 @@ def list_stream_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[StreamFeatureView]: registry_proto = self._get_registry_proto( project=project, allow_cache=allow_cache ) return proto_registry_utils.list_stream_feature_views( - registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) def list_on_demand_feature_views( @@ -552,12 +942,13 @@ def list_on_demand_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: registry_proto = self._get_registry_proto( project=project, allow_cache=allow_cache ) return proto_registry_utils.list_on_demand_feature_views( - registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) def get_on_demand_feature_view( @@ -570,6 +961,42 @@ def get_on_demand_feature_view( registry_proto, name, project ) + def list_label_views( + self, + project: str, + allow_cache: bool = False, + tags: Optional[dict[str, str]] = None, + ) -> List[LabelView]: + registry_proto = self._get_registry_proto( + project=project, allow_cache=allow_cache + ) + return proto_registry_utils.list_label_views(registry_proto, project, tags) + + def get_label_view( + self, name: str, project: str, allow_cache: bool = False + ) -> LabelView: + registry_proto = self._get_registry_proto( + project=project, allow_cache=allow_cache + ) + return proto_registry_utils.get_label_view(registry_proto, name, project) + + def delete_label_view(self, name: str, project: str, commit: bool = True): + self._prepare_registry_for_changes(project) + assert self.cached_registry_proto + + for idx, existing_label_view_proto in enumerate( + self.cached_registry_proto.label_views + ): + if ( + existing_label_view_proto.spec.name == name + and existing_label_view_proto.spec.project == project + ): + del self.cached_registry_proto.label_views[idx] + if commit: + self.commit() + return + raise FeatureViewNotFoundException(name, project) + def get_data_source( self, name: str, project: str, allow_cache: bool = False ) -> DataSource: @@ -580,12 +1007,18 @@ def get_data_source( def apply_materialization( self, - feature_view: Union[FeatureView, OnDemandFeatureView], + feature_view: Union[FeatureView, OnDemandFeatureView, LabelView], project: str, start_date: datetime, end_date: datetime, commit: bool = True, ): + if isinstance(feature_view, LabelView): + raise ValueError( + f"Cannot apply materialization for LabelView {feature_view.name}. " + f"Use FeatureStore.push() to write labels." + ) + self._prepare_registry_for_changes(project) assert self.cached_registry_proto @@ -603,6 +1036,9 @@ def apply_materialization( (start_date, end_date) ) existing_feature_view.last_updated_timestamp = _utc_now() + # Transition state to AVAILABLE_ONLINE after materialization. + if hasattr(existing_feature_view, "state"): + existing_feature_view.state = FeatureViewState.AVAILABLE_ONLINE feature_view_proto = existing_feature_view.to_proto() feature_view_proto.spec.project = project del self.cached_registry_proto.feature_views[idx] @@ -625,6 +1061,11 @@ def apply_materialization( (start_date, end_date) ) existing_stream_feature_view.last_updated_timestamp = _utc_now() + # Transition state to AVAILABLE_ONLINE after materialization. + if hasattr(existing_stream_feature_view, "state"): + existing_stream_feature_view.state = ( + FeatureViewState.AVAILABLE_ONLINE + ) stream_feature_view_proto = existing_stream_feature_view.to_proto() stream_feature_view_proto.spec.project = project del self.cached_registry_proto.stream_feature_views[idx] @@ -640,12 +1081,13 @@ def list_all_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[BaseFeatureView]: registry_proto = self._get_registry_proto( project=project, allow_cache=allow_cache ) return proto_registry_utils.list_all_feature_views( - registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) def get_any_feature_view( @@ -661,11 +1103,14 @@ def list_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[FeatureView]: registry_proto = self._get_registry_proto( project=project, allow_cache=allow_cache ) - return proto_registry_utils.list_feature_views(registry_proto, project, tags) + return proto_registry_utils.list_feature_views( + registry_proto, project, tags, skip_udf=skip_udf + ) def get_feature_view( self, name: str, project: str, allow_cache: bool = False @@ -706,6 +1151,7 @@ def delete_feature_view(self, name: str, project: str, commit: bool = True): self._prepare_registry_for_changes(project) assert self.cached_registry_proto + found = False for idx, existing_feature_view_proto in enumerate( self.cached_registry_proto.feature_views ): @@ -714,35 +1160,60 @@ def delete_feature_view(self, name: str, project: str, commit: bool = True): and existing_feature_view_proto.spec.project == project ): del self.cached_registry_proto.feature_views[idx] - if commit: - self.commit() - return + found = True + break - for idx, existing_on_demand_feature_view_proto in enumerate( - self.cached_registry_proto.on_demand_feature_views - ): - if ( - existing_on_demand_feature_view_proto.spec.name == name - and existing_on_demand_feature_view_proto.spec.project == project + if not found: + for idx, existing_on_demand_feature_view_proto in enumerate( + self.cached_registry_proto.on_demand_feature_views ): - del self.cached_registry_proto.on_demand_feature_views[idx] - if commit: - self.commit() - return + if ( + existing_on_demand_feature_view_proto.spec.name == name + and existing_on_demand_feature_view_proto.spec.project == project + ): + del self.cached_registry_proto.on_demand_feature_views[idx] + found = True + break - for idx, existing_stream_feature_view_proto in enumerate( - self.cached_registry_proto.stream_feature_views - ): - if ( - existing_stream_feature_view_proto.spec.name == name - and existing_stream_feature_view_proto.spec.project == project + if not found: + for idx, existing_stream_feature_view_proto in enumerate( + self.cached_registry_proto.stream_feature_views ): - del self.cached_registry_proto.stream_feature_views[idx] - if commit: - self.commit() - return + if ( + existing_stream_feature_view_proto.spec.name == name + and existing_stream_feature_view_proto.spec.project == project + ): + del self.cached_registry_proto.stream_feature_views[idx] + found = True + break - raise FeatureViewNotFoundException(name, project) + if not found: + for idx, existing_label_view_proto in enumerate( + self.cached_registry_proto.label_views + ): + if ( + existing_label_view_proto.spec.name == name + and existing_label_view_proto.spec.project == project + ): + del self.cached_registry_proto.label_views[idx] + found = True + break + + if not found: + raise FeatureViewNotFoundException(name, project) + + # Clean up version history for the deleted feature view + history = self.cached_registry_proto.feature_view_version_history + indices_to_remove = [ + i + for i, record in enumerate(history.records) + if record.feature_view_name == name and record.project_id == project + ] + for i in reversed(indices_to_remove): + del history.records[i] + + if commit: + self.commit() def delete_entity(self, name: str, project: str, commit: bool = True): self._prepare_registry_for_changes(project) @@ -907,6 +1378,17 @@ def refresh(self, project: Optional[str] = None): """Refreshes the state of the registry cache by fetching the registry state from the remote registry store.""" self._get_registry_proto(project=project, allow_cache=False) + def is_cache_valid(self) -> bool: + if self.cached_registry_proto_created is None: + return False + if ( + self.cached_registry_proto_ttl.total_seconds() > 0 + and _utc_now() + > self.cached_registry_proto_created + self.cached_registry_proto_ttl + ): + return False + return True + def teardown(self): """Tears down (removes) the registry.""" self._registry_store.teardown() @@ -1008,25 +1490,35 @@ def _get_registry_proto( return registry_proto - def _check_conflicting_feature_view_names(self, feature_view: BaseFeatureView): - name_to_fv_protos = self._existing_feature_view_names_to_fvs() + def _check_conflicting_feature_view_names( + self, feature_view: BaseFeatureView, project: str + ): + name_to_fv_protos = self._existing_feature_view_names_to_fvs(project) if feature_view.name in name_to_fv_protos: if not isinstance( name_to_fv_protos.get(feature_view.name), feature_view.proto_class ): raise ConflictingFeatureViewNames(feature_view.name) - def _existing_feature_view_names_to_fvs(self) -> Dict[str, Message]: + def _existing_feature_view_names_to_fvs(self, project: str) -> Dict[str, Message]: assert self.cached_registry_proto odfvs = { fv.spec.name: fv for fv in self.cached_registry_proto.on_demand_feature_views + if fv.spec.project == project + } + fvs = { + fv.spec.name: fv + for fv in self.cached_registry_proto.feature_views + if fv.spec.project == project } - fvs = {fv.spec.name: fv for fv in self.cached_registry_proto.feature_views} sfv = { - fv.spec.name: fv for fv in self.cached_registry_proto.stream_feature_views + fv.spec.name: fv + for fv in self.cached_registry_proto.stream_feature_views + if fv.spec.project == project } - return {**odfvs, **fvs, **sfv} + lvs = {lv.spec.name: lv for lv in self.cached_registry_proto.label_views} + return {**odfvs, **fvs, **sfv, **lvs} def get_permission( self, name: str, project: str, allow_cache: bool = False @@ -1159,6 +1651,9 @@ def delete_project( for feature_view in list_feature_views: self.delete_feature_view(feature_view.name, name) + for lv in self.list_label_views(name): + self.delete_label_view(lv.name, name) + list_data_sources = self.list_data_sources(name) for data_source in list_data_sources: self.delete_data_source(data_source.name, name) diff --git a/sdk/python/feast/infra/registry/remote.py b/sdk/python/feast/infra/registry/remote.py index 8fc0db55c27..677183840ff 100644 --- a/sdk/python/feast/infra/registry/remote.py +++ b/sdk/python/feast/infra/registry/remote.py @@ -17,6 +17,7 @@ from feast.feature_view import FeatureView from feast.infra.infra_object import Infra from feast.infra.registry.base_registry import BaseRegistry +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.auth_model import AuthConfig, NoAuthConfig from feast.permissions.client.grpc_client_auth_interceptor import ( @@ -35,7 +36,10 @@ def extract_base_feature_view( any_feature_view: RegistryServer_pb2.AnyFeatureView, ) -> BaseFeatureView: + from feast.labeling.label_view import LabelView + feature_view_type = any_feature_view.WhichOneof("any_feature_view") + feature_view: BaseFeatureView if feature_view_type == "feature_view": feature_view = FeatureView.from_proto(any_feature_view.feature_view) elif feature_view_type == "on_demand_feature_view": @@ -46,6 +50,12 @@ def extract_base_feature_view( feature_view = StreamFeatureView.from_proto( any_feature_view.stream_feature_view ) + elif feature_view_type == "label_view": + feature_view = LabelView.from_proto(any_feature_view.label_view) + else: + raise ValueError( + f"Unexpected feature view type in AnyFeatureView: {feature_view_type}" + ) return feature_view @@ -64,10 +74,25 @@ class RemoteRegistryConfig(RegistryConfig): is_tls: bool = False """ bool: Set to `True` if you plan to connect to a registry server running in TLS (SSL) mode. - If you intend to add the public certificate to the trust store instead of passing it via the `cert` parameter, this field must be set to `True`. - If you are planning to add the public certificate as part of the trust store instead of passing it as a `cert` parameters then setting this field to `true` is mandatory. + If you are planning to add the public certificate as part of the trust store instead of passing it as a `cert` parameters then setting this field to `True` is mandatory. """ + client_cert: StrictStr = "" + """ str: Path to the client certificate for mTLS (mutual TLS) authentication. + Required when connecting to a server that enforces mutual TLS. + Must be provided together with `client_key`. + Typically this file ends with `*.crt` or `*.pem`. """ + + client_key: StrictStr = "" + """ str: Path to the client private key for mTLS (mutual TLS) authentication. + Must be provided together with `client_cert`. + Typically this file ends with `*.key` or `*.pem`. """ + + authority: StrictStr = "" + """ str: Override the gRPC :authority header for TLS connections. + Required when the connection address differs from the service hostname, + e.g. when connecting through a tunnel or proxy for local development. """ + class RemoteRegistry(BaseRegistry): def __init__( @@ -89,19 +114,45 @@ def __init__( def _create_grpc_channel(self, registry_config): assert isinstance(registry_config, RemoteRegistryConfig) if registry_config.cert or registry_config.is_tls: - cafile = os.getenv("SSL_CERT_FILE") or os.getenv("REQUESTS_CA_BUNDLE") - if not cafile and not registry_config.cert: + cafile = ( + registry_config.cert + or os.getenv("SSL_CERT_FILE") + or os.getenv("REQUESTS_CA_BUNDLE") + ) + if not cafile: raise EnvironmentError( "SSL_CERT_FILE or REQUESTS_CA_BUNDLE environment variable must be set to use secure TLS or set the cert parameter in feature_Store.yaml file under remote registry configuration." ) - with open( - registry_config.cert if registry_config.cert else cafile, "rb" - ) as cert_file: + if (registry_config.client_cert and not registry_config.client_key) or ( + not registry_config.client_cert and registry_config.client_key + ): + raise ValueError( + "Both client_cert and client_key must be provided for mTLS. " + "Only one was set in the remote registry configuration." + ) + + with open(cafile, "rb") as cert_file: trusted_certs = cert_file.read() + private_key: Optional[bytes] = None + certificate_chain: Optional[bytes] = None + if registry_config.client_cert and registry_config.client_key: + with open(registry_config.client_key, "rb") as key_file: + private_key = key_file.read() + with open(registry_config.client_cert, "rb") as cert_file: + certificate_chain = cert_file.read() tls_credentials = grpc.ssl_channel_credentials( - root_certificates=trusted_certs + root_certificates=trusted_certs, + private_key=private_key, + certificate_chain=certificate_chain, + ) + + options = [] + if registry_config.authority: + options.append(("grpc.default_authority", registry_config.authority)) + + return grpc.secure_channel( + registry_config.path, tls_credentials, options=options ) - return grpc.secure_channel(registry_config.path, tls_credentials) else: # Create an insecure gRPC channel return grpc.insecure_channel(registry_config.path) @@ -217,14 +268,22 @@ def list_feature_services( ] def apply_feature_view( - self, feature_view: BaseFeatureView, project: str, commit: bool = True + self, + feature_view: BaseFeatureView, + project: str, + commit: bool = True, + no_promote: bool = False, ): - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + arg_name = "label_view" + elif isinstance(feature_view, StreamFeatureView): arg_name = "stream_feature_view" elif isinstance(feature_view, FeatureView): arg_name = "feature_view" elif isinstance(feature_view, OnDemandFeatureView): arg_name = "on_demand_feature_view" + else: + raise ValueError(f"Unexpected feature view type: {type(feature_view)}") request = RegistryServer_pb2.ApplyFeatureViewRequest( feature_view=( @@ -238,6 +297,7 @@ def apply_feature_view( if arg_name == "on_demand_feature_view" else None ), + label_view=(feature_view.to_proto() if arg_name == "label_view" else None), project=project, commit=commit, ) @@ -264,6 +324,7 @@ def list_stream_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[StreamFeatureView]: request = RegistryServer_pb2.ListStreamFeatureViewsRequest( project=project, allow_cache=allow_cache, tags=tags @@ -288,6 +349,7 @@ def list_on_demand_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: request = RegistryServer_pb2.ListOnDemandFeatureViewsRequest( project=project, allow_cache=allow_cache, tags=tags @@ -298,6 +360,30 @@ def list_on_demand_feature_views( for on_demand_feature_view in response.on_demand_feature_views ] + def get_label_view( + self, name: str, project: str, allow_cache: bool = False + ) -> LabelView: + request = RegistryServer_pb2.GetLabelViewRequest( + name=name, project=project, allow_cache=allow_cache + ) + response = self.stub.GetLabelView(request) + return LabelView.from_proto(response) + + def list_label_views( + self, + project: str, + allow_cache: bool = False, + tags: Optional[dict[str, str]] = None, + ) -> List[LabelView]: + request = RegistryServer_pb2.ListLabelViewsRequest( + project=project, allow_cache=allow_cache, tags=tags + ) + response = self.stub.ListLabelViews(request) + return [LabelView.from_proto(label_view) for label_view in response.label_views] + + def delete_label_view(self, name: str, project: str, commit: bool = True): + self.delete_feature_view(name, project, commit) + def get_any_feature_view( self, name: str, project: str, allow_cache: bool = False ) -> BaseFeatureView: @@ -316,6 +402,7 @@ def list_all_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[BaseFeatureView]: request = RegistryServer_pb2.ListAllFeatureViewsRequest( project=project, allow_cache=allow_cache, tags=tags @@ -343,6 +430,7 @@ def list_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[FeatureView]: request = RegistryServer_pb2.ListFeatureViewsRequest( project=project, allow_cache=allow_cache, tags=tags @@ -356,12 +444,18 @@ def list_feature_views( def apply_materialization( self, - feature_view: Union[FeatureView, OnDemandFeatureView], + feature_view: Union[FeatureView, OnDemandFeatureView, LabelView], project: str, start_date: datetime, end_date: datetime, commit: bool = True, ): + if isinstance(feature_view, LabelView): + raise ValueError( + f"Cannot apply materialization for LabelView {feature_view.name}. " + f"Use FeatureStore.push() to write labels." + ) + start_date_timestamp = Timestamp() end_date_timestamp = Timestamp() start_date_timestamp.FromDatetime(start_date) diff --git a/sdk/python/feast/infra/registry/snowflake.py b/sdk/python/feast/infra/registry/snowflake.py index 12299572f04..3b528209b1a 100644 --- a/sdk/python/feast/infra/registry/snowflake.py +++ b/sdk/python/feast/infra/registry/snowflake.py @@ -33,6 +33,7 @@ GetSnowflakeConnection, execute_snowflake_statement, ) +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -44,6 +45,7 @@ ) from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto from feast.protos.feast.core.InfraObject_pb2 import Infra as InfraProto +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( OnDemandFeatureView as OnDemandFeatureViewProto, ) @@ -139,20 +141,21 @@ def __init__( with GetSnowflakeConnection(self.registry_config) as conn: sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_creation.sql" with open(sql_function_file, "r") as file: - sql_file = file.read() - sql_cmds = sql_file.split(";") + sql_cmds = [ + cmd.strip() for cmd in file.read().split(";") if cmd.strip() + ] for command in sql_cmds: query = command.replace("REGISTRY_PATH", f"{self.registry_path}") execute_snowflake_statement(conn, query) self.purge_feast_metadata = registry_config.purge_feast_metadata - self._sync_feast_metadata_to_projects_table() - if not self.purge_feast_metadata: - self._maybe_init_project_metadata(project) + self.project = project - self.cached_registry_proto = self.proto() - self.cached_registry_proto_created = _utc_now() + # Initialize cache state before any method that may trigger + # _refresh_cached_registry_if_necessary (e.g. proto(), get_project()). self._refresh_lock = Lock() + self.cached_registry_proto = None + self.cached_registry_proto_created = None self.cached_registry_proto_ttl = timedelta( seconds=( registry_config.cache_ttl_seconds @@ -160,11 +163,17 @@ def __init__( else 0 ) ) - self.project = project + + self._sync_feast_metadata_to_projects_table() + if not self.purge_feast_metadata: + self._maybe_init_project_metadata(project) + + self.cached_registry_proto = self.proto() + self.cached_registry_proto_created = _utc_now() def _sync_feast_metadata_to_projects_table(self): - feast_metadata_projects: set = [] - projects_set: set = [] + feast_metadata_projects: set[str] = set() + projects_set: set[str] = set() with GetSnowflakeConnection(self.registry_config) as conn: query = ( @@ -184,7 +193,7 @@ def _sync_feast_metadata_to_projects_table(self): projects_set.add(row[1]["PROJECT_ID"]) # Find object in feast_metadata_projects but not in projects - projects_to_sync = set(feast_metadata_projects) - set(projects_set) + projects_to_sync = feast_metadata_projects - projects_set for project_name in projects_to_sync: self.apply_project(Project(name=project_name), commit=True) @@ -199,7 +208,7 @@ def refresh(self, project: Optional[str] = None): self.cached_registry_proto = self.proto() self.cached_registry_proto_created = _utc_now() - def _refresh_cached_registry_if_necessary(self): + def _refresh_cached_registry_if_necessary(self) -> RegistryProto: with self._refresh_lock: expired = ( self.cached_registry_proto is None @@ -220,13 +229,18 @@ def _refresh_cached_registry_if_necessary(self): logger.info("Registry cache expired, so refreshing") self.refresh() + if self.cached_registry_proto is None: + raise RuntimeError("Registry cache is unexpectedly empty after refresh") + return self.cached_registry_proto + def teardown(self): with GetSnowflakeConnection(self.registry_config) as conn: sql_function_file = f"{os.path.dirname(feast.__file__)}/infra/utils/snowflake/registry/snowflake_table_deletion.sql" with open(sql_function_file, "r") as file: - sqlFile = file.read() - sqlCommands = sqlFile.split(";") - for command in sqlCommands: + sql_cmds = [ + cmd.strip() for cmd in file.read().split(";") if cmd.strip() + ] + for command in sql_cmds: query = command.replace("REGISTRY_PATH", f"{self.registry_path}") execute_snowflake_statement(conn, query) @@ -259,8 +273,18 @@ def apply_feature_service( ) def apply_feature_view( - self, feature_view: BaseFeatureView, project: str, commit: bool = True + self, + feature_view: BaseFeatureView, + project: str, + commit: bool = True, + no_promote: bool = False, ): + if no_promote: + raise NotImplementedError( + "Feature view versioning (no_promote) is not supported by the Snowflake registry. " + "Use the SQL registry or file registry for versioning support." + ) + feature_view.ensure_valid() fv_table_str = self._infer_fv_table(feature_view) fv_column_name = fv_table_str[:-1] return self._apply_object( @@ -363,7 +387,8 @@ def _apply_object( {proto_field_name} = TO_BINARY({proto}), last_updated_timestamp = CURRENT_TIMESTAMP() WHERE - {id_field_name.lower()} = '{name}' + project_id = '{project}' + AND {id_field_name.lower()} = '{name}' """ execute_snowflake_statement(conn, query) @@ -382,7 +407,7 @@ def _apply_object( VALUES ('{name}', '{project}', CURRENT_TIMESTAMP(), TO_BINARY({proto}), '', '') """ - elif "_FEATURE_VIEWS" in table: + elif "_FEATURE_VIEWS" in table or table == "LABEL_VIEWS": query = f""" INSERT INTO {self.registry_path}."{table}" VALUES @@ -439,17 +464,16 @@ def delete_feature_service(self, name: str, project: str, commit: bool = True): FeatureServiceNotFoundException, ) - # can you have featureviews with the same name def delete_feature_view(self, name: str, project: str, commit: bool = True): deleted_count = 0 - for table in { - "FEATURE_VIEWS", - "ON_DEMAND_FEATURE_VIEWS", - "STREAM_FEATURE_VIEWS", - }: - deleted_count += self._delete_object( - table, name, project, "FEATURE_VIEW_NAME", None - ) + _FV_TABLE_ID_COLUMNS = { + "FEATURE_VIEWS": "FEATURE_VIEW_NAME", + "ON_DEMAND_FEATURE_VIEWS": "FEATURE_VIEW_NAME", + "STREAM_FEATURE_VIEWS": "FEATURE_VIEW_NAME", + "LABEL_VIEWS": "LABEL_VIEW_NAME", + } + for table, id_col in _FV_TABLE_ID_COLUMNS.items(): + deleted_count += self._delete_object(table, name, project, id_col, None) if deleted_count == 0: raise FeatureViewNotFoundException(name, project) @@ -508,10 +532,8 @@ def get_data_source( self, name: str, project: str, allow_cache: bool = False ) -> DataSource: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_data_source( - self.cached_registry_proto, name, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_data_source(registry_proto, name, project) return self._get_object( "DATA_SOURCES", name, @@ -525,10 +547,8 @@ def get_data_source( def get_entity(self, name: str, project: str, allow_cache: bool = False) -> Entity: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_entity( - self.cached_registry_proto, name, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_entity(registry_proto, name, project) return self._get_object( "ENTITIES", name, @@ -544,9 +564,9 @@ def get_feature_service( self, name: str, project: str, allow_cache: bool = False ) -> FeatureService: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.get_feature_service( - self.cached_registry_proto, name, project + registry_proto, name, project ) return self._get_object( "FEATURE_SERVICES", @@ -563,10 +583,8 @@ def get_feature_view( self, name: str, project: str, allow_cache: bool = False ) -> FeatureView: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_feature_view( - self.cached_registry_proto, name, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_feature_view(registry_proto, name, project) return self._get_object( "FEATURE_VIEWS", name, @@ -582,9 +600,9 @@ def get_any_feature_view( self, name: str, project: str, allow_cache: bool = False ) -> BaseFeatureView: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.get_any_feature_view( - self.cached_registry_proto, name, project + registry_proto, name, project ) fv = self._get_object( "FEATURE_VIEWS", @@ -617,6 +635,17 @@ def get_any_feature_view( OnDemandFeatureView, "ON_DEMAND_FEATURE_VIEW_NAME", "ON_DEMAND_FEATURE_VIEW_PROTO", + None, + ) + if not fv: + fv = self._get_object( + "LABEL_VIEWS", + name, + project, + LabelViewProto, + LabelView, + "LABEL_VIEW_NAME", + "LABEL_VIEW_PROTO", FeatureViewNotFoundException, ) return fv @@ -626,25 +655,34 @@ def list_all_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[BaseFeatureView]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_all_feature_views( - self.cached_registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) return ( cast( list[BaseFeatureView], - self.list_feature_views(project, allow_cache, tags), + self.list_feature_views(project, allow_cache, tags, skip_udf=skip_udf), + ) + + cast( + list[BaseFeatureView], + self.list_stream_feature_views( + project, allow_cache, tags, skip_udf=skip_udf + ), ) + cast( list[BaseFeatureView], - self.list_stream_feature_views(project, allow_cache, tags), + self.list_on_demand_feature_views( + project, allow_cache, tags, skip_udf=skip_udf + ), ) + cast( list[BaseFeatureView], - self.list_on_demand_feature_views(project, allow_cache, tags), + self.list_label_views(project, allow_cache, tags), ) ) @@ -666,9 +704,9 @@ def get_on_demand_feature_view( self, name: str, project: str, allow_cache: bool = False ) -> OnDemandFeatureView: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.get_on_demand_feature_view( - self.cached_registry_proto, name, project + registry_proto, name, project ) return self._get_object( "ON_DEMAND_FEATURE_VIEWS", @@ -685,10 +723,8 @@ def get_saved_dataset( self, name: str, project: str, allow_cache: bool = False ) -> SavedDataset: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_saved_dataset( - self.cached_registry_proto, name, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_saved_dataset(registry_proto, name, project) return self._get_object( "SAVED_DATASETS", name, @@ -704,9 +740,9 @@ def get_stream_feature_view( self, name: str, project: str, allow_cache: bool = False ): if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.get_stream_feature_view( - self.cached_registry_proto, name, project + registry_proto, name, project ) return self._get_object( "STREAM_FEATURE_VIEWS", @@ -723,9 +759,9 @@ def get_validation_reference( self, name: str, project: str, allow_cache: bool = False ) -> ValidationReference: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.get_validation_reference( - self.cached_registry_proto, name, project + registry_proto, name, project ) return self._get_object( "VALIDATION_REFERENCES", @@ -774,10 +810,8 @@ def get_permission( self, name: str, project: str, allow_cache: bool = False ) -> Permission: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_permission( - self.cached_registry_proto, name, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_permission(registry_proto, name, project) return self._get_object( "PERMISSIONS", name, @@ -797,10 +831,8 @@ def list_data_sources( tags: Optional[dict[str, str]] = None, ) -> List[DataSource]: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.list_data_sources( - self.cached_registry_proto, project, tags - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_data_sources(registry_proto, project, tags) return self._list_objects( "DATA_SOURCES", project, @@ -817,10 +849,8 @@ def list_entities( tags: Optional[dict[str, str]] = None, ) -> List[Entity]: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.list_entities( - self.cached_registry_proto, project, tags - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_entities(registry_proto, project, tags) return self._list_objects( "ENTITIES", project, EntityProto, Entity, "ENTITY_PROTO", tags=tags ) @@ -832,9 +862,9 @@ def list_feature_services( tags: Optional[dict[str, str]] = None, ) -> List[FeatureService]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_feature_services( - self.cached_registry_proto, project, tags + registry_proto, project, tags ) return self._list_objects( "FEATURE_SERVICES", @@ -850,11 +880,12 @@ def list_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[FeatureView]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_feature_views( - self.cached_registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) return self._list_objects( "FEATURE_VIEWS", @@ -863,6 +894,7 @@ def list_feature_views( FeatureView, "FEATURE_VIEW_PROTO", tags=tags, + skip_udf=skip_udf, ) def list_on_demand_feature_views( @@ -870,11 +902,12 @@ def list_on_demand_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[OnDemandFeatureView]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_on_demand_feature_views( - self.cached_registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) return self._list_objects( "ON_DEMAND_FEATURE_VIEWS", @@ -883,6 +916,7 @@ def list_on_demand_feature_views( OnDemandFeatureView, "ON_DEMAND_FEATURE_VIEW_PROTO", tags=tags, + skip_udf=skip_udf, ) def list_saved_datasets( @@ -892,9 +926,9 @@ def list_saved_datasets( tags: Optional[dict[str, str]] = None, ) -> List[SavedDataset]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_saved_datasets( - self.cached_registry_proto, project, tags + registry_proto, project, tags ) return self._list_objects( "SAVED_DATASETS", @@ -910,11 +944,12 @@ def list_stream_feature_views( project: str, allow_cache: bool = False, tags: Optional[dict[str, str]] = None, + skip_udf: bool = False, ) -> List[StreamFeatureView]: if allow_cache: - self._refresh_cached_registry_if_necessary() + registry_proto = self._refresh_cached_registry_if_necessary() return proto_registry_utils.list_stream_feature_views( - self.cached_registry_proto, project, tags + registry_proto, project, tags, skip_udf=skip_udf ) return self._list_objects( "STREAM_FEATURE_VIEWS", @@ -922,9 +957,54 @@ def list_stream_feature_views( StreamFeatureViewProto, StreamFeatureView, "STREAM_FEATURE_VIEW_PROTO", + skip_udf=skip_udf, tags=tags, ) + def get_label_view( + self, name: str, project: str, allow_cache: bool = False + ) -> LabelView: + if allow_cache: + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_label_view(registry_proto, name, project) + return self._get_object( + "LABEL_VIEWS", + name, + project, + LabelViewProto, + LabelView, + "LABEL_VIEW_NAME", + "LABEL_VIEW_PROTO", + FeatureViewNotFoundException, + ) + + def list_label_views( + self, + project: str, + allow_cache: bool = False, + tags: Optional[dict[str, str]] = None, + ) -> List[LabelView]: + if allow_cache: + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_label_views(registry_proto, project, tags) + return self._list_objects( + "LABEL_VIEWS", + project, + LabelViewProto, + LabelView, + "LABEL_VIEW_PROTO", + tags=tags, + ) + + def delete_label_view(self, name: str, project: str, commit: bool = True): + self._delete_object( + "LABEL_VIEWS", + name, + project, + "LABEL_VIEW_NAME", + FeatureViewNotFoundException, + ) + def list_validation_references( self, project: str, @@ -948,7 +1028,20 @@ def _list_objects( python_class: Any, proto_field_name: str, tags: Optional[dict[str, str]] = None, + proto_only: bool = False, + skip_udf: bool = False, ): + """ + Args: + proto_only: If True, return raw protobuf objects without calling + from_proto(). Used by proto() to build the RegistryProto cache + efficiently — avoids the from_proto()/to_proto() round-trip and + works uniformly for all object types (entities, data sources, etc.). + skip_udf: If True, call from_proto() but skip deserializing UDFs + (dill.loads). Returns Python objects suitable for filtering and + display without requiring the UDF's source module to be installed. + Only relevant for feature view types. + """ with GetSnowflakeConnection(self.registry_config) as conn: query = f""" SELECT @@ -962,11 +1055,17 @@ def _list_objects( if not df.empty: objects = [] for row in df.iterrows(): - obj = python_class.from_proto( - proto_class.FromString(row[1][proto_field_name]) - ) - if has_all_tags(obj.tags, tags): - objects.append(obj) + proto = proto_class.FromString(row[1][proto_field_name]) + if proto_only: + objects.append(proto) + else: + obj = ( + python_class.from_proto(proto, skip_udf=skip_udf) + if skip_udf + else python_class.from_proto(proto) + ) + if has_all_tags(obj.tags, tags): + objects.append(obj) return objects return [] @@ -977,10 +1076,8 @@ def list_permissions( tags: Optional[dict[str, str]] = None, ) -> List[Permission]: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.list_permissions( - self.cached_registry_proto, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_permissions(registry_proto, project) return self._list_objects( "PERMISSIONS", project, @@ -992,7 +1089,7 @@ def list_permissions( def apply_materialization( self, - feature_view: Union[FeatureView, OnDemandFeatureView], + feature_view: Union[FeatureView, OnDemandFeatureView, LabelView], project: str, start_date: datetime, end_date: datetime, @@ -1002,7 +1099,7 @@ def apply_materialization( fv_column_name = fv_table_str[:-1] python_class, proto_class = self._infer_fv_classes(feature_view) - if python_class in {OnDemandFeatureView}: + if python_class in {OnDemandFeatureView, LabelView}: raise ValueError( f"Cannot apply materialization for feature {feature_view.name} of type {python_class}" ) @@ -1029,10 +1126,8 @@ def list_project_metadata( self, project: str, allow_cache: bool = False ) -> List[ProjectMetadata]: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.list_project_metadata( - self.cached_registry_proto, project - ) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_project_metadata(registry_proto, project) with GetSnowflakeConnection(self.registry_config) as conn: query = f""" SELECT @@ -1106,7 +1201,8 @@ def get_user_metadata( FROM {self.registry_path}."{fv_table_str}" WHERE - {fv_column_name}_name = '{feature_view.name}' + project_id = '{project}' + AND {fv_column_name}_name = '{feature_view.name}' LIMIT 1 """ df = execute_snowflake_statement(conn, query).fetch_pandas_all() @@ -1125,41 +1221,100 @@ def process_project(project: Project): project_name = project.name last_updated_timestamp = project.last_updated_timestamp - try: - cached_project = self.get_project(project_name, True) - except ProjectObjectNotFoundException: - cached_project = None - - allow_cache = False - - if cached_project is not None: - allow_cache = ( - last_updated_timestamp <= cached_project.last_updated_timestamp - ) - r.projects.extend([project.to_proto()]) last_updated_timestamps.append(last_updated_timestamp) - for lister, registry_proto_field in [ - (self.list_entities, r.entities), - (self.list_feature_views, r.feature_views), - (self.list_data_sources, r.data_sources), - (self.list_on_demand_feature_views, r.on_demand_feature_views), - (self.list_stream_feature_views, r.stream_feature_views), - (self.list_feature_services, r.feature_services), - (self.list_saved_datasets, r.saved_datasets), - (self.list_validation_references, r.validation_references), - (self.list_permissions, r.permissions), + # proto_only=True: return raw protos without calling from_proto(), + # which would trigger dill.loads() on UDFs and fail for cross-project + # modules. _list_objects hits the DB directly (no cache), avoiding + # infinite recursion since proto() itself builds the cache. + for ( + table, + proto_class, + python_class, + proto_field_name, + registry_proto_field, + ) in [ + ("ENTITIES", EntityProto, Entity, "ENTITY_PROTO", r.entities), + ( + "FEATURE_VIEWS", + FeatureViewProto, + FeatureView, + "FEATURE_VIEW_PROTO", + r.feature_views, + ), + ( + "DATA_SOURCES", + DataSourceProto, + DataSource, + "DATA_SOURCE_PROTO", + r.data_sources, + ), + ( + "ON_DEMAND_FEATURE_VIEWS", + OnDemandFeatureViewProto, + OnDemandFeatureView, + "ON_DEMAND_FEATURE_VIEW_PROTO", + r.on_demand_feature_views, + ), + ( + "STREAM_FEATURE_VIEWS", + StreamFeatureViewProto, + StreamFeatureView, + "STREAM_FEATURE_VIEW_PROTO", + r.stream_feature_views, + ), + ( + "FEATURE_SERVICES", + FeatureServiceProto, + FeatureService, + "FEATURE_SERVICE_PROTO", + r.feature_services, + ), + ( + "SAVED_DATASETS", + SavedDatasetProto, + SavedDataset, + "SAVED_DATASET_PROTO", + r.saved_datasets, + ), + ( + "VALIDATION_REFERENCES", + ValidationReferenceProto, + ValidationReference, + "VALIDATION_REFERENCE_PROTO", + r.validation_references, + ), + ( + "PERMISSIONS", + PermissionProto, + Permission, + "PERMISSION_PROTO", + r.permissions, + ), + ( + "LABEL_VIEWS", + LabelViewProto, + LabelView, + "LABEL_VIEW_PROTO", + r.label_views, + ), ]: - objs: List[Any] = lister(project_name, allow_cache) # type: ignore + objs = self._list_objects( + table, + project_name, + proto_class, + python_class, + proto_field_name, + proto_only=True, + ) if objs: - obj_protos = [obj.to_proto() for obj in objs] - for obj_proto in obj_protos: + for obj_proto in objs: if "spec" in obj_proto.DESCRIPTOR.fields_by_name: obj_proto.spec.project = project_name else: obj_proto.project = project_name - registry_proto_field.extend(obj_protos) + registry_proto_field.extend(objs) # This is suuuper jank. Because of https://github.com/feast-dev/feast/issues/2783, # the registry proto only has a single infra field, which we're currently setting as the "last" project. @@ -1194,7 +1349,9 @@ def _get_last_updated_metadata(self, project: str): return datetime.fromtimestamp(int(df.squeeze()), tz=timezone.utc) def _infer_fv_classes(self, feature_view): - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + python_class, proto_class = LabelView, LabelViewProto + elif isinstance(feature_view, StreamFeatureView): python_class, proto_class = StreamFeatureView, StreamFeatureViewProto elif isinstance(feature_view, FeatureView): python_class, proto_class = FeatureView, FeatureViewProto @@ -1205,7 +1362,9 @@ def _infer_fv_classes(self, feature_view): return python_class, proto_class def _infer_fv_table(self, feature_view) -> str: - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + table = "LABEL_VIEWS" + elif isinstance(feature_view, StreamFeatureView): table = "STREAM_FEATURE_VIEWS" elif isinstance(feature_view, FeatureView): table = "FEATURE_VIEWS" @@ -1303,6 +1462,7 @@ def delete_project( "FEATURE_VIEWS", "ON_DEMAND_FEATURE_VIEWS", "STREAM_FEATURE_VIEWS", + "LABEL_VIEWS", "DATA_SOURCES", "ENTITIES", "PERMISSIONS", @@ -1312,7 +1472,7 @@ def delete_project( query = f""" DELETE FROM {self.registry_path}."{table}" WHERE - project_id = '{project}' + project_id = '{name}' """ execute_snowflake_statement(conn, query) return @@ -1340,8 +1500,8 @@ def get_project( allow_cache: bool = False, ) -> Project: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.get_project(self.cached_registry_proto, name) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.get_project(registry_proto, name) return self._get_project(name) def _list_projects( @@ -1357,7 +1517,7 @@ def _list_projects( objects = [] for row in df.iterrows(): obj = Project.from_proto( - ProjectProto.FromString(row[1]["project_proto"]) + ProjectProto.FromString(row[1]["PROJECT_PROTO"]) ) if has_all_tags(obj.tags, tags): objects.append(obj) @@ -1370,8 +1530,8 @@ def list_projects( tags: Optional[dict[str, str]] = None, ) -> List[Project]: if allow_cache: - self._refresh_cached_registry_if_necessary() - return proto_registry_utils.list_projects(self.cached_registry_proto, tags) + registry_proto = self._refresh_cached_registry_if_necessary() + return proto_registry_utils.list_projects(registry_proto, tags) return self._list_projects(tags) def set_project_metadata(self, project: str, key: str, value: str): diff --git a/sdk/python/feast/infra/registry/sql.py b/sdk/python/feast/infra/registry/sql.py index 197ca02d57a..652c5ed6a6e 100644 --- a/sdk/python/feast/infra/registry/sql.py +++ b/sdk/python/feast/infra/registry/sql.py @@ -11,6 +11,7 @@ BigInteger, Column, Index, + Integer, LargeBinary, MetaData, String, @@ -18,6 +19,7 @@ Text, create_engine, delete, + func, insert, select, update, @@ -30,10 +32,13 @@ from feast.data_source import DataSource from feast.entity import Entity from feast.errors import ( + ConcurrentVersionConflict, DataSourceObjectNotFoundException, EntityNotFoundException, FeatureServiceNotFoundException, FeatureViewNotFoundException, + FeatureViewPinConflict, + FeatureViewVersionNotFound, PermissionNotFoundException, ProjectNotFoundException, ProjectObjectNotFoundException, @@ -44,6 +49,7 @@ from feast.feature_view import FeatureView from feast.infra.infra_object import Infra from feast.infra.registry.caching_registry import CachingRegistry +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -55,6 +61,7 @@ ) from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto from feast.protos.feast.core.InfraObject_pb2 import Infra as InfraProto +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto from feast.protos.feast.core.OnDemandFeatureView_pb2 import ( OnDemandFeatureView as OnDemandFeatureViewProto, ) @@ -72,6 +79,11 @@ from feast.saved_dataset import SavedDataset, ValidationReference from feast.stream_feature_view import StreamFeatureView from feast.utils import _utc_now +from feast.version_utils import ( + generate_version_id, + parse_version, + version_tag, +) metadata = MetaData() @@ -146,6 +158,18 @@ Index("idx_on_demand_feature_views_project_id", on_demand_feature_views.c.project_id) +label_views = Table( + "label_views", + metadata, + Column("feature_view_name", String(255), primary_key=True), + Column("project_id", String(255), primary_key=True), + Column("last_updated_timestamp", BigInteger, nullable=False), + Column("feature_view_proto", LargeBinary, nullable=False), + Column("user_metadata", LargeBinary, nullable=True), +) + +Index("idx_label_views_project_id", label_views.c.project_id) + feature_services = Table( "feature_services", metadata, @@ -200,6 +224,24 @@ Index("idx_permissions_project_id", permissions.c.project_id) +feature_view_version_history = Table( + "feature_view_version_history", + metadata, + Column("feature_view_name", String(255), primary_key=True), + Column("project_id", String(255), primary_key=True), + Column("version_number", Integer, primary_key=True), + Column("feature_view_type", String(50), nullable=False), + Column("feature_view_proto", LargeBinary, nullable=False), + Column("created_timestamp", BigInteger, nullable=False), + Column("description", Text, nullable=True), + Column("version_id", String(36), nullable=False), +) + +Index( + "idx_fv_version_history_project_id", + feature_view_version_history.c.project_id, +) + class FeastMetadataKeys(Enum): LAST_UPDATED_TIMESTAMP = "last_updated_timestamp" @@ -267,6 +309,9 @@ def __init__( registry_config.thread_pool_executor_worker_count ) self.purge_feast_metadata = registry_config.purge_feast_metadata + self.enable_online_versioning = ( + registry_config.enable_online_feature_view_versioning + ) super().__init__( project=project, cache_ttl_seconds=registry_config.cache_ttl_seconds, @@ -302,15 +347,21 @@ def _sync_feast_metadata_to_projects_table(self): # Find object in feast_metadata_projects but not in projects projects_to_sync = set(feast_metadata_projects.keys()) - set(projects_set) for project_name in projects_to_sync: - self.apply_project( - Project( - name=project_name, - created_timestamp=datetime.fromtimestamp( - feast_metadata_projects[project_name], tz=timezone.utc + try: + self.apply_project( + Project( + name=project_name, + created_timestamp=datetime.fromtimestamp( + feast_metadata_projects[project_name], tz=timezone.utc + ), ), - ), - commit=True, - ) + commit=True, + ) + except IntegrityError: + logger.info( + "Project %s already created in projects table by another process.", + project_name, + ) if self.purge_feast_metadata: with self.write_engine.begin() as conn: @@ -331,6 +382,8 @@ def teardown(self): saved_datasets, validation_references, permissions, + feature_view_version_history, + label_views, }: with self.write_engine.begin() as conn: stmt = delete(t) @@ -349,7 +402,7 @@ def _get_stream_feature_view(self, name: str, project: str): ) def _list_stream_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[StreamFeatureView]: return self._list_objects( stream_feature_views, @@ -358,6 +411,7 @@ def _list_stream_feature_views( StreamFeatureView, "feature_view_proto", tags=tags, + **kwargs, ) def apply_entity(self, entity: Entity, project: str, commit: bool = True): @@ -414,25 +468,43 @@ def _get_any_feature_view(self, name: str, project: str) -> BaseFeatureView: python_class=StreamFeatureView, id_field_name="feature_view_name", proto_field_name="feature_view_proto", + not_found_exception=None, + ) + + if not fv: + fv = self._get_object( + table=label_views, + name=name, + project=project, + proto_class=LabelViewProto, + python_class=LabelView, + id_field_name="feature_view_name", + proto_field_name="feature_view_proto", not_found_exception=FeatureViewNotFoundException, ) return fv def _list_all_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[BaseFeatureView]: return ( cast( list[BaseFeatureView], - self._list_feature_views(project=project, tags=tags), + self._list_feature_views(project=project, tags=tags, **kwargs), ) + cast( list[BaseFeatureView], - self._list_stream_feature_views(project=project, tags=tags), + self._list_stream_feature_views(project=project, tags=tags, **kwargs), ) + cast( list[BaseFeatureView], - self._list_on_demand_feature_views(project=project, tags=tags), + self._list_on_demand_feature_views( + project=project, tags=tags, **kwargs + ), + ) + + cast( + list[BaseFeatureView], + self._list_label_views(project=project, tags=tags, **kwargs), ) ) @@ -499,7 +571,7 @@ def _get_validation_reference(self, name: str, project: str) -> ValidationRefere ) def _list_validation_references( - self, project: str, tags: Optional[dict[str, str]] = None + self, project: str, tags: Optional[dict[str, str]] = None, **kwargs ) -> List[ValidationReference]: return self._list_objects( table=validation_references, @@ -508,13 +580,20 @@ def _list_validation_references( python_class=ValidationReference, proto_field_name="validation_reference_proto", tags=tags, + **kwargs, ) def _list_entities( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[Entity]: return self._list_objects( - entities, project, EntityProto, Entity, "entity_proto", tags=tags + entities, + project, + EntityProto, + Entity, + "entity_proto", + tags=tags, + **kwargs, ) def delete_entity(self, name: str, project: str, commit: bool = True): @@ -523,17 +602,37 @@ def delete_entity(self, name: str, project: str, commit: bool = True): ) def delete_feature_view(self, name: str, project: str, commit: bool = True): - deleted_count = 0 - for table in { - feature_views, - on_demand_feature_views, - stream_feature_views, - }: - deleted_count += self._delete_object( - table, name, project, "feature_view_name", None + with self.write_engine.begin() as conn: + deleted_count = 0 + for table in { + feature_views, + on_demand_feature_views, + stream_feature_views, + label_views, + }: + stmt = delete(table).where( + table.c.feature_view_name == name, + table.c.project_id == project, + ) + rows = conn.execute(stmt) + deleted_count += rows.rowcount + if deleted_count == 0: + raise FeatureViewNotFoundException(name, project) + # Clean up version history in the same transaction + stmt = delete(feature_view_version_history).where( + feature_view_version_history.c.feature_view_name == name, + feature_view_version_history.c.project_id == project, ) - if deleted_count == 0: - raise FeatureViewNotFoundException(name, project) + conn.execute(stmt) + + self.apply_project( + self.get_project(name=project, allow_cache=False), commit=True + ) + if not self.purge_feast_metadata: + with self.write_engine.begin() as conn: + self._set_last_updated_metadata(_utc_now(), project, conn) + if self.cache_mode == "sync": + self.refresh() def delete_feature_service(self, name: str, project: str, commit: bool = True): return self._delete_object( @@ -557,7 +656,7 @@ def _get_data_source(self, name: str, project: str) -> DataSource: ) def _list_data_sources( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[DataSource]: return self._list_objects( data_sources, @@ -566,6 +665,7 @@ def _list_data_sources( DataSource, "data_source_proto", tags=tags, + **kwargs, ) def apply_data_source( @@ -576,15 +676,229 @@ def apply_data_source( ) def apply_feature_view( - self, feature_view: BaseFeatureView, project: str, commit: bool = True + self, + feature_view: BaseFeatureView, + project: str, + commit: bool = True, + no_promote: bool = False, ): + feature_view.ensure_valid() self._ensure_feature_view_name_is_unique(feature_view, project) fv_table = self._infer_fv_table(feature_view) + fv_type_str = self._infer_fv_type_string(feature_view) - return self._apply_object( + is_latest, pin_version = parse_version(feature_view.version) + + if not is_latest: + # Explicit version: check if it exists (pin/revert) or not (forward declaration) + snapshot = self._get_version_snapshot( + feature_view.name, project, pin_version + ) + + if snapshot is not None: + # Version exists → pin/revert to that snapshot + # Check that the user hasn't also modified the definition. + # Compare user's FV (with version="latest") against active FV. + try: + active_fv = self._get_any_feature_view(feature_view.name, project) + user_fv_copy = feature_view.__copy__() + user_fv_copy.version = "latest" + active_fv.version = "latest" + # Clear metadata that differs due to registry state + user_fv_copy.created_timestamp = active_fv.created_timestamp + user_fv_copy.last_updated_timestamp = ( + active_fv.last_updated_timestamp + ) + user_fv_copy.current_version_number = ( + active_fv.current_version_number + ) + if hasattr(active_fv, "materialization_intervals"): + user_fv_copy.materialization_intervals = ( + active_fv.materialization_intervals + ) + if user_fv_copy != active_fv: + raise FeatureViewPinConflict( + feature_view.name, version_tag(pin_version) + ) + except FeatureViewNotFoundException: + pass + + snap_type, snap_proto_bytes = snapshot + proto_class, python_class = self._proto_class_for_type(snap_type) + snap_proto = proto_class.FromString(snap_proto_bytes) + restored_fv = python_class.from_proto(snap_proto) + restored_fv.version = feature_view.version + restored_fv.current_version_number = pin_version + return self._apply_object( + fv_table, + project, + "feature_view_name", + restored_fv, + "feature_view_proto", + ) + else: + # Version doesn't exist → forward declaration: create it + feature_view.current_version_number = pin_version + snapshot_proto = feature_view.to_proto() + snapshot_proto.spec.project = project + snapshot_proto_bytes = snapshot_proto.SerializeToString() + try: + self._save_version_snapshot( + feature_view.name, + project, + pin_version, + fv_type_str, + snapshot_proto_bytes, + ) + except IntegrityError: + raise ConcurrentVersionConflict( + f"Version v{pin_version} of '{feature_view.name}' was just created by " + f"another concurrent apply. Pull latest and retry." + ) + # Apply the FV as active + return self._apply_object( + fv_table, + project, + "feature_view_name", + feature_view, + "feature_view_proto", + ) + + # Normal (latest) apply: snapshot old version if changed, then save new + # First check if the FV already exists so we can snapshot the old one. + # Use write_engine for both reads to avoid read replica lag issues. + old_proto_bytes = None + with self.write_engine.begin() as conn: + stmt = select(fv_table).where( + fv_table.c.feature_view_name == feature_view.name, + fv_table.c.project_id == project, + ) + row = conn.execute(stmt).first() + if row: + old_proto_bytes = row._mapping["feature_view_proto"] + + # Apply the object (handles idempotency check internally) + # We need to detect if _apply_object actually made a change + # by checking before/after + self._apply_object( fv_table, project, "feature_view_name", feature_view, "feature_view_proto" ) + # After apply, read the current proto to see if it changed + with self.write_engine.begin() as conn: + stmt = select(fv_table).where( + fv_table.c.feature_view_name == feature_view.name, + fv_table.c.project_id == project, + ) + row = conn.execute(stmt).first() + if row: + new_proto_bytes = row._mapping["feature_view_proto"] + else: + return # shouldn't happen + + if old_proto_bytes is not None: + # Deserialize both versions to compare schema/UDF changes + proto_class, fv_class = self._proto_class_for_type(fv_type_str) + old_proto = proto_class.FromString(old_proto_bytes) + new_proto = proto_class.FromString(new_proto_bytes) + + old_fv = fv_class.from_proto(old_proto) + new_fv = fv_class.from_proto(new_proto) + + if not new_fv._schema_or_udf_changed(old_fv): + # No version-significant change, skip version creation + return + + # Something changed (or new FV). Save version snapshot(s). + if old_proto_bytes is not None: + # Snapshot the old version first (if not already in history) + next_ver = self._get_next_version_number(feature_view.name, project) + if next_ver == 0: + # First time versioning: save old as v0 + self._save_version_snapshot( + feature_view.name, + project, + 0, + fv_type_str, + old_proto_bytes, + ) + next_ver = 1 + + # Retry loop: if a concurrent apply claimed the same version number, + # re-read MAX+1 and try again. The client said "latest" so the + # exact number doesn't matter. + max_retries = 3 + for attempt in range(max_retries): + # Update current_version_number before saving snapshot + feature_view.current_version_number = next_ver + snapshot_proto = feature_view.to_proto() + snapshot_proto.spec.project = project + snapshot_proto_bytes = snapshot_proto.SerializeToString() + + try: + # Save new as next version (with correct current_version_number) + self._save_version_snapshot( + feature_view.name, + project, + next_ver, + fv_type_str, + snapshot_proto_bytes, + ) + break + except IntegrityError: + if attempt == max_retries - 1: + raise ConcurrentVersionConflict( + f"Failed to assign version for '{feature_view.name}' after " + f"{max_retries} attempts due to concurrent applies. " + f"Please retry." + ) + # Re-read the next available version number + next_ver = self._get_next_version_number(feature_view.name, project) + + if no_promote: + # Save version snapshot but skip updating the active row. + # The new version is accessible only via explicit @v reads. + return + + # Re-serialize with updated version number + with self.write_engine.begin() as conn: + update_stmt = ( + update(fv_table) + .where( + fv_table.c.feature_view_name == feature_view.name, + fv_table.c.project_id == project, + ) + .values( + feature_view_proto=snapshot_proto_bytes, + ) + ) + conn.execute(update_stmt) + else: + # New FV: save as v0 + feature_view.current_version_number = 0 + snapshot_proto = feature_view.to_proto() + snapshot_proto.spec.project = project + snapshot_proto_bytes = snapshot_proto.SerializeToString() + self._save_version_snapshot( + feature_view.name, + project, + 0, + fv_type_str, + snapshot_proto_bytes, + ) + with self.write_engine.begin() as conn: + update_stmt = ( + update(fv_table) + .where( + fv_table.c.feature_view_name == feature_view.name, + fv_table.c.project_id == project, + ) + .values( + feature_view_proto=snapshot_proto_bytes, + ) + ) + conn.execute(update_stmt) + def apply_feature_service( self, feature_service: FeatureService, project: str, commit: bool = True ): @@ -607,7 +921,7 @@ def delete_data_source(self, name: str, project: str, commit: bool = True): raise DataSourceObjectNotFoundException(name, project) def _list_feature_services( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[FeatureService]: return self._list_objects( feature_services, @@ -616,10 +930,11 @@ def _list_feature_services( FeatureService, "feature_service_proto", tags=tags, + **kwargs, ) def _list_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[FeatureView]: return self._list_objects( feature_views, @@ -628,10 +943,11 @@ def _list_feature_views( FeatureView, "feature_view_proto", tags=tags, + **kwargs, ) def _list_saved_datasets( - self, project: str, tags: Optional[dict[str, str]] = None + self, project: str, tags: Optional[dict[str, str]] = None, **kwargs ) -> List[SavedDataset]: return self._list_objects( saved_datasets, @@ -640,10 +956,11 @@ def _list_saved_datasets( SavedDataset, "saved_dataset_proto", tags=tags, + **kwargs, ) def _list_on_demand_feature_views( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[OnDemandFeatureView]: return self._list_objects( on_demand_feature_views, @@ -652,6 +969,41 @@ def _list_on_demand_feature_views( OnDemandFeatureView, "feature_view_proto", tags=tags, + **kwargs, + ) + + def _get_label_view(self, name: str, project: str) -> LabelView: + return self._get_object( + table=label_views, + name=name, + project=project, + proto_class=LabelViewProto, + python_class=LabelView, + id_field_name="feature_view_name", + proto_field_name="feature_view_proto", + not_found_exception=FeatureViewNotFoundException, + ) + + def _list_label_views( + self, project: str, tags: Optional[dict[str, str]], **kwargs + ) -> List[LabelView]: + return self._list_objects( + label_views, + project, + LabelViewProto, + LabelView, + "feature_view_proto", + tags=tags, + **kwargs, + ) + + def delete_label_view(self, name: str, project: str, commit: bool = True): + self._delete_object( + label_views, + name, + project, + "feature_view_name", + FeatureViewNotFoundException, ) def _list_project_metadata(self, project: str) -> List[ProjectMetadata]: @@ -703,7 +1055,7 @@ def apply_validation_reference( def apply_materialization( self, - feature_view: Union[FeatureView, OnDemandFeatureView], + feature_view: Union[FeatureView, OnDemandFeatureView, LabelView], project: str, start_date: datetime, end_date: datetime, @@ -712,7 +1064,7 @@ def apply_materialization( table = self._infer_fv_table(feature_view) python_class, proto_class = self._infer_fv_classes(feature_view) - if python_class in {OnDemandFeatureView}: + if python_class in {OnDemandFeatureView, LabelView}: raise ValueError( f"Cannot apply materialization for feature {feature_view.name} of type {python_class}" ) @@ -802,7 +1154,9 @@ def apply_user_metadata( raise FeatureViewNotFoundException(feature_view.name, project=project) def _infer_fv_table(self, feature_view): - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + table = label_views + elif isinstance(feature_view, StreamFeatureView): table = stream_feature_views elif isinstance(feature_view, FeatureView): table = feature_views @@ -813,7 +1167,9 @@ def _infer_fv_table(self, feature_view): return table def _infer_fv_classes(self, feature_view): - if isinstance(feature_view, StreamFeatureView): + if isinstance(feature_view, LabelView): + python_class, proto_class = LabelView, LabelViewProto + elif isinstance(feature_view, StreamFeatureView): python_class, proto_class = StreamFeatureView, StreamFeatureViewProto elif isinstance(feature_view, FeatureView): python_class, proto_class = FeatureView, FeatureViewProto @@ -823,6 +1179,129 @@ def _infer_fv_classes(self, feature_view): raise ValueError(f"Unexpected feature view type: {type(feature_view)}") return python_class, proto_class + def _infer_fv_type_string(self, feature_view) -> str: + from feast.labeling.label_view import LabelView + + if isinstance(feature_view, LabelView): + return "label_view" + elif isinstance(feature_view, StreamFeatureView): + return "stream_feature_view" + elif isinstance(feature_view, FeatureView): + return "feature_view" + elif isinstance(feature_view, OnDemandFeatureView): + return "on_demand_feature_view" + else: + raise ValueError(f"Unexpected feature view type: {type(feature_view)}") + + def _proto_class_for_type(self, fv_type: str): + from feast.labeling.label_view import LabelView + from feast.protos.feast.core.LabelView_pb2 import ( + LabelView as LabelViewProto, + ) + + if fv_type == "label_view": + return LabelViewProto, LabelView + elif fv_type == "stream_feature_view": + return StreamFeatureViewProto, StreamFeatureView + elif fv_type == "feature_view": + return FeatureViewProto, FeatureView + elif fv_type == "on_demand_feature_view": + return OnDemandFeatureViewProto, OnDemandFeatureView + else: + raise ValueError(f"Unknown feature view type: {fv_type}") + + def _get_next_version_number(self, name: str, project: str) -> int: + with self.write_engine.begin() as conn: + stmt = select( + func.coalesce( + func.max(feature_view_version_history.c.version_number) + 1, 0 + ) + ).where( + feature_view_version_history.c.feature_view_name == name, + feature_view_version_history.c.project_id == project, + ) + result = conn.execute(stmt).scalar() + return result or 0 + + def _save_version_snapshot( + self, + name: str, + project: str, + version_number: int, + fv_type: str, + proto_bytes: bytes, + ): + now = int(_utc_now().timestamp()) + vid = generate_version_id() + with self.write_engine.begin() as conn: + stmt = insert(feature_view_version_history).values( + feature_view_name=name, + project_id=project, + version_number=version_number, + feature_view_type=fv_type, + feature_view_proto=proto_bytes, + created_timestamp=now, + description="", + version_id=vid, + ) + conn.execute(stmt) + + def _get_version_snapshot( + self, name: str, project: str, version_number: int + ) -> Optional[tuple]: + with self.read_engine.begin() as conn: + stmt = select(feature_view_version_history).where( + feature_view_version_history.c.feature_view_name == name, + feature_view_version_history.c.project_id == project, + feature_view_version_history.c.version_number == version_number, + ) + row = conn.execute(stmt).first() + if row: + return ( + row._mapping["feature_view_type"], + row._mapping["feature_view_proto"], + ) + return None + + def get_feature_view_by_version( + self, name: str, project: str, version_number: int, allow_cache: bool = False + ) -> BaseFeatureView: + snapshot = self._get_version_snapshot(name, project, version_number) + if snapshot is None: + raise FeatureViewVersionNotFound(name, version_tag(version_number), project) + snap_type, snap_proto_bytes = snapshot + proto_class, python_class = self._proto_class_for_type(snap_type) + snap_proto = proto_class.FromString(snap_proto_bytes) + fv = python_class.from_proto(snap_proto) + fv.current_version_number = version_number + return fv + + def list_feature_view_versions( + self, name: str, project: str + ) -> List[Dict[str, Any]]: + with self.read_engine.begin() as conn: + stmt = ( + select(feature_view_version_history) + .where( + feature_view_version_history.c.feature_view_name == name, + feature_view_version_history.c.project_id == project, + ) + .order_by(feature_view_version_history.c.version_number) + ) + rows = conn.execute(stmt).all() + return [ + { + "version": version_tag(row._mapping["version_number"]), + "version_number": row._mapping["version_number"], + "feature_view_type": row._mapping["feature_view_type"], + "created_timestamp": datetime.fromtimestamp( + row._mapping["created_timestamp"], tz=timezone.utc + ), + "version_id": row._mapping["version_id"], + } + for row in rows + ] + def get_user_metadata( self, project: str, feature_view: BaseFeatureView ) -> Optional[bytes]: @@ -849,26 +1328,30 @@ def process_project(project: Project): r.projects.extend([project.to_proto()]) last_updated_timestamps.append(last_updated_timestamp) + # proto_only=True: return raw protos without calling from_proto(), + # which would trigger dill.loads() on UDFs and fail for cross-project + # modules. The _list_* helpers hit the DB directly (no cache), avoiding + # infinite recursion since proto() itself builds the cache. for lister, registry_proto_field in [ - (self.list_entities, r.entities), - (self.list_feature_views, r.feature_views), - (self.list_data_sources, r.data_sources), - (self.list_on_demand_feature_views, r.on_demand_feature_views), - (self.list_stream_feature_views, r.stream_feature_views), - (self.list_feature_services, r.feature_services), - (self.list_saved_datasets, r.saved_datasets), - (self.list_validation_references, r.validation_references), - (self.list_permissions, r.permissions), + (self._list_entities, r.entities), + (self._list_feature_views, r.feature_views), + (self._list_data_sources, r.data_sources), + (self._list_on_demand_feature_views, r.on_demand_feature_views), + (self._list_stream_feature_views, r.stream_feature_views), + (self._list_feature_services, r.feature_services), + (self._list_saved_datasets, r.saved_datasets), + (self._list_validation_references, r.validation_references), + (self._list_permissions, r.permissions), + (self._list_label_views, r.label_views), ]: - objs: List[Any] = lister(project_name, allow_cache=False) # type: ignore + objs: List[Any] = lister(project_name, tags=None, proto_only=True) # type: ignore if objs: - obj_protos = [obj.to_proto() for obj in objs] - for obj_proto in obj_protos: + for obj_proto in objs: if "spec" in obj_proto.DESCRIPTOR.fields_by_name: obj_proto.spec.project = project_name else: obj_proto.project = project_name - registry_proto_field.extend(obj_protos) + registry_proto_field.extend(objs) # This is suuuper jank. Because of https://github.com/feast-dev/feast/issues/2783, # the registry proto only has a single infra field, which we're currently setting as the "last" project. @@ -997,10 +1480,16 @@ def _apply_object( "last_updated_timestamp": update_time, "project_id": project, } - insert_stmt = insert(table).values( - values, - ) - conn.execute(insert_stmt) + try: + with conn.begin_nested(): + conn.execute(insert(table).values(values)) + except IntegrityError: + logger.info( + "Object %s in project %s already created by another " + "process, skipping.", + name, + project, + ) if not isinstance(obj, Project): self.apply_project( @@ -1097,18 +1586,44 @@ def _list_objects( python_class: Any, proto_field_name: str, tags: Optional[dict[str, str]] = None, + proto_only: bool = False, + skip_udf: bool = False, ): + """ + Args: + proto_only: If True, return raw protobuf objects without calling + from_proto(). Used by proto() to build the RegistryProto cache + efficiently — avoids the from_proto()/to_proto() round-trip and + works uniformly for all object types (entities, data sources, etc.). + skip_udf: If True, call from_proto() but skip deserializing UDFs + (dill.loads). Returns Python objects suitable for filtering and + display without requiring the UDF's source module to be installed. + Only relevant for feature view types that contain UDFs. + """ + import inspect + + supports_skip_udf = ( + skip_udf + and "skip_udf" in inspect.signature(python_class.from_proto).parameters + ) + with self.read_engine.begin() as conn: stmt = select(table).where(table.c.project_id == project) rows = conn.execute(stmt).all() if rows: objects = [] for row in rows: - obj = python_class.from_proto( - proto_class.FromString(row._mapping[proto_field_name]) - ) - if utils.has_all_tags(obj.tags, tags): - objects.append(obj) + proto = proto_class.FromString(row._mapping[proto_field_name]) + if proto_only: + objects.append(proto) + else: + obj = ( + python_class.from_proto(proto, skip_udf=True) + if supports_skip_udf + else python_class.from_proto(proto) + ) + if utils.has_all_tags(obj.tags, tags): + objects.append(obj) return objects return [] @@ -1179,7 +1694,7 @@ def _get_permission(self, name: str, project: str) -> Permission: ) def _list_permissions( - self, project: str, tags: Optional[dict[str, str]] + self, project: str, tags: Optional[dict[str, str]], **kwargs ) -> List[Permission]: return self._list_objects( permissions, @@ -1188,6 +1703,7 @@ def _list_permissions( Permission, "permission_proto", tags=tags, + **kwargs, ) def apply_permission( @@ -1265,6 +1781,7 @@ def delete_project( feature_views, on_demand_feature_views, stream_feature_views, + label_views, data_sources, entities, permissions, diff --git a/sdk/python/feast/infra/utils/postgres/postgres_config.py b/sdk/python/feast/infra/utils/postgres/postgres_config.py index a4ebb456ef1..60099ede999 100644 --- a/sdk/python/feast/infra/utils/postgres/postgres_config.py +++ b/sdk/python/feast/infra/utils/postgres/postgres_config.py @@ -21,7 +21,7 @@ class PostgreSQLConfig(FeastConfigBaseModel): db_schema: StrictStr = "public" user: StrictStr password: StrictStr - sslmode: Optional[StrictStr] = None + sslmode: Optional[StrictStr] = "require" sslkey_path: Optional[StrictStr] = None sslcert_path: Optional[StrictStr] = None sslrootcert_path: Optional[StrictStr] = None diff --git a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_creation.sql b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_creation.sql index fc13332e4b0..e38d21f96cf 100644 --- a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_creation.sql +++ b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_creation.sql @@ -97,3 +97,12 @@ CREATE TABLE IF NOT EXISTS REGISTRY_PATH."PERMISSIONS" ( permission_proto BINARY NOT NULL, PRIMARY KEY (permission_name, project_id) ); + +CREATE TABLE IF NOT EXISTS REGISTRY_PATH."LABEL_VIEWS" ( + label_view_name VARCHAR, + project_id VARCHAR, + last_updated_timestamp TIMESTAMP_LTZ NOT NULL, + label_view_proto BINARY NOT NULL, + user_metadata BINARY, + PRIMARY KEY (label_view_name, project_id) +); diff --git a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_deletion.sql b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_deletion.sql index 780424abd17..76d5029b50a 100644 --- a/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_deletion.sql +++ b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_deletion.sql @@ -1,3 +1,5 @@ +DROP TABLE IF EXISTS REGISTRY_PATH."PROJECTS"; + DROP TABLE IF EXISTS REGISTRY_PATH."DATA_SOURCES"; DROP TABLE IF EXISTS REGISTRY_PATH."ENTITIES"; @@ -16,6 +18,8 @@ DROP TABLE IF EXISTS REGISTRY_PATH."SAVED_DATASETS"; DROP TABLE IF EXISTS REGISTRY_PATH."STREAM_FEATURE_VIEWS"; -DROP TABLE IF EXISTS REGISTRY_PATH."VALIDATION_REFERENCES" +DROP TABLE IF EXISTS REGISTRY_PATH."VALIDATION_REFERENCES"; + +DROP TABLE IF EXISTS REGISTRY_PATH."PERMISSIONS"; -DROP TABLE IF EXISTS REGISTRY_PATH."PERMISSIONS" +DROP TABLE IF EXISTS REGISTRY_PATH."LABEL_VIEWS"; diff --git a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py index b9254e72699..e22d4857a19 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py +++ b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py @@ -76,19 +76,15 @@ def __enter__(self): kwargs.update((k, v) for k, v in config_dict.items() if v is not None) - for k, v in kwargs.items(): - if k in ["role", "warehouse", "database", "schema_"]: - kwargs[k] = f'"{v}"' - kwargs["schema"] = kwargs.pop("schema_") # https://docs.snowflake.com/en/user-guide/python-connector-example.html#using-key-pair-authentication-key-pair-rotation # https://docs.snowflake.com/en/user-guide/key-pair-auth.html#configuring-key-pair-authentication if "private_key" in kwargs or "private_key_content" in kwargs: kwargs["private_key"] = parse_private_key_path( - kwargs.get("private_key_passphrase"), - kwargs.get("private_key"), - kwargs.get("private_key_content"), + kwargs.pop("private_key_passphrase", None), + kwargs.pop("private_key", None), + kwargs.pop("private_key_content", None), ) try: diff --git a/sdk/python/feast/labeling/__init__.py b/sdk/python/feast/labeling/__init__.py new file mode 100644 index 00000000000..de55d970ef2 --- /dev/null +++ b/sdk/python/feast/labeling/__init__.py @@ -0,0 +1,11 @@ +"""Labeling primitives for mutable annotations decoupled from immutable feature data.""" + +from feast.labeling.conflict_policy import ConflictPolicy +from feast.labeling.conflict_resolver import resolve_conflicts +from feast.labeling.label_view import LabelView + +__all__ = [ + "ConflictPolicy", + "LabelView", + "resolve_conflicts", +] diff --git a/sdk/python/feast/labeling/conflict_policy.py b/sdk/python/feast/labeling/conflict_policy.py new file mode 100644 index 00000000000..de81e2d4afc --- /dev/null +++ b/sdk/python/feast/labeling/conflict_policy.py @@ -0,0 +1,66 @@ +from enum import Enum + +from feast.protos.feast.core.LabelView_pb2 import ( + ConflictResolutionPolicy as ConflictResolutionPolicyProto, +) + + +class ConflictPolicy(Enum): + """Determines how conflicting labels from different labelers are resolved. + + When multiple labelers write labels for the same entity key, the conflict + policy controls which resolved value is returned for offline/batch reads + (training data generation, UI browse, quality metrics). + + .. note:: + + **Enforcement scope:** The conflict policy is enforced for **offline + store reads** — all batch queries (``pull_all_from_table_or_query``, + UI endpoints, training data generation) apply the configured resolution + strategy. The **online store** always uses ``LAST_WRITE_WINS`` semantics + regardless of this setting, as labeling is primarily a training-time + concern. + + Attributes: + LAST_WRITE_WINS: The most recently written label for a given entity key + takes precedence, regardless of which labeler wrote it. + LABELER_PRIORITY: Labels are ranked by a pre-configured labeler priority + order. Higher-priority labelers override lower-priority ones. + MAJORITY_VOTE: The label value that appears most frequently across all + labelers is selected. Useful for consensus-based annotation workflows. + """ + + LAST_WRITE_WINS = "last_write_wins" + LABELER_PRIORITY = "labeler_priority" + MAJORITY_VOTE = "majority_vote" + + def to_proto(self) -> int: + """Converts this ConflictPolicy to its protobuf enum value. + + Returns: + The integer protobuf enum value corresponding to this policy. + """ + return _POLICY_TO_PROTO[self] + + @classmethod + def from_proto(cls, proto_val: int) -> "ConflictPolicy": + """Creates a ConflictPolicy from a protobuf enum value. + + Args: + proto_val: The integer protobuf enum value. + + Returns: + The ConflictPolicy corresponding to the given protobuf value. + """ + return _PROTO_TO_POLICY[proto_val] + + +_POLICY_TO_PROTO = { + ConflictPolicy.LAST_WRITE_WINS: ConflictResolutionPolicyProto.LAST_WRITE_WINS, + ConflictPolicy.LABELER_PRIORITY: ConflictResolutionPolicyProto.LABELER_PRIORITY, + ConflictPolicy.MAJORITY_VOTE: ConflictResolutionPolicyProto.MAJORITY_VOTE, +} + +_PROTO_TO_POLICY: dict[int, ConflictPolicy] = { + v: k for k, v in _POLICY_TO_PROTO.items() +} diff --git a/sdk/python/feast/labeling/conflict_resolver.py b/sdk/python/feast/labeling/conflict_resolver.py new file mode 100644 index 00000000000..854500a52bd --- /dev/null +++ b/sdk/python/feast/labeling/conflict_resolver.py @@ -0,0 +1,157 @@ +"""Offline-store conflict resolution for LabelView labels. + +Applies the configured ConflictPolicy to a DataFrame containing all historical +label rows (from pull_all_from_table_or_query), producing one resolved row per +entity key. + +The online store continues to use LAST_WRITE_WINS regardless of policy — this +resolver is for offline/batch reads used in training data generation, the UI +browse/quality endpoints, and any batch pipeline consuming resolved labels. +""" + +from typing import List, Optional + +import pandas as pd + +from feast.labeling.conflict_policy import ConflictPolicy + + +def resolve_conflicts( + df: pd.DataFrame, + join_key_columns: List[str], + feature_name_columns: List[str], + timestamp_field: str, + labeler_field: str, + conflict_policy: ConflictPolicy, + labeler_priorities: Optional[List[str]] = None, +) -> pd.DataFrame: + """Resolve label conflicts by applying the configured policy. + + Args: + df: Full history DataFrame (all rows, not deduplicated). + join_key_columns: Entity key column names. + feature_name_columns: Label/feature column names. + timestamp_field: Event timestamp column name. + labeler_field: Column identifying who wrote the label. + conflict_policy: The resolution strategy to apply. + labeler_priorities: Ordered list of labelers from highest to lowest + priority. Required for LABELER_PRIORITY policy. + + Returns: + DataFrame with one resolved row per unique entity key combination. + """ + if df.empty: + return df + + if conflict_policy == ConflictPolicy.LAST_WRITE_WINS: + return _resolve_last_write_wins(df, join_key_columns, timestamp_field) + elif conflict_policy == ConflictPolicy.LABELER_PRIORITY: + return _resolve_labeler_priority( + df, join_key_columns, timestamp_field, labeler_field, labeler_priorities + ) + elif conflict_policy == ConflictPolicy.MAJORITY_VOTE: + return _resolve_majority_vote( + df, join_key_columns, feature_name_columns, timestamp_field + ) + else: + return _resolve_last_write_wins(df, join_key_columns, timestamp_field) + + +def _resolve_last_write_wins( + df: pd.DataFrame, + join_key_columns: List[str], + timestamp_field: str, +) -> pd.DataFrame: + """Keep only the row with the latest timestamp per entity.""" + df_sorted = df.sort_values(timestamp_field, ascending=False) + return df_sorted.drop_duplicates(subset=join_key_columns, keep="first").reset_index( + drop=True + ) + + +def _resolve_labeler_priority( + df: pd.DataFrame, + join_key_columns: List[str], + timestamp_field: str, + labeler_field: str, + labeler_priorities: Optional[List[str]] = None, +) -> pd.DataFrame: + """Pick the label from the highest-priority labeler per entity. + + If multiple rows exist from the same priority labeler, the latest timestamp + wins. Labelers not in the priority list are ranked lowest. + """ + if not labeler_priorities: + return _resolve_last_write_wins(df, join_key_columns, timestamp_field) + + priority_map = {name: i for i, name in enumerate(labeler_priorities)} + max_priority = len(labeler_priorities) + + df = df.copy() + df["_priority_rank"] = df[labeler_field].map( + lambda x: priority_map.get(x, max_priority) + ) + df_sorted = df.sort_values( + ["_priority_rank", timestamp_field], ascending=[True, False] + ) + result = df_sorted.drop_duplicates(subset=join_key_columns, keep="first") + result = result.drop(columns=["_priority_rank"]) + return result.reset_index(drop=True) + + +def _resolve_majority_vote( + df: pd.DataFrame, + join_key_columns: List[str], + feature_name_columns: List[str], + timestamp_field: str, +) -> pd.DataFrame: + """For each entity, pick the most common value per feature column. + + Uses the most frequent value across all labelers for each feature. + Ties are broken by recency (latest timestamp wins). + """ + if not feature_name_columns: + return _resolve_last_write_wins(df, join_key_columns, timestamp_field) + + groups = df.groupby(join_key_columns, sort=False) + resolved_rows = [] + + for keys, group in groups: + if not isinstance(keys, tuple): + keys = (keys,) + row = dict(zip(join_key_columns, keys)) + + for col in feature_name_columns: + value_counts = group[col].value_counts() + if value_counts.empty: + row[col] = None + continue + top_value = value_counts.index[0] + top_count = value_counts.iloc[0] + + # Tie-breaking: if multiple values have the same count, pick the + # one with the most recent timestamp + tied = value_counts[value_counts == top_count] + if len(tied) > 1: + tied_values = tied.index.tolist() + tied_rows = group[group[col].isin(tied_values)] + latest_row = tied_rows.sort_values( + timestamp_field, ascending=False + ).iloc[0] + row[col] = latest_row[col] + else: + row[col] = top_value + + row[timestamp_field] = group[timestamp_field].max() + if "labeler" in group.columns and "labeler" not in join_key_columns: + row["labeler"] = "majority_vote" + + resolved_rows.append(row) + + if not resolved_rows: + return df.head(0) + + result = pd.DataFrame(resolved_rows) + # Preserve column order from original + cols = [c for c in df.columns if c in result.columns] + return result[cols].reset_index(drop=True) diff --git a/sdk/python/feast/labeling/label_view.py b/sdk/python/feast/labeling/label_view.py new file mode 100644 index 00000000000..e2796006422 --- /dev/null +++ b/sdk/python/feast/labeling/label_view.py @@ -0,0 +1,446 @@ +import copy +import warnings +from datetime import timedelta +from typing import Any, Dict, List, Optional, Type + +from google.protobuf.duration_pb2 import Duration +from google.protobuf.message import Message +from typeguard import typechecked + +from feast.base_feature_view import BaseFeatureView +from feast.data_source import DataSource +from feast.entity import Entity +from feast.feature_view_projection import FeatureViewProjection +from feast.field import Field +from feast.labeling.conflict_policy import ConflictPolicy +from feast.proto_utils import serialize_data_source +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto +from feast.protos.feast.core.LabelView_pb2 import LabelViewMeta as LabelViewMetaProto +from feast.protos.feast.core.LabelView_pb2 import LabelViewSpec as LabelViewSpecProto +from feast.types import String as FeastString +from feast.types import from_value_type +from feast.value_type import ValueType + +warnings.simplefilter("once", DeprecationWarning) + + +@typechecked +class LabelView(BaseFeatureView): + """A LabelView manages mutable labels decoupled from immutable feature data. + + A LabelView defines a mutable set of labels or annotations that are kept + separate from the immutable feature data stored in regular FeatureViews. + It supports multi-labeler workflows where different sources (human reviewers, + automated safety scanners, reward models) can independently write labels for + the same entity keys. + + .. note:: + + **Enforcement scope:** + + - ``conflict_policy`` is enforced for **offline store reads** (training + data generation, UI browse/quality endpoints, batch pipelines). The + online store always uses LAST_WRITE_WINS for low-latency serving. + - The offline store always retains full write history (all writes are + appended). The online store keeps only the latest value per entity key. + + Attributes: + name: The unique name of the label view. + entities: The list of entity names associated with this label view. + ttl: How long labels are valid for online serving. ``timedelta(0)`` + means labels never expire. + source: The data source (typically a ``PushSource``) feeding label data. + entity_columns: The entity key columns in the schema. + features: The label columns (non-entity fields in the schema). + online: Whether labels are served from the online store. + description: A human-readable description. + tags: Arbitrary key-value metadata. + owner: Owner email or identifier. + labeler_field: Name of the schema field that identifies who wrote the + label (default ``"labeler"``). + conflict_policy: How conflicting labels from different labelers are + resolved (default ``ConflictPolicy.LAST_WRITE_WINS``). Enforced for + offline store reads (training, UI). Online store uses LAST_WRITE_WINS. + reference_feature_view: Optional name of the ``FeatureView`` whose + entities this label view annotates. + """ + + name: str + entities: List[str] + ttl: Optional[timedelta] + source: Optional[DataSource] + entity_columns: List[Field] + features: List[Field] + online: bool + description: str + tags: Dict[str, str] + owner: str + + labeler_field: str + conflict_policy: ConflictPolicy + reference_feature_view: Optional[str] + + def __init__( + self, + *, + name: str, + source: Optional[DataSource] = None, + schema: Optional[List[Field]] = None, + entities: Optional[List[Entity]] = None, + ttl: Optional[timedelta] = timedelta(days=0), + online: bool = True, + description: str = "", + tags: Optional[Dict[str, str]] = None, + owner: str = "", + labeler_field: str = "labeler", + conflict_policy: ConflictPolicy = ConflictPolicy.LAST_WRITE_WINS, + reference_feature_view: Optional[str] = None, + ): + """Creates a LabelView object. + + Args: + name: The unique name of this label view. + source: The data source for ingesting labels, typically a + ``PushSource``. If ``None``, labels can only be written + programmatically via ``FeatureStore.push()``. + schema: The list of ``Field`` objects describing both entity + columns and label columns. Entity columns are identified + by matching against entity join keys. + entities: The list of ``Entity`` objects whose join keys are + used to key the labels. + ttl: The time-to-live for labels in the online store. + ``timedelta(0)`` means labels never expire. ``None`` means + the label view inherits the default TTL. + online: Whether this label view should be materialized to the + online store for low-latency serving. + description: A human-readable description of what the labels + represent. + tags: A dictionary of key-value pairs for arbitrary metadata. + owner: The owner of this label view, typically an email address. + labeler_field: The name of the field in the schema that + identifies the labeler. Defaults to ``"labeler"``. + conflict_policy: The policy for resolving conflicting labels + from different labelers. Defaults to + ``ConflictPolicy.LAST_WRITE_WINS``. Enforced for offline + store reads (training, UI). Online store uses LAST_WRITE_WINS. + reference_feature_view: The name of the ``FeatureView`` whose + entities this label view annotates. This is informational + and does not create a hard dependency. + """ + self.ttl = ttl + self.entities = [] + self.source = source + + schema = schema or [] + + features: List[Field] = [] + self.entity_columns = [] + + join_keys: List[str] = [] + if entities: + for entity in entities: + join_keys.append(entity.join_key) + if entity.name != entity.join_key: + self.entities.append(entity.name) + else: + self.entities.append(entity.name) + + if len(set(join_keys)) < len(join_keys): + raise ValueError( + "A label view should not have entities that share a join key." + ) + + for field in schema: + if field.name in join_keys: + self.entity_columns.append(field) + matching_entities = ( + [e for e in entities if e.join_key == field.name] + if entities + else [] + ) + if matching_entities: + entity = matching_entities[0] + if entity.value_type != ValueType.UNKNOWN: + if from_value_type(entity.value_type) != field.dtype: + raise ValueError( + f"Entity {entity.name} has type {entity.value_type}, " + f"which does not match the inferred type {field.dtype}." + ) + else: + features.append(field) + + existing_entity_col_names = {ec.name for ec in self.entity_columns} + for jk in join_keys: + if jk not in existing_entity_col_names: + matching = [e for e in entities if e.join_key == jk] if entities else [] + if matching and matching[0].value_type != ValueType.UNKNOWN: + dtype = from_value_type(matching[0].value_type) + else: + dtype = FeastString + self.entity_columns.append(Field(name=jk, dtype=dtype)) + + self.labeler_field = labeler_field + self.conflict_policy = conflict_policy + self.reference_feature_view = reference_feature_view or "" + + super().__init__( + name=name, + features=features, + description=description, + tags=tags, + owner=owner, + source=source, + ) + self.projection.view_type = "labelView" + self.online = online + + def __hash__(self): + return super().__hash__() + + def __copy__(self): + lv = LabelView( + name=self.name, + ttl=self.ttl, + source=self.source, + schema=self.schema, + tags=self.tags, + online=self.online, + description=self.description, + owner=self.owner, + labeler_field=self.labeler_field, + conflict_policy=self.conflict_policy, + reference_feature_view=self.reference_feature_view or None, + ) + lv.entities = list(self.entities) + lv.features = copy.copy(self.features) + lv.entity_columns = copy.copy(self.entity_columns) + lv.projection = copy.copy(self.projection) + lv.version = self.version + lv.current_version_number = self.current_version_number + return lv + + def __eq__(self, other): + if not isinstance(other, LabelView): + raise TypeError("Comparisons should only involve LabelView class objects.") + + if not super().__eq__(other): + return False + + if ( + sorted(self.entities) != sorted(other.entities) + or self.ttl != other.ttl + or self.online != other.online + or sorted(self.entity_columns) != sorted(other.entity_columns) + or self.labeler_field != other.labeler_field + or self.conflict_policy != other.conflict_policy + or self.reference_feature_view != other.reference_feature_view + ): + return False + + return True + + @property + def join_keys(self) -> List[str]: + """The entity join key column names for this label view.""" + return [ec.name for ec in self.entity_columns] + + @property + def schema(self) -> List[Field]: + """The full schema including both entity columns and label columns.""" + return list(set(self.entity_columns + self.features)) + + @property + def batch_source(self) -> Optional[DataSource]: + """The batch data source for this label view. + + If the source is a ``PushSource``, returns its underlying + ``batch_source``. Otherwise returns the source directly. + This property enables compatibility with offline store + ``get_historical_features`` implementations. + """ + from feast.data_source import PushSource + + if self.source is None: + return None + if isinstance(self.source, PushSource): + return self.source.batch_source + return self.source + + @property + def stream_source(self) -> Optional[DataSource]: + """The stream data source for this label view. + + Returns the source if it is a ``PushSource``, ``None`` otherwise. + """ + from feast.data_source import PushSource + + if self.source is not None and isinstance(self.source, PushSource): + return self.source + return None + + # --- Labeling method helpers (parsed from tags) --- + + _TAG_PREFIX_PROFILE = "feast.io/labeling-method" + _TAG_PREFIX_ROLE = "feast.io/field-role:" + _TAG_PREFIX_VALUES = "feast.io/label-values:" + _TAG_PREFIX_WIDGET = "feast.io/label-widget:" + + @property + def labeling_method(self) -> str: + """The labeling method for this label view. + + Parsed from the ``feast.io/labeling-method`` tag. Supported + methods: ``table`` (default), ``document-span``, + ``entity-form``, ``active-learning``. + """ + return self.tags.get(self._TAG_PREFIX_PROFILE, "table") + + @property + def annotation_config(self) -> Dict[str, Any]: + """Structured annotation configuration derived from tags. + + Returns a dict with:: + + { + "profile": "document-span", + "field_roles": {"source_document": "content_ref", ...}, + "label_values": {"relevance": ["relevant", "irrelevant"]}, + "label_widgets": {"relevance": "binary", ...}, + } + """ + field_roles: Dict[str, str] = {} + label_values: Dict[str, List[str]] = {} + label_widgets: Dict[str, str] = {} + + for key, value in self.tags.items(): + if key.startswith(self._TAG_PREFIX_ROLE): + field_name = key[len(self._TAG_PREFIX_ROLE) :] + field_roles[field_name] = value + elif key.startswith(self._TAG_PREFIX_VALUES): + field_name = key[len(self._TAG_PREFIX_VALUES) :] + label_values[field_name] = [v.strip() for v in value.split(",")] + elif key.startswith(self._TAG_PREFIX_WIDGET): + field_name = key[len(self._TAG_PREFIX_WIDGET) :] + label_widgets[field_name] = value + + return { + "profile": self.labeling_method, + "field_roles": field_roles, + "label_values": label_values, + "label_widgets": label_widgets, + } + + def ensure_valid(self): + """Validates the label view configuration. + + Raises: + ValueError: If the label view has no name (from ``BaseFeatureView``) + or no entities. + """ + super().ensure_valid() + if not self.entities: + raise ValueError("Label view has no entities.") + + @property + def proto_class(self) -> Type[Message]: + """The protobuf message class for LabelView.""" + return LabelViewProto + + def to_proto(self) -> LabelViewProto: + """Converts this LabelView to its protobuf representation. + + Returns: + A ``LabelViewProto`` message with the spec and metadata populated. + """ + meta = LabelViewMetaProto() + if self.created_timestamp: + meta.created_timestamp.FromDatetime(self.created_timestamp) + if self.last_updated_timestamp: + meta.last_updated_timestamp.FromDatetime(self.last_updated_timestamp) + + ttl_duration = None + if self.ttl is not None: + ttl_duration = Duration() + ttl_duration.FromTimedelta(self.ttl) + + source_proto = serialize_data_source(self.source) + + spec = LabelViewSpecProto( + name=self.name, + entities=self.entities, + entity_columns=[field.to_proto() for field in self.entity_columns], + features=[feature.to_proto() for feature in self.features], + description=self.description, + tags=self.tags, + owner=self.owner, + ttl=(ttl_duration if ttl_duration is not None else None), + online=self.online, + source=source_proto, + labeler_field=self.labeler_field, + conflict_policy=self.conflict_policy.to_proto(), # type: ignore[arg-type] + reference_feature_view=self.reference_feature_view or "", + ) + + return LabelViewProto(spec=spec, meta=meta) + + @classmethod + def from_proto(cls, label_view_proto: LabelViewProto) -> "LabelView": + """Creates a LabelView from a protobuf representation. + + Args: + label_view_proto: A ``LabelViewProto`` message to deserialize. + + Returns: + A ``LabelView`` instance populated from the protobuf data. + """ + source = ( + DataSource.from_proto(label_view_proto.spec.source) + if label_view_proto.spec.HasField("source") + else None + ) + + label_view = cls( + name=label_view_proto.spec.name, + description=label_view_proto.spec.description, + tags=dict(label_view_proto.spec.tags), + owner=label_view_proto.spec.owner, + online=label_view_proto.spec.online, + ttl=( + timedelta(days=0) + if label_view_proto.spec.ttl.ToNanoseconds() == 0 + else label_view_proto.spec.ttl.ToTimedelta() + ), + source=source, + labeler_field=label_view_proto.spec.labeler_field or "labeler", + conflict_policy=ConflictPolicy.from_proto( + label_view_proto.spec.conflict_policy + ), + reference_feature_view=( + label_view_proto.spec.reference_feature_view or None + ), + ) + + label_view.entities = list(label_view_proto.spec.entities) + + label_view.features = [ + Field.from_proto(field_proto) + for field_proto in label_view_proto.spec.features + ] + label_view.entity_columns = [ + Field.from_proto(field_proto) + for field_proto in label_view_proto.spec.entity_columns + ] + + label_view.projection = FeatureViewProjection.from_definition(label_view) + label_view.projection.view_type = "labelView" + + if label_view_proto.meta.HasField("created_timestamp"): + label_view.created_timestamp = ( + label_view_proto.meta.created_timestamp.ToDatetime() + ) + if label_view_proto.meta.HasField("last_updated_timestamp"): + label_view.last_updated_timestamp = ( + label_view_proto.meta.last_updated_timestamp.ToDatetime() + ) + + return label_view diff --git a/sdk/python/feast/lineage/registry_lineage.py b/sdk/python/feast/lineage/registry_lineage.py index 9d11ab70d53..ce038f4d1ae 100644 --- a/sdk/python/feast/lineage/registry_lineage.py +++ b/sdk/python/feast/lineage/registry_lineage.py @@ -17,6 +17,7 @@ class FeastObjectType(Enum): DATA_SOURCE = "dataSource" ENTITY = "entity" FEATURE_VIEW = "featureView" + LABEL_VIEW = "labelView" FEATURE_SERVICE = "featureService" FEATURE = "feature" @@ -82,7 +83,12 @@ def _parse_direct_relationships(self, registry: Registry) -> List[EntityRelation """Parse direct relationships between objects.""" relationships = [] - # FeatureService -> FeatureView relationships + # FeatureService -> FeatureView/LabelView relationships + label_view_names = { + lv.spec.name + for lv in registry.label_views + if hasattr(lv, "spec") and lv.spec + } for feature_service in registry.feature_services: if ( hasattr(feature_service, "spec") @@ -90,10 +96,18 @@ def _parse_direct_relationships(self, registry: Registry) -> List[EntityRelation and feature_service.spec.features ): for feature in feature_service.spec.features: + view_type_str = getattr(feature, "view_type", "") + is_label_view = ( + view_type_str == "labelView" + or feature.feature_view_name in label_view_names + ) + source_type = ( + FeastObjectType.LABEL_VIEW + if is_label_view + else FeastObjectType.FEATURE_VIEW + ) rel = EntityRelation( - source=EntityReference( - FeastObjectType.FEATURE_VIEW, feature.feature_view_name - ), + source=EntityReference(source_type, feature.feature_view_name), target=EntityReference( FeastObjectType.FEATURE_SERVICE, feature_service.spec.name, @@ -307,6 +321,75 @@ def _parse_direct_relationships(self, registry: Registry) -> List[EntityRelation ) ) + # LabelView relationships + for label_view in registry.label_views: + if hasattr(label_view, "spec") and label_view.spec: + # Entity relationships + if hasattr(label_view.spec, "entities"): + for entity_name in label_view.spec.entities: + relationships.append( + EntityRelation( + source=EntityReference( + FeastObjectType.ENTITY, entity_name + ), + target=EntityReference( + FeastObjectType.LABEL_VIEW, label_view.spec.name + ), + ) + ) + + # Data source relationships: LabelView uses spec.source (PushSource) + # which contains a nested batch_source + if hasattr(label_view.spec, "source") and label_view.spec.source: + source = label_view.spec.source + # Link to the push source itself + if hasattr(source, "name") and source.name: + relationships.append( + EntityRelation( + source=EntityReference( + FeastObjectType.DATA_SOURCE, source.name + ), + target=EntityReference( + FeastObjectType.LABEL_VIEW, label_view.spec.name + ), + ) + ) + # Link to the nested batch source + if ( + hasattr(source, "batch_source") + and source.batch_source + and hasattr(source.batch_source, "name") + and source.batch_source.name + ): + relationships.append( + EntityRelation( + source=EntityReference( + FeastObjectType.DATA_SOURCE, + source.batch_source.name, + ), + target=EntityReference( + FeastObjectType.LABEL_VIEW, label_view.spec.name + ), + ) + ) + elif ( + hasattr(label_view.spec, "batch_source") + and label_view.spec.batch_source + and hasattr(label_view.spec.batch_source, "name") + and label_view.spec.batch_source.name + ): + relationships.append( + EntityRelation( + source=EntityReference( + FeastObjectType.DATA_SOURCE, + label_view.spec.batch_source.name, + ), + target=EntityReference( + FeastObjectType.LABEL_VIEW, label_view.spec.name + ), + ) + ) + return relationships def _parse_indirect_relationships( @@ -325,12 +408,16 @@ def _parse_indirect_relationships( ): for feature in feature_service.spec.features: if hasattr(feature, "feature_view_name"): - # Find all relationships that target this feature view + # Find all relationships that target this feature view or label view related_sources = [ rel.source for rel in direct_relationships if rel.target.name == feature.feature_view_name - and rel.target.type == FeastObjectType.FEATURE_VIEW + and rel.target.type + in ( + FeastObjectType.FEATURE_VIEW, + FeastObjectType.LABEL_VIEW, + ) ] # Create indirect relationships to the feature service @@ -345,25 +432,24 @@ def _parse_indirect_relationships( ) ) - # Create Entity -> DataSource relationships (through feature views) - # Build a map of feature view -> data sources + # Create Entity -> DataSource relationships (through feature views and label views) + # Build a map of view -> data sources feature_view_to_data_sources: Dict[str, List[str]] = {} for rel in direct_relationships: - if ( - rel.source.type == FeastObjectType.DATA_SOURCE - and rel.target.type == FeastObjectType.FEATURE_VIEW + if rel.source.type == FeastObjectType.DATA_SOURCE and rel.target.type in ( + FeastObjectType.FEATURE_VIEW, + FeastObjectType.LABEL_VIEW, ): if rel.target.name not in feature_view_to_data_sources: feature_view_to_data_sources[rel.target.name] = [] feature_view_to_data_sources[rel.target.name].append(rel.source.name) - # For each Entity -> FeatureView relationship, create Entity -> DataSource relationships + # For each Entity -> FeatureView/LabelView relationship, create Entity -> DataSource relationships for rel in direct_relationships: - if ( - rel.source.type == FeastObjectType.ENTITY - and rel.target.type == FeastObjectType.FEATURE_VIEW + if rel.source.type == FeastObjectType.ENTITY and rel.target.type in ( + FeastObjectType.FEATURE_VIEW, + FeastObjectType.LABEL_VIEW, ): - # Find data sources that this feature view uses if rel.target.name in feature_view_to_data_sources: for data_source_name in feature_view_to_data_sources[ rel.target.name diff --git a/sdk/python/feast/loaders/yaml.py b/sdk/python/feast/loaders/yaml.py deleted file mode 100644 index 624bc47d49c..00000000000 --- a/sdk/python/feast/loaders/yaml.py +++ /dev/null @@ -1,77 +0,0 @@ -import yaml - - -def yaml_loader(yml, load_single=False): - """ - Loads one or more Feast resources from a YAML path or string. Multiple resources - can be divided by three hyphens '---' - - Args: - yml: A path ending in .yaml or .yml, or a YAML string - load_single: Expect only a single YAML resource, fail otherwise - - Returns: - Either a single YAML dictionary or a list of YAML dictionaries - - """ - - yml_content = _get_yaml_contents(yml) - yaml_strings = yml_content.strip("---").split("---") - - # Return a single resource dict - if load_single: - if len(yaml_strings) > 1: - raise Exception( - f"More than one YAML file is being loaded when only a single file is supported: ${yaml_strings}" - ) - return _yaml_to_dict(yaml_strings[0]) - - # Return a list of resource dicts - resources = [] - for yaml_string in yaml_strings: - resources.append(_yaml_to_dict(yaml_string)) - return resources - - -def _get_yaml_contents(yml: str) -> str: - """ - Returns the YAML contents from an object. If a path ending with .yaml or - .yml is passed, it will be read for its contents. If a string containing - YAML is passed, that will be returned. - - Args: - yml: Path of YAML file or string containing YAML - - Returns: - String object containing YAML - """ - if ( - isinstance(yml, str) - and yml.count("\n") == 0 - and (".yaml" in yml.lower() or ".yml" in yml.lower()) - ): - with open(yml, "r") as f: - yml_content = f.read() - - elif isinstance(yml, str): - yml_content = yml - else: - raise Exception( - f"Invalid YAML provided. Please provide either a file path or YAML string.\n" - f"Provided YAML: {yml}" - ) - return yml_content - - -def _yaml_to_dict(yaml_string): - """ - Converts a yaml string to dictionary - - Args: - yaml_string: String containing YAML - - Returns: - Dictionary containing the same object - """ - - return yaml.safe_load(yaml_string) diff --git a/sdk/python/feast/metrics.py b/sdk/python/feast/metrics.py index be2b068d32c..13a855d587b 100644 --- a/sdk/python/feast/metrics.py +++ b/sdk/python/feast/metrics.py @@ -42,6 +42,7 @@ """ import atexit +import json import logging import os import shutil @@ -51,7 +52,7 @@ from contextlib import contextmanager from dataclasses import dataclass from datetime import datetime, timezone -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, List, Optional import psutil @@ -123,6 +124,8 @@ class _MetricsFlags: push: bool = False materialization: bool = False freshness: bool = False + offline_features: bool = False + audit_logging: bool = False _config = _MetricsFlags() @@ -144,6 +147,8 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag push=True, materialization=True, freshness=True, + offline_features=True, + audit_logging=False, ) return _MetricsFlags( enabled=True, @@ -153,6 +158,8 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag push=getattr(metrics_config, "push", True), materialization=getattr(metrics_config, "materialization", True), freshness=getattr(metrics_config, "freshness", True), + offline_features=getattr(metrics_config, "offline_features", True), + audit_logging=getattr(metrics_config, "audit_logging", False), ) @@ -198,6 +205,11 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag "Number of entity rows per online feature request", buckets=(1, 5, 10, 25, 50, 100, 250, 500, 1000), ) +online_features_status_total = Counter( + "feast_online_features_status_total", + "Count of individual feature values by retrieval status per feature view", + ["feature_view", "status"], +) # --------------------------------------------------------------------------- # Push / write metrics @@ -211,8 +223,8 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag # --------------------------------------------------------------------------- # Materialization metrics # --------------------------------------------------------------------------- -materialization_total = Counter( - "feast_materialization_total", +materialization_result_total = Counter( + "feast_materialization_result_total", "Total materialization runs per feature view", ["feature_view", "status"], ) @@ -223,6 +235,27 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag buckets=(1.0, 5.0, 10.0, 30.0, 60.0, 120.0, 300.0, 600.0, 1800.0, 3600.0), ) +# --------------------------------------------------------------------------- +# Sub-request timing — online store reads and ODFV transformations +# --------------------------------------------------------------------------- +online_store_read_duration_seconds = Histogram( + "feast_feature_server_online_store_read_duration_seconds", + "Duration of the online store read phase in seconds (covers all table reads including parallel async)", + buckets=(0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0), +) +transformation_duration_seconds = Histogram( + "feast_feature_server_transformation_duration_seconds", + "Duration of on-demand feature view transformations on read in seconds", + ["odfv_name", "mode"], + buckets=(0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0), +) +write_transformation_duration_seconds = Histogram( + "feast_feature_server_write_transformation_duration_seconds", + "Duration of on-demand feature view transformations on write in seconds", + ["odfv_name", "mode"], + buckets=(0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0), +) + # --------------------------------------------------------------------------- # Feature freshness metrics — "max" shows the worst-case staleness across # processes (freshness is identical regardless of which process computes it). @@ -234,6 +267,33 @@ def build_metrics_flags(metrics_config: Optional[object] = None) -> _MetricsFlag multiprocess_mode="max", ) +# --------------------------------------------------------------------------- +# Offline store retrieval metrics +# --------------------------------------------------------------------------- +offline_store_request_total = Counter( + "feast_offline_store_request_total", + "Total offline store retrieval requests", + ["method", "status"], +) +offline_store_request_latency_seconds = Histogram( + "feast_offline_store_request_latency_seconds", + "Latency of offline store retrieval operations in seconds", + ["method"], + buckets=(0.1, 0.5, 1.0, 5.0, 10.0, 30.0, 60.0, 120.0, 300.0, 600.0), +) +offline_store_row_count = Histogram( + "feast_offline_store_row_count", + "Number of rows returned by offline store retrieval", + ["method"], + buckets=(100, 1000, 10000, 100000, 500000, 1000000, 5000000), +) + +# --------------------------------------------------------------------------- +# Audit logger — separate from the main feast logger so operators can +# route SOX-style audit entries to a dedicated sink. +# --------------------------------------------------------------------------- +audit_logger = logging.getLogger("feast.audit") + # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- @@ -306,6 +366,47 @@ def track_push(push_source: str, mode: str): push_request_count.labels(push_source=push_source, mode=mode).inc() +def track_online_store_read(duration_seconds: float): + """Record the duration of the online store read phase.""" + if not _config.online_features: + return + online_store_read_duration_seconds.observe(duration_seconds) + + +def track_feature_statuses( + feature_view_name: str, present_count: int, not_found_count: int +): + """Record the number of PRESENT vs NOT_FOUND feature values for a feature view.""" + if not _config.online_features: + return + if present_count > 0: + online_features_status_total.labels( + feature_view=feature_view_name, status="present" + ).inc(present_count) + if not_found_count > 0: + online_features_status_total.labels( + feature_view=feature_view_name, status="not_found" + ).inc(not_found_count) + + +def track_transformation(odfv_name: str, mode: str, duration_seconds: float): + """Record the duration of an on-demand feature view read-path transformation.""" + if not _config.online_features: + return + transformation_duration_seconds.labels(odfv_name=odfv_name, mode=mode).observe( + duration_seconds + ) + + +def track_write_transformation(odfv_name: str, mode: str, duration_seconds: float): + """Record the duration of an on-demand feature view write-path transformation.""" + if not _config.online_features: + return + write_transformation_duration_seconds.labels( + odfv_name=odfv_name, mode=mode + ).observe(duration_seconds) + + def track_materialization( feature_view_name: str, success: bool, duration_seconds: float ): @@ -313,12 +414,80 @@ def track_materialization( if not _config.materialization: return status = "success" if success else "failure" - materialization_total.labels(feature_view=feature_view_name, status=status).inc() + materialization_result_total.labels( + feature_view=feature_view_name, status=status + ).inc() materialization_duration_seconds.labels(feature_view=feature_view_name).observe( duration_seconds ) +def emit_online_audit_log( + *, + requestor_id: str, + entity_keys: List[str], + entity_count: int, + feature_views: List[str], + feature_count: int, + status: str, + latency_ms: float, +): + """Emit a structured JSON audit log entry for an online feature request.""" + if not _config.audit_logging: + return + audit_logger.info( + _json_dumps( + { + "event": "online_feature_request", + "timestamp": datetime.now(tz=timezone.utc).isoformat(), + "requestor_id": requestor_id, + "entity_keys": entity_keys, + "entity_count": entity_count, + "feature_views": feature_views, + "feature_count": feature_count, + "status": status, + "latency_ms": round(latency_ms, 2), + } + ) + ) + + +def emit_offline_audit_log( + *, + method: str, + feature_views: List[str], + feature_count: int, + row_count: int, + status: str, + start_time: str, + end_time: str, + duration_ms: float, +): + """Emit a structured JSON audit log entry for an offline feature retrieval.""" + if not _config.audit_logging: + return + audit_logger.info( + _json_dumps( + { + "event": "offline_feature_retrieval", + "timestamp": datetime.now(tz=timezone.utc).isoformat(), + "method": method, + "start_time": start_time, + "end_time": end_time, + "feature_views": feature_views, + "feature_count": feature_count, + "row_count": row_count, + "status": status, + "duration_ms": round(duration_ms, 2), + } + ) + ) + + +def _json_dumps(obj: dict) -> str: + return json.dumps(obj, separators=(",", ":")) + + def update_feature_freshness( store: "FeatureStore", ) -> None: @@ -330,8 +499,10 @@ def update_feature_freshness( """ try: feature_views = store.list_feature_views(allow_cache=True) + stream_feature_views = store.list_stream_feature_views(allow_cache=True) + all_views = feature_views + stream_feature_views now = datetime.now(tz=timezone.utc) - for fv in feature_views: + for fv in all_views: end_time = fv.most_recent_end_time if end_time is not None: if end_time.tzinfo is None: @@ -436,6 +607,8 @@ def start_metrics_server( push=True, materialization=True, freshness=True, + offline_features=True, + audit_logging=False, ) from prometheus_client import CollectorRegistry, make_wsgi_app diff --git a/sdk/python/feast/mlflow.py b/sdk/python/feast/mlflow.py new file mode 100644 index 00000000000..f6cc359ea8b --- /dev/null +++ b/sdk/python/feast/mlflow.py @@ -0,0 +1,139 @@ +""" +``feast.mlflow`` — drop-in replacement for ``import mlflow`` with Feast superpowers. + +Any function or attribute available on the ``mlflow`` module can be accessed +via ``feast.mlflow.*``. A subset of calls are **Feast-enhanced** with +automatic tagging, lineage tracking, and feature resolution: + +- ``start_run()`` — auto-tags runs with ``feast.project`` +- ``log_model()`` — auto-saves ``feast_features.json`` +- ``register_model()`` — auto-tags model versions with ``feast.feature_service`` +- ``load_model()`` — auto-links prediction runs to training runs +- ``resolve_features()`` — Feast-only: model URI → feature service name +- ``get_training_entity_df()`` — Feast-only: recover training entity data + +All other calls (``log_params``, ``log_metrics``, ``set_tag``, +``log_artifact``, ``MlflowClient``, etc.) pass through to the raw +``mlflow`` module unchanged. + +**Store resolution order** (first match wins): + +1. Explicit ``feast.mlflow.init(store)`` call +2. Most recently created ``FeatureStore`` (auto-registered) +3. ``FeatureStore(".")`` from the current working directory +""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Any, Optional + +if TYPE_CHECKING: + from feast import FeatureStore + +_logger = logging.getLogger(__name__) + +_MISSING = object() + +_client: Optional[Any] = None +_registered_store: Optional["FeatureStore"] = None + + +def _register_store(store: "FeatureStore") -> None: + """Called by ``FeatureStore.__init__`` to auto-register itself. + + This is an internal API — end users should call :func:`init` instead. + """ + global _registered_store + _registered_store = store + + +def _build_client() -> Any: + """Create a ``FeastMlflowClient`` using the best available store.""" + from feast.mlflow_integration.client import FeastMlflowClient + + store = _registered_store + if store is None: + try: + from feast import FeatureStore + + store = FeatureStore(".") + except Exception as exc: + raise RuntimeError( + "feast.mlflow could not auto-discover a FeatureStore. " + "Either call feast.mlflow.init(store), create a FeatureStore " + "before using feast.mlflow, or ensure feature_store.yaml " + "exists in the current directory." + ) from exc + + mlflow_cfg = getattr(store.config, "mlflow", None) + if mlflow_cfg is None or not mlflow_cfg.enabled: + raise RuntimeError( + "MLflow integration is not enabled. " + "Set mlflow.enabled=true in feature_store.yaml, or call " + "feast.mlflow.init(store) with a store whose config has " + "mlflow.enabled=true." + ) + + try: + return FeastMlflowClient(store) + except ImportError: + raise ImportError( + "mlflow package is not installed. " + "Install it with: pip install feast[mlflow]" + ) + + +def _ensure_client() -> Any: + """Return the cached client, creating it on first call.""" + global _client + if _client is None: + _client = _build_client() + return _client + + +def init(store: "FeatureStore") -> None: + """Bind ``feast.mlflow`` to a specific :class:`~feast.FeatureStore`. + + Call this once at the start of a notebook or script. All subsequent + ``feast.mlflow.*`` calls will use this store's MLflow configuration. + + This is **optional** — if you skip it, ``feast.mlflow`` will use the + most recently created ``FeatureStore`` automatically. + """ + global _client, _registered_store + _client = None + _registered_store = store + + +def get_active_run_id() -> Optional[str]: + """Return the active MLflow run ID, or ``None``.""" + return _ensure_client().active_run_id + + +def __getattr__(name: str) -> Any: + """Open delegation: Feast-enhanced client first, raw mlflow fallback. + + Lookup order for ``feast.mlflow.``: + + 1. If ``FeastMlflowClient`` has a public attribute *name*, return it. + This gives Feast-enhanced versions of ``start_run``, ``log_model``, + ``register_model``, ``load_model``, etc. + 2. Otherwise, fall back to the raw ``mlflow`` module. This makes + ``feast.mlflow.log_params``, ``feast.mlflow.set_tag``, + ``feast.mlflow.MlflowClient``, etc. work without any wrappers. + """ + if name.startswith("_"): + raise AttributeError(f"module 'feast.mlflow' has no attribute {name!r}") + + client = _ensure_client() + + client_attr = getattr(client, name, _MISSING) + if client_attr is not _MISSING: + return client_attr + + mlflow_attr = getattr(client._mlflow, name, _MISSING) + if mlflow_attr is not _MISSING: + return mlflow_attr + + raise AttributeError(f"module 'feast.mlflow' has no attribute {name!r}") diff --git a/sdk/python/feast/mlflow_integration/__init__.py b/sdk/python/feast/mlflow_integration/__init__.py new file mode 100644 index 00000000000..400b42ee9ba --- /dev/null +++ b/sdk/python/feast/mlflow_integration/__init__.py @@ -0,0 +1,39 @@ +""" +MLflow integration for Feast Feature Store. + +This module provides seamless integration between Feast and MLflow. When enabled +in feature_store.yaml, feature metadata is logged to MLflow +during get_historical_features and get_online_features calls. + +Usage: + Configure MLflow in your feature_store.yaml: + + project: my_project + # ... other config ... + + mlflow: + enabled: true + tracking_uri: https://mlflow.example.com # or set MLFLOW_TRACKING_URI + auto_log: true + + When ``tracking_uri`` is omitted, the ``MLFLOW_TRACKING_URI`` environment + variable is used. If neither is set, MLflow falls back to its own default. + + All functionality is accessed through ``store.mlflow``: + + - ``store.mlflow.start_run()`` — start an MLflow run pre-tagged with Feast metadata + - ``store.mlflow.log_model()`` — log a model with ``feast_features.json`` + - ``store.mlflow.resolve_features()`` — map an MLflow model to its feature service + - ``store.mlflow.get_training_entity_df()`` — reproduce training by pulling entity + data from a previous MLflow run's artifacts +""" + +from feast.mlflow_integration.config import MlflowConfig +from feast.mlflow_integration.entity_df_builder import FeastMlflowEntityDfError +from feast.mlflow_integration.model_resolver import FeastMlflowModelResolutionError + +__all__ = [ + "MlflowConfig", + "FeastMlflowModelResolutionError", + "FeastMlflowEntityDfError", +] diff --git a/sdk/python/feast/mlflow_integration/client.py b/sdk/python/feast/mlflow_integration/client.py new file mode 100644 index 00000000000..bb64fe44dd3 --- /dev/null +++ b/sdk/python/feast/mlflow_integration/client.py @@ -0,0 +1,313 @@ +from __future__ import annotations + +import json +import logging +import os +import re +import tempfile +from typing import TYPE_CHECKING, Any, Dict, List, Optional + +if TYPE_CHECKING: + import pandas as pd + + from feast import FeatureStore + +_logger = logging.getLogger(__name__) + +_FLAVOR_MAP = { + "sklearn": "sklearn", + "pytorch": "pytorch", + "xgboost": "xgboost", + "lightgbm": "lightgbm", + "tensorflow": "tensorflow", + "keras": "keras", + "pyfunc": "pyfunc", +} + + +class FeastMlflowClient: + """Single integration client for all Feast–MLflow functionality. + + Composes :class:`FeastMlflowLogger`, :class:`FeastMlflowEntityDfBuilder`, + and :class:`FeastMlflowModelResolver` so that there is exactly **one** + ``mlflow`` import and **one** ``MlflowClient`` instance. + + Access via ``store.mlflow`` or ``feast.mlflow``:: + + store = FeatureStore(".") + + with store.mlflow.start_run(run_name="training"): + df = store.get_historical_features(...).to_df() + model = train(df) + store.mlflow.log_model(model, "model") + """ + + def __init__(self, store: "FeatureStore"): + import mlflow as _mlflow_mod + + self._mlflow = _mlflow_mod + self._store = store + self._tracking_uri = store.config.mlflow.get_tracking_uri() + self._client = _mlflow_mod.MlflowClient(tracking_uri=self._tracking_uri) + self._default_experiment = store.config.project + + from feast.mlflow_integration.entity_df_builder import ( + FeastMlflowEntityDfBuilder, + ) + from feast.mlflow_integration.logger import FeastMlflowLogger + from feast.mlflow_integration.model_resolver import FeastMlflowModelResolver + + self._logger_impl = FeastMlflowLogger(store, _mlflow_mod, self._client) + self._entity_df_builder = FeastMlflowEntityDfBuilder( + store, _mlflow_mod, self._client + ) + self._model_resolver = FeastMlflowModelResolver( + store, _mlflow_mod, self._client + ) + + @property + def client(self): + """The underlying ``MlflowClient`` instance.""" + return self._client + + @property + def mlflow(self): + """Escape hatch: access the raw ``mlflow`` module.""" + return self._mlflow + + @property + def active_run_id(self) -> Optional[str]: + """Return the active MLflow run ID, or ``None``.""" + run = self._mlflow.active_run() + return run.info.run_id if run else None + + # ------------------------------------------------------------------ + # Run management + # ------------------------------------------------------------------ + + def start_run( + self, + run_name: Optional[str] = None, + tags: Optional[Dict[str, str]] = None, + **kwargs: Any, + ): + """Context manager that starts an MLflow run pre-tagged with Feast metadata. + + Sets the default Feast experiment only when a run is actually started, + avoiding global side effects during ``FeatureStore.__init__``. If the + caller already set an experiment (via ``kwargs["experiment_id"]`` or a + prior ``mlflow.set_experiment``), that choice is respected. + """ + if self._tracking_uri: + self._mlflow.set_tracking_uri(self._tracking_uri) + if "experiment_id" not in kwargs: + self._mlflow.set_experiment(self._default_experiment) + + merged_tags = {"feast.project": self._store.project} + if tags: + merged_tags.update(tags) + return self._mlflow.start_run(run_name=run_name, tags=merged_tags, **kwargs) + + # ------------------------------------------------------------------ + # Model lifecycle + # ------------------------------------------------------------------ + + def log_model( + self, + model: Any, + artifact_path: str, + flavor: str = "sklearn", + **kwargs: Any, + ): + """Log a model and auto-attach ``feast_features.json``.""" + flavor_name = _FLAVOR_MAP.get(flavor, "pyfunc") + flavor_mod = getattr(self._mlflow, flavor_name, self._mlflow.pyfunc) + flavor_mod.log_model(model, artifact_path, **kwargs) + self._log_required_features() + + def _log_required_features(self) -> None: + try: + run = self._mlflow.active_run() + if run is None: + return + tags = self._client.get_run(run.info.run_id).data.tags + refs_str = tags.get("feast.feature_refs") + if not refs_str: + return + features = [r for r in refs_str.split(",") if r] + if not features: + return + + with tempfile.TemporaryDirectory() as tmp_dir: + path = os.path.join(tmp_dir, "feast_features.json") + with open(path, "w") as f: + json.dump(features, f) + self._client.log_artifact(run.info.run_id, path, artifact_path="") + except Exception as e: + _logger.debug("Failed to log feast_features.json: %s", e) + + def register_model(self, model_uri: str, name: str): + """Register a model and auto-tag the version with ``feast.feature_service``.""" + result = self._mlflow.register_model(model_uri, name) + + try: + if result.run_id: + run = self._client.get_run(result.run_id) + fs_name = run.data.tags.get("feast.feature_service") + if fs_name: + self._client.set_model_version_tag( + name, result.version, "feast.feature_service", fs_name + ) + except Exception as e: + _logger.debug("Failed to auto-tag model version: %s", e) + + return result + + def load_model(self, model_uri: str, **kwargs: Any): + """Load a model and auto-tag the active prediction run with training lineage.""" + model = self._mlflow.pyfunc.load_model(model_uri, **kwargs) + + try: + active = self._mlflow.active_run() + if active is None: + return model + + run_id = active.info.run_id + parsed = _parse_model_uri(model_uri) + if parsed is None: + return model + + model_name, version_or_alias = parsed + try: + if version_or_alias.isdigit(): + mv = self._client.get_model_version(model_name, version_or_alias) + else: + mv = self._client.get_model_version_by_alias( + model_name, version_or_alias + ) + except Exception: + return model + + self._client.set_tag(run_id, "feast.model_name", model_name) + self._client.set_tag(run_id, "feast.model_version", str(mv.version)) + + if mv.run_id: + self._client.set_tag(run_id, "feast.training_run_id", mv.run_id) + try: + training_run = self._client.get_run(mv.run_id) + fs_name = training_run.data.tags.get("feast.feature_service") + if fs_name: + self._client.set_tag(run_id, "feast.feature_service", fs_name) + except Exception: + pass + + except Exception as e: + _logger.debug("Failed to tag prediction run with training lineage: %s", e) + + return model + + # ------------------------------------------------------------------ + # Delegated to logger + # ------------------------------------------------------------------ + + def log_feature_retrieval( + self, + feature_refs: List[str], + entity_count: int, + duration_seconds: float, + retrieval_type: str = "historical", + feature_service: Optional[Any] = None, + feature_service_name: Optional[str] = None, + ) -> bool: + """Log feature retrieval metadata to the active MLflow run.""" + return self._logger_impl.log_feature_retrieval( + feature_refs=feature_refs, + entity_count=entity_count, + duration_seconds=duration_seconds, + retrieval_type=retrieval_type, + feature_service=feature_service, + feature_service_name=feature_service_name, + ) + + def log_training_dataset( + self, + df: "pd.DataFrame", + dataset_name: str = "feast_training_data", + source: Optional[str] = None, + ) -> bool: + """Log a training DataFrame as an MLflow dataset input.""" + return self._logger_impl.log_training_dataset( + df=df, dataset_name=dataset_name, source=source + ) + + def log_apply( + self, + changed_objects: List[Any], + transition_types: Optional[Dict[str, str]] = None, + ) -> bool: + """Log a feast apply operation to MLflow.""" + return self._logger_impl.log_apply( + changed_objects=changed_objects, + transition_types=transition_types, + ) + + def log_materialize( + self, + feature_view_names: List[str], + start_date: Any, + end_date: Any, + duration_seconds: float, + incremental: bool = False, + ) -> bool: + """Log a feast materialize operation to MLflow.""" + return self._logger_impl.log_materialize( + feature_view_names=feature_view_names, + start_date=start_date, + end_date=end_date, + duration_seconds=duration_seconds, + incremental=incremental, + ) + + def log_entity_df_metadata( + self, entity_df: Any, start_date: Any = None, end_date: Any = None + ) -> None: + """Log lightweight entity_df metadata to MLflow.""" + self._logger_impl.log_entity_df_metadata(entity_df, start_date, end_date) + + def log_entity_df_artifact(self, entity_df: Any) -> None: + """Upload entity DataFrame as a parquet artifact to MLflow.""" + self._logger_impl.log_entity_df_artifact(entity_df) + + # ------------------------------------------------------------------ + # Delegated to model resolver + # ------------------------------------------------------------------ + + def resolve_features(self, model_uri: str) -> str: + """Resolve which Feast feature service a registered model needs.""" + return self._model_resolver.resolve(model_uri) + + # ------------------------------------------------------------------ + # Delegated to entity df builder + # ------------------------------------------------------------------ + + def get_training_entity_df( + self, + run_id: str, + timestamp_column: str = "event_timestamp", + max_rows: Optional[int] = None, + ) -> "pd.DataFrame": + """Pull the entity DataFrame from a past MLflow run.""" + return self._entity_df_builder.get_entity_df( + run_id=run_id, + timestamp_column=timestamp_column, + max_rows=max_rows, + ) + + +def _parse_model_uri(model_uri: str) -> Optional[tuple]: + """Parse ``models://`` into a tuple.""" + pattern = r"^models:/([^/]+)/(.+)$" + match = re.match(pattern, model_uri) + if match: + return match.group(1), match.group(2) + return None diff --git a/sdk/python/feast/mlflow_integration/config.py b/sdk/python/feast/mlflow_integration/config.py new file mode 100644 index 00000000000..db1d18eb080 --- /dev/null +++ b/sdk/python/feast/mlflow_integration/config.py @@ -0,0 +1,65 @@ +import os +from typing import Optional + +from pydantic import StrictBool, StrictInt, StrictStr + +from feast.repo_config import FeastBaseModel + +MLFLOW_TAG_MAX_LENGTH = 5000 +MLFLOW_TAG_TRUNCATION_LIMIT = MLFLOW_TAG_MAX_LENGTH - 10 +MLFLOW_TAG_TRUNCATION_SLICE = MLFLOW_TAG_MAX_LENGTH - 13 + +MLFLOW_PARAM_MAX_LENGTH = 500 +MLFLOW_PARAM_TRUNCATION_LIMIT = MLFLOW_PARAM_MAX_LENGTH - 10 +MLFLOW_PARAM_TRUNCATION_SLICE = MLFLOW_PARAM_MAX_LENGTH - 13 + +DEFAULT_ENTITY_DF_MAX_ROWS = 100_000 + + +def resolve_tracking_uri(configured_uri: Optional[str] = None) -> Optional[str]: + """Return the effective MLflow tracking URI. + + Priority: + 1. Explicitly configured URI from feature_store.yaml + 2. MLFLOW_TRACKING_URI environment variable (MLflow's native convention) + 3. None — let MLflow fall back to its own defaults (local ./mlruns) + """ + if configured_uri: + return configured_uri + return os.environ.get("MLFLOW_TRACKING_URI") + + +class MlflowConfig(FeastBaseModel): + enabled: StrictBool = False + """ bool: Whether MLflow integration is enabled. Defaults to False. """ + + tracking_uri: Optional[StrictStr] = None + """ str: MLflow tracking URI. When not set, the MLFLOW_TRACKING_URI + environment variable is used. If neither is set, MLflow falls back + to its own default (local ./mlruns directory). """ + + auto_log: StrictBool = True + """ bool: Automatically log feature retrieval metadata to the active + MLflow run when get_historical_features or get_online_features is + called. Defaults to True. """ + + auto_log_entity_df: StrictBool = False + """ bool: When True, the input entity_df (or SQL query) is recorded in + the MLflow run. Defaults to False. """ + + entity_df_max_rows: StrictInt = DEFAULT_ENTITY_DF_MAX_ROWS + """ int: Maximum number of entity DataFrame rows to save as an MLflow + artifact. DataFrames exceeding this limit are skipped to avoid + OOM and slow uploads. Defaults to 100000. """ + + log_operations: StrictBool = False + """ bool: Log feast apply and materialize operations to a separate + MLflow experiment. Opt-in to avoid noise. Defaults to False. """ + + ops_experiment_suffix: StrictStr = "-feast-ops" + """ str: Suffix appended to the project name to form the MLflow + experiment name for operation logs. Defaults to '-feast-ops'. """ + + def get_tracking_uri(self) -> Optional[str]: + """Resolve the effective tracking URI for this config instance.""" + return resolve_tracking_uri(self.tracking_uri) diff --git a/sdk/python/feast/mlflow_integration/entity_df_builder.py b/sdk/python/feast/mlflow_integration/entity_df_builder.py new file mode 100644 index 00000000000..9aa0c8ba528 --- /dev/null +++ b/sdk/python/feast/mlflow_integration/entity_df_builder.py @@ -0,0 +1,116 @@ +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Any, Optional + +import pandas as pd + +if TYPE_CHECKING: + from feast import FeatureStore + +_logger = logging.getLogger(__name__) + + +class FeastMlflowEntityDfError(Exception): + """Raised when an entity DataFrame cannot be built from an MLflow run.""" + + pass + + +class FeastMlflowEntityDfBuilder: + """Reconstructs entity DataFrames from MLflow run artifacts. + + Instantiated once inside :class:`FeastMlflowClient` and reuses its + ``MlflowClient`` — no separate ``import mlflow`` needed. + """ + + def __init__(self, store: "FeatureStore", mlflow_mod: Any, client: Any): + self._store = store + self._mlflow = mlflow_mod + self._client = client + + def get_entity_df( + self, + run_id: str, + timestamp_column: str = "event_timestamp", + max_rows: Optional[int] = None, + ) -> pd.DataFrame: + """Build an entity DataFrame from an MLflow run's artifacts. + + Convention: the run should have an artifact named ``entity_df.parquet`` + (or ``entity_df.csv``), saved automatically when + ``auto_log_entity_df: true`` is set in ``feature_store.yaml``. + + Args: + run_id: The MLflow run ID. + timestamp_column: Expected name of the timestamp column in the + entity DataFrame. + max_rows: Optional limit on number of rows to load. + + Returns: + A ``pd.DataFrame`` suitable for passing to + ``store.get_historical_features(entity_df=...)``. + + Raises: + FeastMlflowEntityDfError: If run not found or no entity data + is available on the run. + """ + from mlflow.exceptions import MlflowException + + try: + self._client.get_run(run_id) + except MlflowException as e: + raise FeastMlflowEntityDfError(f"Run '{run_id}' not found: {e}") + + df = self._try_artifact(run_id, "entity_df.parquet", "parquet") + if df is not None: + if max_rows is not None: + df = df.head(max_rows) + self._validate_timestamp_col(df, timestamp_column) + return df + + df = self._try_artifact(run_id, "entity_df.csv", "csv") + if df is not None: + if max_rows is not None: + df = df.head(max_rows) + self._validate_timestamp_col(df, timestamp_column) + return df + + raise FeastMlflowEntityDfError( + f"No entity data found for run '{run_id}'. " + f"Expected artifact 'entity_df.parquet' or 'entity_df.csv'. " + f"Ensure auto_log_entity_df is enabled in feature_store.yaml." + ) + + def _try_artifact( + self, run_id: str, artifact_name: str, fmt: str + ) -> Optional[pd.DataFrame]: + try: + local_path = self._client.download_artifacts(run_id, artifact_name) + if fmt == "parquet": + return pd.read_parquet(local_path) + if fmt == "csv": + return pd.read_csv(local_path) + _logger.warning( + "Unsupported entity DataFrame format '%s' for artifact '%s'. " + "Only 'parquet' and 'csv' are supported.", + fmt, + artifact_name, + ) + return None + except Exception as e: + _logger.debug( + "Artifact '%s' not found for run '%s': %s", + artifact_name, + run_id, + e, + ) + return None + + @staticmethod + def _validate_timestamp_col(df: pd.DataFrame, col: str) -> None: + if col not in df.columns: + raise FeastMlflowEntityDfError( + f"Entity DataFrame missing required timestamp column '{col}'. " + f"Available columns: {list(df.columns)}" + ) diff --git a/sdk/python/feast/mlflow_integration/logger.py b/sdk/python/feast/mlflow_integration/logger.py new file mode 100644 index 00000000000..e538f97c7db --- /dev/null +++ b/sdk/python/feast/mlflow_integration/logger.py @@ -0,0 +1,375 @@ +from __future__ import annotations + +import logging +import time +from datetime import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Optional + +import pandas as pd + +from feast.mlflow_integration.config import ( + MLFLOW_TAG_TRUNCATION_LIMIT, + MLFLOW_TAG_TRUNCATION_SLICE, +) + +if TYPE_CHECKING: + from feast import FeatureStore + from feast.feature_service import FeatureService + +_logger = logging.getLogger(__name__) + +_WARNING_INTERVAL_SECONDS = 300 + + +class FeastMlflowLogger: + """Handles all MLflow logging for Feast feature retrieval and operations. + + Instantiated once inside :class:`FeastMlflowClient` and reuses its + ``mlflow`` module reference and ``MlflowClient`` — no duplicate + ``import mlflow`` or client construction. + """ + + def __init__(self, store: "FeatureStore", mlflow_mod: Any, client: Any): + self._store = store + self._mlflow = mlflow_mod + self._client = client + self._tracking_uri = store.config.mlflow.get_tracking_uri() + self._consecutive_failures = 0 + self._last_warning_time = 0.0 + + def _truncate_for_tag(self, value: str) -> str: + if len(value) > MLFLOW_TAG_TRUNCATION_LIMIT: + return value[:MLFLOW_TAG_TRUNCATION_SLICE] + "..." + return value + + def _report_failure(self, msg: str, exc: Exception) -> None: + self._consecutive_failures += 1 + now = time.monotonic() + if ( + self._consecutive_failures == 1 + or (now - self._last_warning_time) >= _WARNING_INTERVAL_SECONDS + ): + _logger.warning( + "%s (failures=%d): %s", msg, self._consecutive_failures, exc + ) + self._last_warning_time = now + else: + _logger.debug("%s (failures=%d): %s", msg, self._consecutive_failures, exc) + + def _report_success(self) -> None: + self._consecutive_failures = 0 + + def log_feature_retrieval( + self, + feature_refs: List[str], + entity_count: int, + duration_seconds: float, + retrieval_type: str = "historical", + feature_service: Optional["FeatureService"] = None, + feature_service_name: Optional[str] = None, + ) -> bool: + """Log feature retrieval metadata to the active MLflow run.""" + active_run = self._mlflow.active_run() + if active_run is None: + return False + + try: + run_id = active_run.info.run_id + + if self._store.project: + self._client.set_tag(run_id, "feast.project", self._store.project) + self._client.set_tag(run_id, "feast.retrieval_type", retrieval_type) + + fs_name = None + if feature_service is not None: + fs_name = feature_service.name + elif feature_service_name is not None: + fs_name = feature_service_name + if fs_name: + self._client.set_tag(run_id, "feast.feature_service", fs_name) + + fv_names = sorted({ref.split(":")[0] for ref in feature_refs if ":" in ref}) + if fv_names: + fv_str = self._truncate_for_tag(",".join(fv_names)) + self._client.set_tag(run_id, "feast.feature_views", fv_str) + + refs_str = self._truncate_for_tag(",".join(feature_refs)) + self._client.set_tag(run_id, "feast.feature_refs", refs_str) + self._client.set_tag(run_id, "feast.entity_count", str(entity_count)) + self._client.set_tag(run_id, "feast.feature_count", str(len(feature_refs))) + + self._client.log_metric( + run_id, "feast.job_submission_sec", round(duration_seconds, 4) + ) + + self._report_success() + return True + except Exception as e: + self._report_failure("Failed to log feature retrieval to MLflow", e) + return False + + def log_training_dataset( + self, + df: pd.DataFrame, + dataset_name: str = "feast_training_data", + source: Optional[str] = None, + ) -> bool: + """Log a training DataFrame as an MLflow dataset input on the active run.""" + active_run = self._mlflow.active_run() + if active_run is None: + return False + + try: + dataset = self._mlflow.data.from_pandas( + df, + name=dataset_name, + source=source or "feast.get_historical_features", + ) + self._mlflow.log_input(dataset, context="training") + return True + except Exception as e: + self._report_failure("Failed to log training dataset to MLflow", e) + return False + + def _get_or_create_experiment(self, experiment_name: str) -> str: + exp = self._client.get_experiment_by_name(experiment_name) + if exp is not None: + return exp.experiment_id + return self._client.create_experiment(experiment_name) + + def log_apply( + self, + changed_objects: List[Any], + transition_types: Optional[Dict[str, str]] = None, + ) -> bool: + """Log a feast apply operation to a dedicated MLflow experiment.""" + try: + from feast import Entity, FeatureService + from feast.feature_view import FeatureView + + project = self._store.project + mlflow_cfg = self._store.config.mlflow + ops_suffix = mlflow_cfg.ops_experiment_suffix + + experiment_name = f"{project}{ops_suffix}" + experiment_id = self._get_or_create_experiment(experiment_name) + + fv_names: List[str] = [] + fs_names: List[str] = [] + entity_names: List[str] = [] + for obj in changed_objects: + if isinstance(obj, FeatureView): + fv_names.append(obj.name) + elif isinstance(obj, FeatureService): + fs_names.append(obj.name) + elif isinstance(obj, Entity) and obj.name != "__dummy": + entity_names.append(obj.name) + + run = self._client.create_run(experiment_id, run_name=f"apply_{project}") + run_id = run.info.run_id + try: + self._client.set_tag(run_id, "feast.operation", "apply") + self._client.set_tag(run_id, "feast.project", project) + if fv_names: + self._client.set_tag( + run_id, + "feast.feature_views_changed", + self._truncate_for_tag(",".join(fv_names)), + ) + if fs_names: + self._client.set_tag( + run_id, + "feast.feature_services_changed", + self._truncate_for_tag(",".join(fs_names)), + ) + if entity_names: + self._client.set_tag( + run_id, + "feast.entities_changed", + self._truncate_for_tag(",".join(entity_names)), + ) + self._client.log_metric( + run_id, "feast.apply.feature_views_count", len(fv_names) + ) + self._client.log_metric( + run_id, "feast.apply.feature_services_count", len(fs_names) + ) + self._client.log_metric( + run_id, "feast.apply.entities_count", len(entity_names) + ) + + if transition_types: + self._log_transition_tags( + run_id, + transition_types, + fv_names, + fs_names, + entity_names, + ) + finally: + self._client.set_terminated(run_id) + + self._report_success() + return True + except Exception as e: + self._report_failure("Failed to log apply to MLflow", e) + return False + + def _log_transition_tags( + self, + run_id: str, + transition_types: Dict[str, str], + fv_names: List[str], + fs_names: List[str], + entity_names: List[str], + ) -> None: + buckets: Dict[str, Dict[str, List[str]]] = { + "feature_views": {"created": [], "updated": [], "deleted": []}, + "feature_services": {"created": [], "updated": [], "deleted": []}, + "entities": {"created": [], "updated": [], "deleted": []}, + } + + for name in fv_names: + tt = transition_types.get(name, "").upper() + if tt in ("CREATE", "UPDATE", "DELETE"): + buckets["feature_views"][tt.lower() + "d"].append(name) + + for name in fs_names: + tt = transition_types.get(name, "").upper() + if tt in ("CREATE", "UPDATE", "DELETE"): + buckets["feature_services"][tt.lower() + "d"].append(name) + + for name in entity_names: + tt = transition_types.get(name, "").upper() + if tt in ("CREATE", "UPDATE", "DELETE"): + buckets["entities"][tt.lower() + "d"].append(name) + + for obj_type, transitions in buckets.items(): + for transition, names in transitions.items(): + if names: + self._client.set_tag( + run_id, + f"feast.{obj_type}_{transition}", + self._truncate_for_tag(",".join(names)), + ) + + def log_materialize( + self, + feature_view_names: List[str], + start_date: Optional[datetime], + end_date: datetime, + duration_seconds: float, + incremental: bool = False, + ) -> bool: + """Log a feast materialize operation to a dedicated MLflow experiment.""" + try: + project = self._store.project + mlflow_cfg = self._store.config.mlflow + ops_suffix = mlflow_cfg.ops_experiment_suffix + + experiment_name = f"{project}{ops_suffix}" + experiment_id = self._get_or_create_experiment(experiment_name) + + op_type = "materialize_incremental" if incremental else "materialize" + run = self._client.create_run( + experiment_id, run_name=f"{op_type}_{project}" + ) + run_id = run.info.run_id + try: + self._client.set_tag(run_id, "feast.operation", op_type) + self._client.set_tag(run_id, "feast.project", project) + self._client.set_tag( + run_id, + "feast.materialize.feature_views", + self._truncate_for_tag(",".join(feature_view_names)), + ) + if start_date: + self._client.log_param( + run_id, + "feast.materialize.start_date", + start_date.isoformat(), + ) + self._client.log_param( + run_id, + "feast.materialize.end_date", + end_date.isoformat(), + ) + self._client.log_metric( + run_id, + "feast.materialize.duration_sec", + round(duration_seconds, 4), + ) + finally: + self._client.set_terminated(run_id) + + self._report_success() + return True + except Exception as e: + self._report_failure("Failed to log materialize to MLflow", e) + return False + + def log_entity_df_metadata( + self, entity_df: Any, start_date: Any = None, end_date: Any = None + ) -> None: + """Log lightweight entity_df metadata to MLflow. + + Uses ``set_tag`` (not ``log_param``) so the metadata can safely be + updated when ``get_historical_features`` is called multiple times + within the same MLflow run. + """ + try: + if self._mlflow.active_run() is None: + return + run_id = self._mlflow.active_run().info.run_id + + if isinstance(entity_df, str): + if len(entity_df) > MLFLOW_TAG_TRUNCATION_LIMIT: + query = entity_df[:MLFLOW_TAG_TRUNCATION_SLICE] + "..." + else: + query = entity_df + self._client.set_tag(run_id, "feast.entity_df_query", query) + self._client.set_tag(run_id, "feast.entity_df_type", "sql") + + elif isinstance(entity_df, pd.DataFrame): + self._client.set_tag(run_id, "feast.entity_df_type", "dataframe") + self._client.set_tag( + run_id, "feast.entity_df_rows", str(len(entity_df)) + ) + cols = ",".join(entity_df.columns) + if len(cols) > MLFLOW_TAG_TRUNCATION_LIMIT: + cols = cols[:MLFLOW_TAG_TRUNCATION_SLICE] + "..." + self._client.set_tag(run_id, "feast.entity_df_columns", cols) + + elif entity_df is None and (start_date or end_date): + self._client.set_tag(run_id, "feast.entity_df_type", "range") + if start_date: + self._client.set_tag(run_id, "feast.start_date", str(start_date)) + if end_date: + self._client.set_tag(run_id, "feast.end_date", str(end_date)) + + except Exception as e: + _logger.debug("Failed to log entity_df metadata to MLflow: %s", e) + + def log_entity_df_artifact(self, entity_df: Any) -> None: + """Upload entity DataFrame as a parquet artifact to MLflow.""" + try: + import os + import tempfile + + if self._mlflow.active_run() is None: + return + if not isinstance(entity_df, pd.DataFrame): + return + + mlflow_cfg = self._store.config.mlflow + run_id = self._mlflow.active_run().info.run_id + + max_rows = mlflow_cfg.entity_df_max_rows + if len(entity_df) <= max_rows: + with tempfile.TemporaryDirectory() as tmp_dir: + path = os.path.join(tmp_dir, "entity_df.parquet") + entity_df.to_parquet(path, index=False) + self._client.log_artifact(run_id, path) + + except Exception as e: + _logger.debug("Failed to log entity_df artifact to MLflow: %s", e) diff --git a/sdk/python/feast/mlflow_integration/model_resolver.py b/sdk/python/feast/mlflow_integration/model_resolver.py new file mode 100644 index 00000000000..b2d94dccbee --- /dev/null +++ b/sdk/python/feast/mlflow_integration/model_resolver.py @@ -0,0 +1,138 @@ +from __future__ import annotations + +import json +import logging +import re +from typing import TYPE_CHECKING, Any, Optional + +if TYPE_CHECKING: + from feast import FeatureStore + +_logger = logging.getLogger(__name__) + + +class FeastMlflowModelResolutionError(Exception): + """Raised when a model URI cannot be resolved to a feature service.""" + + pass + + +class FeastMlflowModelResolver: + """Resolves MLflow model URIs to Feast feature service names. + + Instantiated once inside :class:`FeastMlflowClient` and reuses its + ``MlflowClient`` — no separate ``import mlflow`` needed. + """ + + def __init__(self, store: "FeatureStore", mlflow_mod: Any, client: Any): + self._store = store + self._mlflow = mlflow_mod + self._client = client + + def resolve(self, model_uri: str) -> str: + """Resolve the Feast feature service name for a given MLflow model URI. + + Resolution order: + 1. Model version tag ``feast.feature_service`` (explicit override). + 2. Training run tag ``feast.feature_service`` (set by auto-log). + + Args: + model_uri: MLflow model URI in the form + ``models://``. + + Raises: + FeastMlflowModelResolutionError: If URI is invalid, resolution + fails, or validation against the store fails. + """ + from mlflow.exceptions import MlflowException + + pattern = r"^models:/([^/]+)/(.+)$" + match = re.match(pattern, model_uri) + if not match: + raise FeastMlflowModelResolutionError( + f"Invalid model_uri format: '{model_uri}'. " + f"Expected 'models://'." + ) + + model_name, version_or_alias = match.group(1), match.group(2) + + try: + if version_or_alias.isdigit(): + mv = self._client.get_model_version(model_name, version_or_alias) + else: + mv = self._client.get_model_version_by_alias( + model_name, version_or_alias + ) + except MlflowException as e: + raise FeastMlflowModelResolutionError( + f"Could not resolve model '{model_uri}': {e}" + ) + + tags = mv.tags or {} + if "feast.feature_service" in tags: + fs_name = tags["feast.feature_service"] + else: + fs_name = self._resolve_from_run_tags(mv) + if fs_name is None: + raise FeastMlflowModelResolutionError( + f"Could not determine feature service for model '{model_uri}'. " + f"No 'feast.feature_service' tag found on the model version or " + f"its training run. Set the tag explicitly on the model version " + f"or ensure auto_log was enabled during training." + ) + + self._validate_feature_service(fs_name, mv) + return fs_name + + def _resolve_from_run_tags(self, model_version: Any) -> Optional[str]: + try: + run = self._client.get_run(model_version.run_id) + return run.data.tags.get("feast.feature_service") + except Exception as e: + _logger.debug("Could not read run tags for model version: %s", e) + return None + + def _validate_feature_service(self, fs_name: str, model_version: Any) -> None: + try: + fs = self._store.get_feature_service(fs_name) + except Exception: + raise FeastMlflowModelResolutionError( + f"Feature service '{fs_name}' not found in the Feast registry." + ) + + if not self._has_artifact(model_version.run_id, "feast_features.json"): + return + + try: + local_path = self._client.download_artifacts( + model_version.run_id, "feast_features.json" + ) + with open(local_path) as f: + expected_features = json.load(f) + + actual_features = [] + for proj in fs.feature_view_projections: + for feat in proj.features: + actual_features.append(f"{proj.name_to_use()}:{feat.name}") + + expected_set = set(expected_features) + actual_set = set(actual_features) + + if expected_set != actual_set: + missing = expected_set - actual_set + extra = actual_set - expected_set + raise FeastMlflowModelResolutionError( + f"Feature mismatch for service '{fs_name}'. " + f"Missing: {missing}, Extra: {extra}" + ) + except FeastMlflowModelResolutionError: + raise + except Exception as e: + _logger.debug("Could not validate feast_features.json: %s", e) + + def _has_artifact(self, run_id: str, artifact_name: str) -> bool: + try: + artifacts = self._client.list_artifacts(run_id) + return any(a.path == artifact_name for a in artifacts) + except Exception: + return False diff --git a/sdk/python/feast/monitoring/__init__.py b/sdk/python/feast/monitoring/__init__.py new file mode 100644 index 00000000000..69a921060a5 --- /dev/null +++ b/sdk/python/feast/monitoring/__init__.py @@ -0,0 +1,7 @@ +from feast.monitoring.dqm_job_manager import DQMJobManager +from feast.monitoring.metrics_calculator import MetricsCalculator + +__all__ = [ + "DQMJobManager", + "MetricsCalculator", +] diff --git a/sdk/python/feast/monitoring/dqm_job_manager.py b/sdk/python/feast/monitoring/dqm_job_manager.py new file mode 100644 index 00000000000..5a0765ffa5f --- /dev/null +++ b/sdk/python/feast/monitoring/dqm_job_manager.py @@ -0,0 +1,149 @@ +import json +import logging +import uuid +from datetime import date, datetime, timezone +from typing import Any, Dict, Optional + +logger = logging.getLogger(__name__) + +JOB_STATUS_PENDING = "pending" +JOB_STATUS_RUNNING = "running" +JOB_STATUS_COMPLETED = "completed" +JOB_STATUS_FAILED = "failed" + + +class DQMJobManager: + """DQM job manager that persists jobs via the offline store abstraction.""" + + def __init__(self, offline_store, config): + self._offline_store = offline_store + self._config = config + + def ensure_table(self) -> None: + self._offline_store.ensure_monitoring_tables(self._config) + + def submit( + self, + project: str, + job_type: str, + feature_view_name: Optional[str] = None, + parameters: Optional[Dict[str, Any]] = None, + ) -> str: + job_id = str(uuid.uuid4()) + now = datetime.now(timezone.utc) + row = { + "job_id": job_id, + "project_id": project, + "feature_view_name": feature_view_name, + "job_type": job_type, + "status": JOB_STATUS_PENDING, + "parameters": json.dumps(parameters) if parameters else None, + "metric_date": now.date(), + "started_at": None, + "completed_at": None, + "error_message": None, + "result_summary": None, + } + self._offline_store.save_monitoring_metrics(self._config, "job", [row]) + return job_id + + def get_job(self, job_id: str) -> Optional[Dict[str, Any]]: + rows = self._offline_store.query_monitoring_metrics( + config=self._config, + project="", + metric_type="job", + filters={"job_id": job_id}, + ) + if not rows: + return None + record = rows[0] + for key in ("parameters", "result_summary"): + val = record.get(key) + if isinstance(val, str): + try: + record[key] = json.loads(val) + except (json.JSONDecodeError, TypeError): + pass + return record + + def update_status( + self, + job_id: str, + status: str, + error_message: Optional[str] = None, + result_summary: Optional[Dict[str, Any]] = None, + ) -> None: + job = self.get_job(job_id) + if job is None: + return + + now = datetime.now(timezone.utc) + job["status"] = status + + if status == JOB_STATUS_RUNNING: + job["started_at"] = now + elif status in (JOB_STATUS_COMPLETED, JOB_STATUS_FAILED): + job["completed_at"] = now + + if error_message is not None: + job["error_message"] = error_message + if result_summary is not None: + job["result_summary"] = json.dumps(result_summary) + + if "parameters" in job and not isinstance(job["parameters"], str): + job["parameters"] = ( + json.dumps(job["parameters"]) if job["parameters"] else None + ) + + if isinstance(job.get("metric_date"), str): + job["metric_date"] = date.fromisoformat(job["metric_date"]) + + self._offline_store.save_monitoring_metrics(self._config, "job", [job]) + + def execute_job(self, job_id: str, monitoring_service) -> Dict[str, Any]: + """Execute a DQM job synchronously. Manages status transitions.""" + job = self.get_job(job_id) + if job is None: + raise ValueError(f"Failed to find DQM job '{job_id}'") + + self.update_status(job_id, JOB_STATUS_RUNNING) + + try: + params = job.get("parameters") or {} + job_type = job["job_type"] + project = job["project_id"] + + if job_type == "auto_compute": + result = monitoring_service.auto_compute( + project=project, + feature_view_name=job.get("feature_view_name"), + ) + elif job_type == "baseline": + result = monitoring_service.compute_baseline( + project=project, + feature_view_name=job.get("feature_view_name"), + feature_names=params.get("feature_names"), + ) + elif job_type == "compute": + result = monitoring_service.compute_metrics( + project=project, + feature_view_name=job.get("feature_view_name"), + feature_names=params.get("feature_names"), + start_date=date.fromisoformat(params["start_date"]) + if params.get("start_date") + else None, + end_date=date.fromisoformat(params["end_date"]) + if params.get("end_date") + else None, + granularity=params.get("granularity", "daily"), + set_baseline=params.get("set_baseline", False), + ) + else: + raise ValueError(f"Unknown job type '{job_type}'") + + self.update_status(job_id, JOB_STATUS_COMPLETED, result_summary=result) + return result + + except Exception as e: + self.update_status(job_id, JOB_STATUS_FAILED, error_message=str(e)) + raise diff --git a/sdk/python/feast/monitoring/metrics_calculator.py b/sdk/python/feast/monitoring/metrics_calculator.py new file mode 100644 index 00000000000..1b8b3b3e7ca --- /dev/null +++ b/sdk/python/feast/monitoring/metrics_calculator.py @@ -0,0 +1,187 @@ +import logging +import math +from typing import Dict, List, Optional, Tuple + +import numpy as np +import pyarrow as pa +import pyarrow.compute as pc + +from feast.types import PrimitiveFeastType + +logger = logging.getLogger(__name__) + + +def _safe_float(val): + """Return None for None/NaN/Inf, otherwise float.""" + if val is None: + return None + f = float(val) + if math.isnan(f) or math.isinf(f): + return None + return f + + +_NUMERIC_TYPES = { + PrimitiveFeastType.INT32, + PrimitiveFeastType.INT64, + PrimitiveFeastType.FLOAT32, + PrimitiveFeastType.FLOAT64, + PrimitiveFeastType.DECIMAL, +} + +_CATEGORICAL_TYPES = { + PrimitiveFeastType.STRING, + PrimitiveFeastType.BOOL, +} + + +class MetricsCalculator: + def __init__(self, histogram_bins: int = 20, top_n: int = 10): + self.histogram_bins = histogram_bins + self.top_n = top_n + + @staticmethod + def classify_feature(dtype) -> Optional[str]: + primitive = dtype + if hasattr(dtype, "base_type"): + primitive = dtype.base_type if dtype.base_type else dtype + + if isinstance(primitive, PrimitiveFeastType): + if primitive in _NUMERIC_TYPES: + return "numeric" + if primitive in _CATEGORICAL_TYPES: + return "categorical" + return None + + @staticmethod + def classify_feature_arrow(arrow_type: pa.DataType) -> Optional[str]: + """Classify a PyArrow data type as numeric or categorical.""" + if ( + pa.types.is_integer(arrow_type) + or pa.types.is_floating(arrow_type) + or pa.types.is_decimal(arrow_type) + ): + return "numeric" + if ( + pa.types.is_string(arrow_type) + or pa.types.is_large_string(arrow_type) + or pa.types.is_boolean(arrow_type) + ): + return "categorical" + return None + + def compute_numeric(self, array: pa.Array) -> Dict: + total = len(array) + null_count = array.null_count + result = { + "feature_type": "numeric", + "row_count": total, + "null_count": null_count, + "null_rate": null_count / total if total > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + valid = pc.drop_null(array) # type: ignore[attr-defined] + if len(valid) == 0: + return result + + float_array = pc.cast(valid, pa.float64()) + result["mean"] = _safe_float(pc.mean(float_array).as_py()) # type: ignore[attr-defined] + result["stddev"] = _safe_float(pc.stddev(float_array, ddof=1).as_py()) # type: ignore[attr-defined] + + min_max = pc.min_max(float_array) # type: ignore[attr-defined] + result["min_val"] = min_max["min"].as_py() + result["max_val"] = min_max["max"].as_py() + + quantiles = pc.quantile(float_array, q=[0.50, 0.75, 0.90, 0.95, 0.99]) # type: ignore[attr-defined] + q_values = quantiles.to_pylist() + result["p50"] = q_values[0] + result["p75"] = q_values[1] + result["p90"] = q_values[2] + result["p95"] = q_values[3] + result["p99"] = q_values[4] + + np_array = float_array.to_numpy() + counts, bin_edges = np.histogram(np_array, bins=self.histogram_bins) + result["histogram"] = { + "bins": bin_edges.tolist(), + "counts": counts.tolist(), + "bin_width": float(bin_edges[1] - bin_edges[0]) + if len(bin_edges) > 1 + else 0, + } + + return result + + def compute_categorical(self, array: pa.Array) -> Dict: + total = len(array) + null_count = array.null_count + result = { + "feature_type": "categorical", + "row_count": total, + "null_count": null_count, + "null_rate": null_count / total if total > 0 else 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + valid = pc.drop_null(array) # type: ignore[attr-defined] + if len(valid) == 0: + return result + + value_counts = pc.value_counts(valid) # type: ignore[attr-defined] + entries = [ + {"value": vc["values"].as_py(), "count": vc["counts"].as_py()} + for vc in value_counts + ] + entries.sort(key=lambda x: x["count"], reverse=True) + + unique_count = len(entries) + top_entries = entries[: self.top_n] + other_count = sum(e["count"] for e in entries[self.top_n :]) + + result["histogram"] = { + "values": top_entries, + "other_count": other_count, + "unique_count": unique_count, + } + + return result + + def compute_all( + self, + table: pa.Table, + feature_fields: List[Tuple[str, str]], + ) -> List[Dict]: + results = [] + for name, ftype in feature_fields: + if name not in table.column_names: + logger.warning("Column '%s' not found in arrow table, skipping", name) + continue + column = table.column(name) + if ftype == "numeric": + metrics = self.compute_numeric(column) + elif ftype == "categorical": + metrics = self.compute_categorical(column) + else: + continue + metrics["feature_name"] = name + results.append(metrics) + return results diff --git a/sdk/python/feast/monitoring/monitoring_service.py b/sdk/python/feast/monitoring/monitoring_service.py new file mode 100644 index 00000000000..1e284647732 --- /dev/null +++ b/sdk/python/feast/monitoring/monitoring_service.py @@ -0,0 +1,1251 @@ +import logging +import math +import time +from collections import defaultdict +from datetime import date, datetime, timedelta, timezone +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple + +from feast.feature_logging import LOG_TIMESTAMP_FIELD, FeatureServiceLoggingSource +from feast.infra.offline_stores.offline_store import OfflineStore +from feast.monitoring.dqm_job_manager import DQMJobManager +from feast.monitoring.metrics_calculator import MetricsCalculator +from feast.monitoring.monitoring_utils import build_view_aggregate + +if TYPE_CHECKING: + from feast.feature_store import FeatureStore + +logger = logging.getLogger(__name__) + +VALID_GRANULARITIES = OfflineStore.MONITORING_VALID_GRANULARITIES + +_EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc) +_FAR_FUTURE = datetime(2099, 12, 31, 23, 59, 59, tzinfo=timezone.utc) + +GRANULARITY_WINDOWS = { + "daily": timedelta(days=1), + "weekly": timedelta(days=7), + "biweekly": timedelta(days=14), + "monthly": timedelta(days=30), + "quarterly": timedelta(days=90), +} + +_FLOAT_FIELDS = frozenset( + { + "null_rate", + "mean", + "stddev", + "min_val", + "max_val", + "p50", + "p75", + "p90", + "p95", + "p99", + "avg_null_rate", + "max_null_rate", + } +) + + +def _sanitize_floats(row: Dict[str, Any]) -> Dict[str, Any]: + """Replace NaN/Inf float values with None so JSON serialization succeeds.""" + for key in _FLOAT_FIELDS: + val = row.get(key) + if isinstance(val, float) and (math.isnan(val) or math.isinf(val)): + row[key] = None + return row + + +class MonitoringService: + def __init__(self, store: "FeatureStore"): + self._store = store + self._job_manager: Optional[DQMJobManager] = None + self._calculator = MetricsCalculator() + self._monitoring_tables_ensured = False + self._offline_store_cache = None + + def _get_offline_store(self): + if self._offline_store_cache is None: + self._offline_store_cache = self._store._get_provider().offline_store + return self._offline_store_cache + + def _ensure_monitoring_tables(self): + if not self._monitoring_tables_ensured: + self._get_offline_store().ensure_monitoring_tables(self._store.config) + self._monitoring_tables_ensured = True + + @property + def job_manager(self) -> DQMJobManager: + if self._job_manager is None: + self._job_manager = DQMJobManager( + self._get_offline_store(), self._store.config + ) + self._job_manager.ensure_table() + return self._job_manager + + # ------------------------------------------------------------------ # + # Auto-compute: detect dates, compute all granularities + # ------------------------------------------------------------------ # + + def auto_compute( + self, + project: Optional[str] = None, + feature_view_name: Optional[str] = None, + ) -> Dict[str, Any]: + """Detect date ranges from source data and compute all granularities.""" + start_time = time.time() + self._ensure_monitoring_tables() + if project is None: + project = self._store.config.project + + feature_views = self._resolve_feature_views(project, feature_view_name) + total_features = 0 + total_views = 0 + granularities_computed = set() + + for fv in feature_views: + try: + feature_fields = self._classify_fields(fv) + if not feature_fields: + continue + + max_ts = self._get_max_timestamp(fv) + if max_ts is None: + logger.warning( + "No data found for feature view '%s', skipping", fv.name + ) + continue + + now = datetime.now(timezone.utc) + + for granularity, window in GRANULARITY_WINDOWS.items(): + window_start = max_ts - window + metrics_list = self._compute_feature_metrics( + fv, + feature_fields, + window_start, + max_ts, + ) + self._save_computed_metrics( + project=project, + feature_view=fv, + metrics_list=metrics_list, + metric_date=window_start.date(), + granularity=granularity, + set_baseline=False, + now=now, + ) + self._compute_feature_service_metrics( + project=project, + granularity=granularity, + metric_dates=[window_start.date()], + set_baseline=False, + ) + total_features += len(metrics_list) + granularities_computed.add(granularity) + total_views += 1 + except Exception: + logger.exception( + "Failed to auto-compute metrics for feature view '%s'", fv.name + ) + + duration_ms = int((time.time() - start_time) * 1000) + + return { + "status": "completed", + "computed_feature_views": total_views, + "computed_features": total_features, + "granularities": sorted(granularities_computed), + "duration_ms": duration_ms, + } + + # ------------------------------------------------------------------ # + # Log source: compute metrics from feature serving logs + # ------------------------------------------------------------------ # + + def compute_log_metrics( + self, + project: str, + feature_service_name: str, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + granularity: str = "daily", + set_baseline: bool = False, + ) -> Dict[str, Any]: + """Compute monitoring metrics from feature serving logs. + + Requires the feature service to have a logging_config with a + LoggingDestination that can be converted to a DataSource. + """ + self._ensure_monitoring_tables() + if granularity not in VALID_GRANULARITIES: + raise ValueError( + f"Invalid granularity '{granularity}'. " + f"Must be one of {VALID_GRANULARITIES}" + ) + + start_time = time.time() + start_dt, end_dt = self._to_date_range(start_date, end_date) + + fs = self._store.registry.get_feature_service( + name=feature_service_name, project=project + ) + log_source = self._resolve_log_source(fs) + if log_source is None: + return { + "status": "skipped", + "reason": f"Feature service '{feature_service_name}' has no logging configured", + "duration_ms": int((time.time() - start_time) * 1000), + } + + data_source, ts_field, feature_fields, log_col_map = log_source + metrics_list = self._compute_from_source( + data_source, + ts_field, + feature_fields, + start_dt, + end_dt, + ) + + now = datetime.now(timezone.utc) + metric_date = start_dt.date() + + self._save_log_metrics( + project=project, + feature_service_name=feature_service_name, + log_col_map=log_col_map, + metrics_list=metrics_list, + metric_date=metric_date, + granularity=granularity, + set_baseline=set_baseline, + now=now, + ) + + duration_ms = int((time.time() - start_time) * 1000) + return { + "status": "completed", + "data_source_type": "log", + "feature_service_name": feature_service_name, + "granularity": granularity, + "computed_features": len(metrics_list), + "metric_date": metric_date.isoformat(), + "duration_ms": duration_ms, + } + + def auto_compute_log_metrics( + self, + project: Optional[str] = None, + feature_service_name: Optional[str] = None, + ) -> Dict[str, Any]: + """Auto-detect date ranges from log data and compute all granularities.""" + start_time = time.time() + self._ensure_monitoring_tables() + if project is None: + project = self._store.config.project + + if feature_service_name: + services = [ + self._store.registry.get_feature_service( + name=feature_service_name, project=project + ) + ] + else: + services = self._store.registry.list_feature_services(project=project) + + total_features = 0 + total_services = 0 + granularities_computed: set = set() + + for fs in services: + try: + log_source = self._resolve_log_source(fs) + if log_source is None: + continue + + data_source, ts_field, feature_fields, log_col_map = log_source + + max_ts = self._get_max_timestamp_for_source(data_source, ts_field) + if max_ts is None: + logger.warning( + "No log data found for feature service '%s', skipping", + fs.name, + ) + continue + + now = datetime.now(timezone.utc) + + for gran, window in GRANULARITY_WINDOWS.items(): + window_start = max_ts - window + metrics_list = self._compute_from_source( + data_source, + ts_field, + feature_fields, + window_start, + max_ts, + ) + self._save_log_metrics( + project=project, + feature_service_name=fs.name, + log_col_map=log_col_map, + metrics_list=metrics_list, + metric_date=window_start.date(), + granularity=gran, + set_baseline=False, + now=now, + ) + total_features += len(metrics_list) + granularities_computed.add(gran) + + total_services += 1 + except Exception: + logger.exception( + "Failed to auto-compute log metrics for feature service '%s'", + fs.name, + ) + + duration_ms = int((time.time() - start_time) * 1000) + return { + "status": "completed", + "data_source_type": "log", + "computed_feature_services": total_services, + "computed_features": total_features, + "granularities": sorted(granularities_computed), + "duration_ms": duration_ms, + } + + # ------------------------------------------------------------------ # + # Baseline: compute from all available source data + # ------------------------------------------------------------------ # + + def compute_baseline( + self, + project: Optional[str] = None, + feature_view_name: Optional[str] = None, + feature_names: Optional[List[str]] = None, + ) -> Dict[str, Any]: + """Compute baseline metrics from all available source data. + + Idempotent: only features without existing baselines are computed. + """ + start_time = time.time() + self._ensure_monitoring_tables() + if project is None: + project = self._store.config.project + + feature_views = self._resolve_feature_views(project, feature_view_name) + total_features = 0 + total_views = 0 + + for fv in feature_views: + try: + fields_needing_baseline = self._get_features_without_baseline( + project, fv, feature_names + ) + if not fields_needing_baseline: + logger.info( + "All features in '%s' already have baselines, skipping", + fv.name, + ) + continue + + feature_fields = self._classify_fields( + fv, fields=fields_needing_baseline + ) + if not feature_fields: + continue + + metrics_list = self._compute_feature_metrics( + fv, + feature_fields, + _EPOCH, + _FAR_FUTURE, + ) + + now = datetime.now(timezone.utc) + self._save_computed_metrics( + project=project, + feature_view=fv, + metrics_list=metrics_list, + metric_date=date.today(), + granularity="baseline", + set_baseline=True, + now=now, + ) + + total_features += len(metrics_list) + total_views += 1 + except Exception: + logger.exception( + "Failed to compute baseline for feature view '%s'", fv.name + ) + + duration_ms = int((time.time() - start_time) * 1000) + + return { + "status": "completed", + "computed_features": total_features, + "computed_feature_views": total_views, + "is_baseline": True, + "duration_ms": duration_ms, + } + + # ------------------------------------------------------------------ # + # Compute: explicit dates + granularity (stored) + # ------------------------------------------------------------------ # + + def compute_metrics( + self, + project: str, + feature_view_name: Optional[str] = None, + feature_names: Optional[List[str]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + granularity: str = "daily", + set_baseline: bool = False, + ) -> Dict[str, Any]: + self._ensure_monitoring_tables() + if granularity not in VALID_GRANULARITIES: + raise ValueError( + f"Invalid granularity '{granularity}'. " + f"Must be one of {VALID_GRANULARITIES}" + ) + + start_time = time.time() + start_dt, end_dt = self._to_date_range(start_date, end_date) + + feature_views = self._resolve_feature_views(project, feature_view_name) + + total_features = 0 + total_views = 0 + computed_dates: set = set() + + for fv in feature_views: + try: + fv_metrics = self._compute_for_feature_view( + project=project, + feature_view=fv, + feature_names=feature_names, + start_dt=start_dt, + end_dt=end_dt, + granularity=granularity, + set_baseline=set_baseline, + ) + total_features += fv_metrics["feature_count"] + total_views += 1 + computed_dates.update(fv_metrics["dates"]) + except Exception: + logger.exception( + "Failed to compute metrics for feature view '%s'", fv.name + ) + + total_services = self._compute_feature_service_metrics( + project=project, + granularity=granularity, + metric_dates=list(computed_dates), + set_baseline=set_baseline, + ) + + duration_ms = int((time.time() - start_time) * 1000) + + return { + "status": "completed", + "granularity": granularity, + "computed_features": total_features, + "computed_feature_views": total_views, + "computed_feature_services": total_services, + "metric_dates": sorted(d.isoformat() for d in computed_dates), + "duration_ms": duration_ms, + } + + # ------------------------------------------------------------------ # + # Transient compute (not stored) + # ------------------------------------------------------------------ # + + def compute_transient( + self, + project: str, + feature_view_name: str, + feature_names: Optional[List[str]] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> Dict[str, Any]: + """Compute metrics on-the-fly for an arbitrary date range without persisting.""" + start_time = time.time() + start_dt, end_dt = self._to_date_range(start_date, end_date) + effective_start = start_date or (date.today() - timedelta(days=1)) + effective_end = end_date or date.today() + + fv = self._store.registry.get_feature_view( + name=feature_view_name, project=project + ) + + feature_fields = self._classify_fields(fv, feature_names=feature_names) + if not feature_fields: + return { + "status": "completed", + "feature_view_name": feature_view_name, + "start_date": effective_start.isoformat(), + "end_date": effective_end.isoformat(), + "metrics": [], + "duration_ms": int((time.time() - start_time) * 1000), + } + + metrics_list = self._compute_feature_metrics( + fv, + feature_fields, + start_dt, + end_dt, + ) + + for m in metrics_list: + m["feature_view_name"] = feature_view_name + m["start_date"] = effective_start.isoformat() + m["end_date"] = effective_end.isoformat() + + return { + "status": "completed", + "feature_view_name": feature_view_name, + "start_date": effective_start.isoformat(), + "end_date": effective_end.isoformat(), + "metrics": metrics_list, + "duration_ms": int((time.time() - start_time) * 1000), + } + + # ------------------------------------------------------------------ # + # DQM Job helpers + # ------------------------------------------------------------------ # + + def submit_job( + self, + project: str, + job_type: str, + feature_view_name: Optional[str] = None, + parameters: Optional[Dict[str, Any]] = None, + ) -> str: + return self.job_manager.submit( + project=project, + job_type=job_type, + feature_view_name=feature_view_name, + parameters=parameters, + ) + + def get_job(self, job_id: str) -> Optional[Dict[str, Any]]: + return self.job_manager.get_job(job_id) + + def execute_job(self, job_id: str) -> Dict[str, Any]: + return self.job_manager.execute_job(job_id, self) + + # ------------------------------------------------------------------ # + # Read helpers (delegate to offline store) + # ------------------------------------------------------------------ # + + def _query( + self, + metric_type: str, + project: str, + filters=None, + start_date=None, + end_date=None, + ): + self._ensure_monitoring_tables() + rows = self._get_offline_store().query_monitoring_metrics( + config=self._store.config, + project=project, + metric_type=metric_type, + filters=filters, + start_date=start_date, + end_date=end_date, + ) + return [_sanitize_floats(r) for r in rows] + + def get_feature_metrics( + self, + project: str, + feature_service_name: Optional[str] = None, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + granularity: Optional[str] = None, + data_source_type: Optional[str] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + filters = { + "feature_view_name": feature_view_name, + "feature_name": feature_name, + "granularity": granularity, + "data_source_type": data_source_type, + } + if feature_service_name: + return self._get_metrics_by_service( + project, + feature_service_name, + lambda fv_name: self._query( + "feature", + project, + {**filters, "feature_view_name": fv_name}, + start_date, + end_date, + ), + ) + return self._query("feature", project, filters, start_date, end_date) + + def get_feature_view_metrics( + self, + project: str, + feature_service_name: Optional[str] = None, + feature_view_name: Optional[str] = None, + granularity: Optional[str] = None, + data_source_type: Optional[str] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + filters = { + "feature_view_name": feature_view_name, + "granularity": granularity, + "data_source_type": data_source_type, + } + if feature_service_name: + return self._get_metrics_by_service( + project, + feature_service_name, + lambda fv_name: self._query( + "feature_view", + project, + {**filters, "feature_view_name": fv_name}, + start_date, + end_date, + ), + ) + return self._query("feature_view", project, filters, start_date, end_date) + + def get_feature_service_metrics( + self, + project: str, + feature_service_name: Optional[str] = None, + granularity: Optional[str] = None, + data_source_type: Optional[str] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + filters = { + "feature_service_name": feature_service_name, + "granularity": granularity, + "data_source_type": data_source_type, + } + return self._query("feature_service", project, filters, start_date, end_date) + + def get_baseline( + self, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + data_source_type: Optional[str] = None, + ) -> List[Dict[str, Any]]: + filters = { + "feature_view_name": feature_view_name, + "feature_name": feature_name, + "data_source_type": data_source_type, + "is_baseline": True, + } + return self._query("feature", project, filters) + + def get_timeseries( + self, + project: str, + feature_view_name: Optional[str] = None, + feature_name: Optional[str] = None, + feature_service_name: Optional[str] = None, + granularity: Optional[str] = None, + data_source_type: Optional[str] = None, + start_date: Optional[date] = None, + end_date: Optional[date] = None, + ) -> List[Dict[str, Any]]: + return self.get_feature_metrics( + project=project, + feature_service_name=feature_service_name, + feature_view_name=feature_view_name, + feature_name=feature_name, + granularity=granularity, + data_source_type=data_source_type, + start_date=start_date, + end_date=end_date, + ) + + # ------------------------------------------------------------------ # + # Auto-baseline trigger for feast apply + # ------------------------------------------------------------------ # + + def submit_baseline_for_new_features( + self, + project: str, + feature_views: Optional[List] = None, + ) -> List[str]: + """Submit baseline DQM jobs for feature views with new features. + + Called from feast apply. Returns list of submitted job IDs. + Idempotent — only features without existing baselines are included. + """ + if project is None: + project = self._store.config.project + + if feature_views is None: + feature_views = self._store.registry.list_feature_views(project=project) + + job_ids = [] + for fv in feature_views: + new_features = self._get_features_without_baseline(project, fv) + if not new_features: + continue + + feature_names = [f.name for f in new_features] + job_id = self.job_manager.submit( + project=project, + job_type="baseline", + feature_view_name=fv.name, + parameters={"feature_names": feature_names}, + ) + job_ids.append(job_id) + logger.info( + "Queued baseline computation for '%s' features %s (job: %s)", + fv.name, + feature_names, + job_id, + ) + + return job_ids + + # ------------------------------------------------------------------ # + # Private: compute engine dispatch (SQL push-down → Python fallback) + # ------------------------------------------------------------------ # + + def _compute_feature_metrics( + self, + feature_view, + feature_fields: List[Tuple[str, str]], + start_dt: datetime, + end_dt: datetime, + ) -> List[Dict[str, Any]]: + """Compute metrics from a feature view's batch source.""" + return self._compute_from_source( + feature_view.batch_source, + feature_view.batch_source.timestamp_field, + feature_fields, + start_dt, + end_dt, + ) + + def _get_max_timestamp(self, feature_view) -> Optional[datetime]: + """Query the batch source for MAX(event_timestamp).""" + return self._get_max_timestamp_for_source( + feature_view.batch_source, + feature_view.batch_source.timestamp_field, + ) + + # ------------------------------------------------------------------ # + # Private: shared helpers (DRY) + # ------------------------------------------------------------------ # + + @staticmethod + def _to_date_range( + start_date: Optional[date], end_date: Optional[date] + ) -> Tuple[datetime, datetime]: + today = date.today() + if end_date is None: + end_date = today + if start_date is None: + start_date = end_date - timedelta(days=1) + start_dt = datetime( + start_date.year, start_date.month, start_date.day, tzinfo=timezone.utc + ) + end_dt = datetime( + end_date.year, end_date.month, end_date.day, 23, 59, 59, tzinfo=timezone.utc + ) + return start_dt, end_dt + + @staticmethod + def _classify_fields( + feature_view, + feature_names=None, + fields=None, + ) -> List[Tuple[str, str]]: + """Extract and classify features as numeric/categorical. + + Args: + feature_view: FeatureView to extract fields from (used if fields is None). + feature_names: Optional filter list of feature names. + fields: Optional pre-selected Field objects (e.g., from idempotency check). + """ + if fields is None: + fields = feature_view.features + if feature_names: + fields = [f for f in fields if f.name in feature_names] + + result = [] + for field in fields: + ftype = MetricsCalculator.classify_feature(field.dtype) + if ftype is None: + logger.warning( + "Unsupported dtype '%s' for feature '%s', skipping", + field.dtype, + field.name, + ) + continue + result.append((field.name, ftype)) + return result + + def _save_computed_metrics( + self, + project: str, + feature_view, + metrics_list: List[Dict[str, Any]], + metric_date: date, + granularity: str, + set_baseline: bool, + now: datetime, + ) -> None: + if not metrics_list: + return + + offline_store = self._get_offline_store() + config = self._store.config + + if set_baseline: + offline_store.clear_monitoring_baseline( + config=config, + project=project, + feature_view_name=feature_view.name, + ) + + for m in metrics_list: + m["project_id"] = project + m["feature_view_name"] = feature_view.name + m["metric_date"] = metric_date + m["granularity"] = granularity + m["data_source_type"] = "batch" + m["computed_at"] = now + m["is_baseline"] = set_baseline + + offline_store.save_monitoring_metrics(config, "feature", metrics_list) + + view_metric = { + "project_id": project, + "feature_view_name": feature_view.name, + "metric_date": metric_date, + "granularity": granularity, + "data_source_type": "batch", + "computed_at": now, + "is_baseline": set_baseline, + **build_view_aggregate(metrics_list), + } + offline_store.save_monitoring_metrics(config, "feature_view", [view_metric]) + + def _resolve_join_key_columns(self, feature_view) -> List[str]: + config = self._store.config + return ( + [ + entity.name + for entity in self._store.registry.list_entities(project=config.project) + if entity.name in (feature_view.entities or []) + ] + or feature_view.entities + or [] + ) + + def _get_metrics_by_service( + self, project: str, feature_service_name: str, query_fn + ): + fs = self._store.registry.get_feature_service( + name=feature_service_name, project=project + ) + fv_names = [proj.name for proj in fs.feature_view_projections] + results = [] + for fv_name in fv_names: + results.extend(query_fn(fv_name)) + return results + + def _resolve_feature_views(self, project: str, feature_view_name: Optional[str]): + if feature_view_name: + fv = self._store.registry.get_feature_view( + name=feature_view_name, project=project + ) + return [fv] + return self._store.registry.list_feature_views(project=project) + + def _get_features_without_baseline(self, project, feature_view, feature_names=None): + existing = self.get_baseline( + project=project, + feature_view_name=feature_view.name, + ) + existing_names = {m["feature_name"] for m in existing} + + fields = feature_view.features + if feature_names: + fields = [f for f in fields if f.name in feature_names] + + return [f for f in fields if f.name not in existing_names] + + def _compute_for_feature_view( + self, + project: str, + feature_view, + feature_names: Optional[List[str]], + start_dt: datetime, + end_dt: datetime, + granularity: str, + set_baseline: bool, + ) -> Dict[str, Any]: + feature_fields = self._classify_fields( + feature_view, feature_names=feature_names + ) + if not feature_fields: + return {"feature_count": 0, "dates": set()} + + metrics_list = self._compute_feature_metrics( + feature_view, + feature_fields, + start_dt, + end_dt, + ) + + now = datetime.now(timezone.utc) + metric_date = start_dt.date() + + self._save_computed_metrics( + project=project, + feature_view=feature_view, + metrics_list=metrics_list, + metric_date=metric_date, + granularity=granularity, + set_baseline=set_baseline, + now=now, + ) + + return {"feature_count": len(metrics_list), "dates": {metric_date}} + + # ------------------------------------------------------------------ # + # Private: log source helpers + # ------------------------------------------------------------------ # + + def _resolve_log_source(self, feature_service): + """Resolve log data source for a feature service. + + Returns (DataSource, timestamp_field, feature_fields, log_col_map) + or None if the feature service has no logging configured. + + ``feature_fields`` uses the raw log column names (needed for + SQL/PyArrow column access). ``log_col_map`` maps each raw log + column to ``(feature_view_name, normalized_feature_name)`` so + callers can store metrics under the correct view and feature + name — critical for drift detection across batch and log sources. + """ + if not feature_service.logging_config: + return None + + destination = feature_service.logging_config.destination + try: + data_source = destination.to_data_source() + except NotImplementedError: + logger.warning( + "Logging destination for '%s' does not support to_data_source()", + feature_service.name, + ) + return None + + logging_source = FeatureServiceLoggingSource( + feature_service, + self._store.config.project, + ) + schema = logging_source.get_schema(self._store.registry) + + skip_cols = { + LOG_TIMESTAMP_FIELD, + "__log_date", + "__request_id", + } + entity_columns = set() + view_feature_names: dict = {} + for proj in feature_service.feature_view_projections: + view_alias = proj.name_to_use() + try: + fv = self._store.registry.get_feature_view( + name=proj.name, project=self._store.config.project + ) + for ec in fv.entity_columns: + entity_columns.add(ec.name) + except Exception: + pass + for feat in proj.features: + log_col = f"{view_alias}__{feat.name}" + view_feature_names[log_col] = (proj.name, feat.name) + + feature_fields = [] + log_col_map: dict = {} + for field in schema: + if field.name in skip_cols or field.name in entity_columns: + continue + if field.name.endswith("__timestamp") or field.name.endswith("__status"): + continue + ftype = MetricsCalculator.classify_feature_arrow(field.type) + if ftype is not None: + feature_fields.append((field.name, ftype)) + if field.name in view_feature_names: + log_col_map[field.name] = view_feature_names[field.name] + + if not feature_fields: + return None + + return data_source, LOG_TIMESTAMP_FIELD, feature_fields, log_col_map + + def _get_max_timestamp_for_source(self, data_source, ts_field): + """Get MAX timestamp from an arbitrary data source. + + Prefers the offline store's native push-down; falls back to reading + the table and computing max in Python. + """ + offline_store = self._get_offline_store() + try: + return offline_store.get_monitoring_max_timestamp( + config=self._store.config, + data_source=data_source, + timestamp_field=ts_field, + ) + except NotImplementedError: + pass + + import pyarrow.compute as pc + + retrieval_job = offline_store.pull_all_from_table_or_query( + config=self._store.config, + data_source=data_source, + join_key_columns=[], + feature_name_columns=[], + timestamp_field=ts_field, + start_date=_EPOCH, + end_date=_FAR_FUTURE, + ) + + table = retrieval_job.to_arrow() + if ts_field not in table.column_names or len(table) == 0: + return None + + max_val = pc.max(table.column(ts_field)).as_py() + if max_val is None: + return None + + if isinstance(max_val, datetime): + return max_val if max_val.tzinfo else max_val.replace(tzinfo=timezone.utc) + return datetime.combine(max_val, datetime.min.time(), tzinfo=timezone.utc) + + def _compute_from_source( + self, + data_source, + ts_field: str, + feature_fields: List[Tuple[str, str]], + start_dt: datetime, + end_dt: datetime, + ) -> List[Dict[str, Any]]: + """Compute metrics from an arbitrary data source (batch or log). + + Prefers SQL push-down; falls back to Python-based computation. + """ + offline_store = self._get_offline_store() + try: + return offline_store.compute_monitoring_metrics( + config=self._store.config, + data_source=data_source, + feature_columns=feature_fields, + timestamp_field=ts_field, + start_date=start_dt, + end_date=end_dt, + histogram_bins=self._calculator.histogram_bins, + top_n=self._calculator.top_n, + ) + except NotImplementedError: + logger.debug( + "Offline store does not support compute_monitoring_metrics, " + "falling back to Python-based computation for log source" + ) + retrieval_job = offline_store.pull_all_from_table_or_query( + config=self._store.config, + data_source=data_source, + join_key_columns=[], + feature_name_columns=[name for name, _ in feature_fields], + timestamp_field=ts_field, + start_date=start_dt, + end_date=end_dt, + ) + arrow_table = retrieval_job.to_arrow() + return self._calculator.compute_all(arrow_table, feature_fields) + + def _save_log_metrics( + self, + project: str, + feature_service_name: str, + log_col_map: Dict[str, Tuple[str, str]], + metrics_list: List[Dict[str, Any]], + metric_date: date, + granularity: str, + set_baseline: bool, + now: datetime, + ) -> None: + """Save log-sourced metrics tagged with data_source_type='log'. + + Normalizes log column names (``driver_stats__conv_rate``) back to + their originating ``feature_view_name`` and ``feature_name`` so + that drift detection can join batch and log metrics on the same + feature identity. + """ + if not metrics_list: + return + + offline_store = self._get_offline_store() + config = self._store.config + + for m in metrics_list: + log_col = m.get("feature_name", "") + view_name, feat_name = log_col_map.get( + log_col, (feature_service_name, log_col) + ) + m["project_id"] = project + m["feature_view_name"] = view_name + m["feature_name"] = feat_name + m["metric_date"] = metric_date + m["granularity"] = granularity + m["data_source_type"] = "log" + m["computed_at"] = now + m["is_baseline"] = set_baseline + + offline_store.save_monitoring_metrics(config, "feature", metrics_list) + + # --- per-feature-view aggregates (grouped by originating view) --- + by_view: Dict[str, List[Dict[str, Any]]] = defaultdict(list) + for m in metrics_list: + by_view[m["feature_view_name"]].append(m) + + view_metrics = [ + { + "project_id": project, + "feature_view_name": vname, + "metric_date": metric_date, + "granularity": granularity, + "data_source_type": "log", + "computed_at": now, + "is_baseline": set_baseline, + **build_view_aggregate(vmetrics), + } + for vname, vmetrics in by_view.items() + ] + offline_store.save_monitoring_metrics(config, "feature_view", view_metrics) + + # --- feature service aggregate --- + svc_agg = build_view_aggregate(metrics_list) + svc_metric = { + "project_id": project, + "feature_service_name": feature_service_name, + "metric_date": metric_date, + "granularity": granularity, + "data_source_type": "log", + "computed_at": now, + "is_baseline": set_baseline, + "total_feature_views": len(by_view), + "total_features": svc_agg["total_features"], + "avg_null_rate": svc_agg["avg_null_rate"], + "max_null_rate": svc_agg["max_null_rate"], + } + offline_store.save_monitoring_metrics(config, "feature_service", [svc_metric]) + + def _read_batch_source(self, feature_view, feature_fields, start_dt, end_dt): + config = self._store.config + data_source = feature_view.batch_source + offline_store = self._get_offline_store() + + retrieval_job = offline_store.pull_all_from_table_or_query( + config=config, + data_source=data_source, + join_key_columns=self._resolve_join_key_columns(feature_view), + feature_name_columns=[name for name, _ in feature_fields], + timestamp_field=data_source.timestamp_field, + created_timestamp_column=data_source.created_timestamp_column, + start_date=start_dt, + end_date=end_dt, + ) + + return retrieval_job.to_arrow() + + def _compute_feature_service_metrics( + self, + project: str, + granularity: str, + metric_dates: List[date], + set_baseline: bool, + ) -> int: + if not metric_dates: + return 0 + + feature_services = self._store.registry.list_feature_services(project=project) + if not feature_services: + return 0 + + offline_store = self._get_offline_store() + config = self._store.config + now = datetime.now(timezone.utc) + count = 0 + + for fs in feature_services: + try: + fv_names = {proj.name for proj in fs.feature_view_projections} + + for metric_date in metric_dates: + fv_metrics = offline_store.query_monitoring_metrics( + config=config, + project=project, + metric_type="feature_view", + filters={ + "granularity": granularity, + "data_source_type": "batch", + }, + start_date=metric_date, + end_date=metric_date, + ) + + relevant = [ + m for m in fv_metrics if m.get("feature_view_name") in fv_names + ] + if not relevant: + continue + + null_rates = [ + m["avg_null_rate"] + for m in relevant + if m.get("avg_null_rate") is not None + ] + + service_metric = { + "project_id": project, + "feature_service_name": fs.name, + "metric_date": metric_date + if isinstance(metric_date, date) + else date.fromisoformat(str(metric_date)), + "granularity": granularity, + "data_source_type": "batch", + "computed_at": now, + "is_baseline": set_baseline, + "total_feature_views": len(relevant), + "total_features": sum( + m.get("total_features", 0) for m in relevant + ), + "avg_null_rate": ( + sum(null_rates) / len(null_rates) if null_rates else 0.0 + ), + "max_null_rate": max(null_rates) if null_rates else 0.0, + } + offline_store.save_monitoring_metrics( + config, + "feature_service", + [service_metric], + ) + count += 1 + except Exception: + logger.exception("Failed to compute service metrics for '%s'", fs.name) + + return count diff --git a/sdk/python/feast/monitoring/monitoring_utils.py b/sdk/python/feast/monitoring/monitoring_utils.py new file mode 100644 index 00000000000..0450e008a05 --- /dev/null +++ b/sdk/python/feast/monitoring/monitoring_utils.py @@ -0,0 +1,296 @@ +"""Shared constants and helpers for monitoring across all offline store backends. + +Every backend needs the same table names, column lists, primary keys, +empty-metric templates, and result-row normalization. Centralizing them +here avoids ~8x duplication and prevents column-list drift. +""" + +import json +import math +from datetime import date, datetime +from typing import Any, Dict, List, Optional, Tuple + +# ------------------------------------------------------------------ # +# Table / file names +# ------------------------------------------------------------------ # + +MON_TABLE_FEATURE = "feast_monitoring_feature_metrics" +MON_TABLE_FEATURE_VIEW = "feast_monitoring_feature_view_metrics" +MON_TABLE_FEATURE_SERVICE = "feast_monitoring_feature_service_metrics" +MON_TABLE_JOB = "feast_monitoring_jobs" + +MONITORING_DIR = "feast_monitoring" + +MONITORING_PARQUET_FILES: Dict[str, str] = { + "feature": "feast_monitoring_feature_metrics.parquet", + "feature_view": "feast_monitoring_feature_view_metrics.parquet", + "feature_service": "feast_monitoring_feature_service_metrics.parquet", + "job": "feast_monitoring_jobs.parquet", +} + +# ------------------------------------------------------------------ # +# Column definitions — (ordered, used by INSERT / SELECT / Parquet) +# ------------------------------------------------------------------ # + +FEATURE_METRICS_COLUMNS: List[str] = [ + "project_id", + "feature_view_name", + "feature_name", + "metric_date", + "granularity", + "data_source_type", + "computed_at", + "is_baseline", + "feature_type", + "row_count", + "null_count", + "null_rate", + "mean", + "stddev", + "min_val", + "max_val", + "p50", + "p75", + "p90", + "p95", + "p99", + "histogram", +] + +FEATURE_METRICS_PK: List[str] = [ + "project_id", + "feature_view_name", + "feature_name", + "metric_date", + "granularity", + "data_source_type", +] + +FEATURE_VIEW_METRICS_COLUMNS: List[str] = [ + "project_id", + "feature_view_name", + "metric_date", + "granularity", + "data_source_type", + "computed_at", + "is_baseline", + "total_row_count", + "total_features", + "features_with_nulls", + "avg_null_rate", + "max_null_rate", +] + +FEATURE_VIEW_METRICS_PK: List[str] = [ + "project_id", + "feature_view_name", + "metric_date", + "granularity", + "data_source_type", +] + +FEATURE_SERVICE_METRICS_COLUMNS: List[str] = [ + "project_id", + "feature_service_name", + "metric_date", + "granularity", + "data_source_type", + "computed_at", + "is_baseline", + "total_feature_views", + "total_features", + "avg_null_rate", + "max_null_rate", +] + +FEATURE_SERVICE_METRICS_PK: List[str] = [ + "project_id", + "feature_service_name", + "metric_date", + "granularity", + "data_source_type", +] + +JOB_COLUMNS: List[str] = [ + "job_id", + "project_id", + "feature_view_name", + "job_type", + "status", + "parameters", + "metric_date", + "started_at", + "completed_at", + "error_message", + "result_summary", +] + +JOB_PK: List[str] = [ + "job_id", +] + + +def monitoring_table_meta( + metric_type: str, +) -> Tuple[str, List[str], List[str]]: + """Return (table_name, columns, pk_columns) for a metric type. + + Raises ValueError for unknown metric types. + """ + if metric_type == "feature": + return MON_TABLE_FEATURE, FEATURE_METRICS_COLUMNS, FEATURE_METRICS_PK + if metric_type == "feature_view": + return ( + MON_TABLE_FEATURE_VIEW, + FEATURE_VIEW_METRICS_COLUMNS, + FEATURE_VIEW_METRICS_PK, + ) + if metric_type == "feature_service": + return ( + MON_TABLE_FEATURE_SERVICE, + FEATURE_SERVICE_METRICS_COLUMNS, + FEATURE_SERVICE_METRICS_PK, + ) + if metric_type == "job": + return MON_TABLE_JOB, JOB_COLUMNS, JOB_PK + raise ValueError(f"Unknown monitoring metric_type: '{metric_type}'") + + +def monitoring_parquet_meta( + metric_type: str, +) -> Tuple[str, List[str], List[str]]: + """Return (parquet_filename, columns, pk_columns) for file-based backends. + + File names match the SQL table names with a ``.parquet`` extension so + the mapping between backends is consistent. + """ + fname = MONITORING_PARQUET_FILES.get(metric_type) + if fname is None: + raise ValueError(f"Unknown monitoring metric_type: '{metric_type}'") + _, columns, pk = monitoring_table_meta(metric_type) + return fname, columns, pk + + +# ------------------------------------------------------------------ # +# Tiny helpers duplicated across backends +# ------------------------------------------------------------------ # + + +def opt_float(val: Any) -> Optional[float]: + """Safely cast a value to float, returning None for None/NaN/Inf.""" + if val is None: + return None + f = float(val) + if math.isnan(f) or math.isinf(f): + return None + return f + + +def empty_numeric_metric(feature_name: str) -> Dict[str, Any]: + """Return a metric dict with all-None stats for a numeric feature.""" + return { + "feature_name": feature_name, + "feature_type": "numeric", + "row_count": 0, + "null_count": 0, + "null_rate": 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + +def empty_categorical_metric(feature_name: str) -> Dict[str, Any]: + """Return a metric dict with all-None stats for a categorical feature.""" + return { + "feature_name": feature_name, + "feature_type": "categorical", + "row_count": 0, + "null_count": 0, + "null_rate": 0.0, + "mean": None, + "stddev": None, + "min_val": None, + "max_val": None, + "p50": None, + "p75": None, + "p90": None, + "p95": None, + "p99": None, + "histogram": None, + } + + +# ------------------------------------------------------------------ # +# Result-row normalization (used after SQL fetch or Parquet read) +# ------------------------------------------------------------------ # + + +def normalize_monitoring_row(record: Dict[str, Any]) -> Dict[str, Any]: + """Normalize a monitoring metric dict for JSON serialization. + + - Replaces float NaN / Inf with None (not JSON-serializable). + - Parses ``histogram`` from JSON string if needed. + - Converts ``metric_date`` / ``computed_at`` to ISO strings. + - Normalizes ``is_baseline`` to Python bool. + """ + import math + + for key, val in record.items(): + if isinstance(val, float) and (math.isnan(val) or math.isinf(val)): + record[key] = None + + hist = record.get("histogram") + if isinstance(hist, str): + try: + record["histogram"] = json.loads(hist) + except (json.JSONDecodeError, TypeError): + pass + + for key in ("metric_date", "computed_at"): + val = record.get(key) + if isinstance(val, (date, datetime)): + record[key] = val.isoformat() + + baseline = record.get("is_baseline") + if baseline is not None: + record["is_baseline"] = bool(baseline) + + return record + + +# ------------------------------------------------------------------ # +# View-level aggregate builder (shared by batch + log save paths) +# ------------------------------------------------------------------ # + + +def build_view_aggregate( + metrics_list: List[Dict[str, Any]], +) -> Dict[str, Any]: + """Compute view-level aggregate stats from per-feature metrics. + + Returns a dict with keys: total_row_count, total_features, + features_with_nulls, avg_null_rate, max_null_rate. + """ + null_rates = [ + m["null_rate"] for m in metrics_list if m.get("null_rate") is not None + ] + return { + "total_row_count": max( + (m["row_count"] for m in metrics_list if m.get("row_count") is not None), + default=0, + ), + "total_features": len(metrics_list), + "features_with_nulls": sum( + 1 for m in metrics_list if (m.get("null_count") or 0) > 0 + ), + "avg_null_rate": sum(null_rates) / len(null_rates) if null_rates else 0.0, + "max_null_rate": max(null_rates) if null_rates else 0.0, + } diff --git a/sdk/python/feast/offline_server.py b/sdk/python/feast/offline_server.py index bcdf808868b..0373b3a8146 100644 --- a/sdk/python/feast/offline_server.py +++ b/sdk/python/feast/offline_server.py @@ -15,6 +15,7 @@ from feast import FeatureStore, FeatureView, utils from feast.arrow_error_handler import arrow_server_error_handling_decorator from feast.data_source import DataSource +from feast.errors import FeatureViewNotFoundException from feast.feature_logging import FeatureServiceLoggingSource from feast.feature_view import DUMMY_ENTITY_NAME from feast.infra.offline_stores.offline_utils import get_offline_store_from_config @@ -199,7 +200,7 @@ def get_feature_view_by_name( ) fv = fv.with_projection(p) return fv - except Exception: + except FeatureViewNotFoundException: try: return self.store.registry.get_stream_feature_view( name=fv_name, project=project @@ -435,6 +436,10 @@ def get_historical_features(self, command: dict, key: Optional[str] = None): if len(entity_df.columns) == 1 and "key" in entity_df.columns: entity_df = None + # If the client sent a SQL string, use it directly + if entity_df is None and "entity_df_sql" in command: + entity_df = command["entity_df_sql"] + feature_view_names = command["feature_view_names"] name_aliases = command["name_aliases"] feature_refs = command["feature_refs"] diff --git a/sdk/python/feast/on_demand_feature_view.py b/sdk/python/feast/on_demand_feature_view.py index 6430675f4e7..bf2d34666cf 100644 --- a/sdk/python/feast/on_demand_feature_view.py +++ b/sdk/python/feast/on_demand_feature_view.py @@ -1,5 +1,6 @@ import copy import functools +import uuid import warnings from types import FunctionType from typing import Any, List, Optional, Union, cast @@ -13,7 +14,7 @@ from feast.data_source import RequestSource from feast.entity import Entity from feast.errors import RegistryInferenceFailure, SpecifiedFeaturesNotPresentError -from feast.feature_view import DUMMY_ENTITY_NAME, FeatureView +from feast.feature_view import DUMMY_ENTITY_NAME, FeatureView, FeatureViewState from feast.feature_view_projection import FeatureViewProjection from feast.field import Field, from_value_type from feast.proto_utils import transformation_to_proto @@ -35,6 +36,7 @@ from feast.transformation.substrait_transformation import SubstraitTransformation from feast.utils import _utc_now from feast.value_type import ValueType +from feast.version_utils import normalize_version_string warnings.simplefilter("once", DeprecationWarning) OnDemandSourceType = Union[FeatureView, FeatureViewProjection, RequestSource] @@ -129,23 +131,33 @@ class OnDemandFeatureView(BaseFeatureView): tags: A dictionary of key-value pairs to store arbitrary metadata. owner: The owner of the on demand feature view, typically the email of the primary maintainer. + org: The organizational unit that owns this on demand feature view (e.g. "ads", + "search"). Defaults to empty string. """ + _TRACK_METRICS_TAG = "feast:track_metrics" + _INPUT_SCHEMA_SOURCE_PREFIX = "__input_schema__" + name: str entities: Optional[List[str]] features: List[Field] source_feature_view_projections: dict[str, FeatureViewProjection] source_request_sources: dict[str, RequestSource] - feature_transformation: Transformation + feature_transformation: Optional[Transformation] mode: str description: str tags: dict[str, str] owner: str + org: str write_to_online_store: bool singleton: bool + track_metrics: bool udf: Optional[FunctionType] udf_string: Optional[str] aggregations: List[Aggregation] + enabled: bool + state: FeatureViewState + _raw_feature_transformation_proto: Optional[Any] = None def __init__( # noqa: C901 self, @@ -153,7 +165,8 @@ def __init__( # noqa: C901 name: str, entities: Optional[List[Entity]] = None, schema: Optional[List[Field]] = None, - sources: List[OnDemandSourceType], + sources: Optional[List[OnDemandSourceType]] = None, + input_schema: Optional[List[Field]] = None, udf: Optional[FunctionType] = None, udf_string: Optional[str] = "", feature_transformation: Optional[Transformation] = None, @@ -161,9 +174,13 @@ def __init__( # noqa: C901 description: str = "", tags: Optional[dict[str, str]] = None, owner: str = "", + org: str = "", write_to_online_store: bool = False, singleton: bool = False, + track_metrics: bool = False, aggregations: Optional[List[Aggregation]] = None, + version: str = "latest", + enabled: bool = True, ): """ Creates an OnDemandFeatureView object. @@ -176,6 +193,11 @@ def __init__( # noqa: C901 sources: A map from input source names to the actual input sources, which may be feature views, or request data sources. These sources serve as inputs to the udf, which will refer to them by name. + input_schema (optional): A list of Fields describing data that is accepted as input + but not stored directly as features — e.g. aggregation columns, normalization + parameters, thresholds, or other contextual values passed at request time. + When provided, sources is not required — an internal RequestSource will be + created automatically. udf: The user defined transformation function, which must take pandas dataframes as inputs. udf_string: The source code version of the udf (for diffing and displaying in Web UI) @@ -185,10 +207,17 @@ def __init__( # noqa: C901 tags (optional): A dictionary of key-value pairs to store arbitrary metadata. owner (optional): The owner of the on demand feature view, typically the email of the primary maintainer. + org (optional): The organizational unit that owns this feature view + (e.g. "ads", "search"). write_to_online_store (optional): A boolean that indicates whether to write the on demand feature view to the online store for faster retrieval. singleton (optional): A boolean that indicates whether the transformation is executed on a singleton (only applicable when mode="python"). + track_metrics (optional): Whether to emit Prometheus timing metrics + (``feast_feature_server_transformation_duration_seconds``) for + this ODFV. Defaults to ``False``. Set to ``True`` to opt in + to per-ODFV transformation duration tracking when the server + is started with metrics enabled. aggregations (optional): List of aggregations to apply before transformation. """ super().__init__( @@ -199,17 +228,48 @@ def __init__( # noqa: C901 owner=owner, ) + self.org = org + self.version = version schema = schema or [] self.entities = [e.name for e in entities] if entities else [DUMMY_ENTITY_NAME] - self.sources = sources + self.input_schema = input_schema self.mode = mode.lower() self.udf = udf self.udf_string = udf_string self.source_feature_view_projections: dict[str, FeatureViewProjection] = {} self.source_request_sources: dict[str, RequestSource] = {} + self._input_schema_sentinel: Optional[RequestSource] = None + + # Strip any existing sentinel from sources (handles __copy__ round-trip) + effective_sources: List[OnDemandSourceType] = [ + s + for s in (sources or []) + if not ( + isinstance(s, RequestSource) + and s.name.startswith(self._INPUT_SCHEMA_SOURCE_PREFIX) + ) + ] + + if input_schema is not None: + # Automatically create an internal RequestSource from input_schema. + # Stored privately so it does not appear in source_request_sources for + # external consumers (e.g. the feature server, apply(), utils.py). + self._input_schema_sentinel = RequestSource( + name=f"{self._INPUT_SCHEMA_SOURCE_PREFIX}{name}", + schema=input_schema, + ) + self.source_request_sources[self._input_schema_sentinel.name] = ( + self._input_schema_sentinel + ) + elif not effective_sources: + raise ValueError( + "Either 'sources' or 'input_schema' must be provided for OnDemandFeatureView." + ) + + self.sources = effective_sources # Process each source with explicit type handling - for odfv_source in sources: + for odfv_source in effective_sources: self._add_source_to_collections(odfv_source) features: List[Field] = [] @@ -246,16 +306,37 @@ def __init__( # noqa: C901 features.append(field) self.features = features - self.feature_transformation = ( - feature_transformation or self.get_feature_transformation() - ) + if feature_transformation is not None: + self.feature_transformation = feature_transformation + elif self.udf is not None: + self.feature_transformation = self.get_feature_transformation() + else: + self.feature_transformation = None self.write_to_online_store = write_to_online_store self.singleton = singleton if self.singleton and self.mode != "python": raise ValueError( ODFVErrorMessages.singleton_mode_requires_python(self.mode) ) + self.track_metrics = track_metrics self.aggregations = aggregations or [] + self.enabled = enabled + + self.state = FeatureViewState.STATE_UNSPECIFIED + + if input_schema is not None and self.aggregations: + input_field_names = {f.name for f in input_schema} + unknown = [ + agg.column + for agg in self.aggregations + if agg.column and agg.column not in input_field_names + ] + if unknown: + raise ValueError( + f"Aggregation column(s) {unknown} not found in input_schema " + f"for OnDemandFeatureView '{name}'. " + f"Available fields: {sorted(input_field_names)}" + ) def _add_source_to_collections(self, odfv_source: OnDemandSourceType) -> None: """ @@ -311,21 +392,71 @@ def __copy__(self): schema=self.features, sources=list(self.source_feature_view_projections.values()) + list(self.source_request_sources.values()), + input_schema=self.input_schema, feature_transformation=self.feature_transformation, mode=self.mode, description=self.description, tags=self.tags, owner=self.owner, + org=self.org, write_to_online_store=self.write_to_online_store, singleton=self.singleton, + version=self.version, + track_metrics=self.track_metrics, + aggregations=self.aggregations, ) fv.entities = self.entities fv.features = self.features fv.projection = copy.copy(self.projection) fv.entity_columns = copy.copy(self.entity_columns) + fv.enabled = self.enabled + fv.state = self.state return fv + def _schema_or_udf_changed(self, other: "BaseFeatureView") -> bool: + """Check for OnDemandFeatureView schema/UDF changes.""" + if super()._schema_or_udf_changed(other): + return True + + if not isinstance(other, OnDemandFeatureView): + return True + + # UDF/transformation changes + # Handle None cases for feature_transformation + if ( + self.feature_transformation is None + and other.feature_transformation is not None + ): + return True + if ( + self.feature_transformation is not None + and other.feature_transformation is None + ): + return True + if ( + self.feature_transformation is not None + and other.feature_transformation is not None + and self.feature_transformation != other.feature_transformation + ): + return True + if self.mode != other.mode: + return True + if ( + self.source_feature_view_projections + != other.source_feature_view_projections + ): + return True + if self.source_request_sources != other.source_request_sources: + return True + if sorted(self.entity_columns) != sorted(other.entity_columns): + return True + if self.aggregations != other.aggregations: + return True + + # Skip configuration: write_to_online_store, singleton + return False + def __eq__(self, other): if not isinstance(other, OnDemandFeatureView): raise TypeError( @@ -345,7 +476,11 @@ def __eq__(self, other): or self.write_to_online_store != other.write_to_online_store or sorted(self.entity_columns) != sorted(other.entity_columns) or self.singleton != other.singleton + or self.track_metrics != other.track_metrics or self.aggregations != other.aggregations + or normalize_version_string(self.version) + != normalize_version_string(other.version) + or self.org != other.org ): return False @@ -410,6 +545,10 @@ def _validate_sources_config(self) -> None: def _validate_transformation_config(self) -> None: """Validate transformation configuration.""" + # Aggregations provide their own transformation; no udf/feature_transformation required. + if self.aggregations: + return + if not self.feature_transformation: raise ValueError(ODFVErrorMessages.no_transformation_provided()) @@ -456,6 +595,10 @@ def to_proto(self) -> OnDemandFeatureViewProto: meta.created_timestamp.FromDatetime(self.created_timestamp) if self.last_updated_timestamp: meta.last_updated_timestamp.FromDatetime(self.last_updated_timestamp) + if self.current_version_number is not None: + meta.current_version_number = self.current_version_number + if self.state != FeatureViewState.STATE_UNSPECIFIED: + meta.state = self.state.to_proto() sources = {} for source_name, fv_projection in self.source_feature_view_projections.items(): sources[source_name] = OnDemandSource( @@ -469,7 +612,26 @@ def to_proto(self) -> OnDemandFeatureViewProto: request_data_source=request_sources.to_proto() ) - feature_transformation = transformation_to_proto(self.feature_transformation) + # Serialize the input_schema sentinel so that from_proto() can reconstruct + # input_schema correctly; it is excluded from source_request_sources so that + # external consumers never see it as a real data source. + if self._input_schema_sentinel is not None: + sources[self._input_schema_sentinel.name] = OnDemandSource( + request_data_source=self._input_schema_sentinel.to_proto() + ) + + if getattr(self, "_raw_feature_transformation_proto", None) is not None: + feature_transformation = self._raw_feature_transformation_proto + else: + feature_transformation = transformation_to_proto( + self.feature_transformation + ) + + tags = dict(self.tags) if self.tags else {} + if self.track_metrics: + tags[self._TRACK_METRICS_TAG] = "true" + else: + tags.pop(self._TRACK_METRICS_TAG, None) spec = OnDemandFeatureViewSpec( name=self.name, @@ -482,11 +644,14 @@ def to_proto(self) -> OnDemandFeatureViewProto: feature_transformation=feature_transformation, mode=self.mode, description=self.description, - tags=self.tags, + tags=tags, owner=self.owner, + org=self.org, write_to_online_store=self.write_to_online_store, singleton=self.singleton or False, - aggregations=self.aggregations, + aggregations=[agg.to_proto() for agg in self.aggregations], + version=self.version, + disabled=not self.enabled, ) return OnDemandFeatureViewProto(spec=spec, meta=meta) @@ -507,11 +672,25 @@ def from_proto( A OnDemandFeatureView object based on the on-demand feature view protobuf. """ # Parse sources from proto - sources = cls._parse_sources_from_proto(on_demand_feature_view_proto) + sources = cls._parse_sources_from_proto( + on_demand_feature_view_proto, skip_udf=skip_udf + ) - # Parse transformation from proto + # Detect and strip input_schema sentinel from sources + input_schema: Optional[List[Field]] = None + sources_without_sentinel: List[OnDemandSourceType] = [] + for source in sources: + if isinstance(source, RequestSource) and source.name.startswith( + cls._INPUT_SCHEMA_SOURCE_PREFIX + ): + input_schema = source.schema + else: + sources_without_sentinel.append(source) + sources = sources_without_sentinel + + # Parse transformation from proto (skip UDF deserialization if requested) transformation = cls._parse_transformation_from_proto( - on_demand_feature_view_proto + on_demand_feature_view_proto, skip_udf=skip_udf ) # Parse optional fields with defaults @@ -519,24 +698,42 @@ def from_proto( on_demand_feature_view_proto ) + # Extract track_metrics from proto tags and strip the internal key + # so it doesn't leak into user-facing self.tags. + proto_tags = dict(on_demand_feature_view_proto.spec.tags) + track_metrics = ( + proto_tags.pop(cls._TRACK_METRICS_TAG, "false").lower() == "true" + ) + # Create the OnDemandFeatureView object on_demand_feature_view_obj = cls( name=on_demand_feature_view_proto.spec.name, schema=cls._parse_features_from_proto(on_demand_feature_view_proto), sources=cast(List[OnDemandSourceType], sources), + input_schema=input_schema, feature_transformation=transformation, mode=on_demand_feature_view_proto.spec.mode or "pandas", description=on_demand_feature_view_proto.spec.description, - tags=dict(on_demand_feature_view_proto.spec.tags), + tags=proto_tags, owner=on_demand_feature_view_proto.spec.owner, + org=on_demand_feature_view_proto.spec.org, write_to_online_store=optional_fields["write_to_online_store"], singleton=optional_fields["singleton"], + track_metrics=track_metrics, aggregations=optional_fields["aggregations"], ) # Set additional attributes that aren't part of the constructor on_demand_feature_view_obj.entities = optional_fields["entities"] on_demand_feature_view_obj.entity_columns = optional_fields["entity_columns"] + on_demand_feature_view_obj.enabled = ( + not on_demand_feature_view_proto.spec.disabled + ) + + # Restore lifecycle state from meta. + on_demand_feature_view_obj.state = FeatureViewState.from_proto( + on_demand_feature_view_proto.meta.state + ) # FeatureViewProjections are not saved in the OnDemandFeatureView proto. # Create the default projection. @@ -544,6 +741,24 @@ def from_proto( on_demand_feature_view_obj ) + # Restore version fields. + spec_version = on_demand_feature_view_proto.spec.version + on_demand_feature_view_obj.version = spec_version or "latest" + cvn = on_demand_feature_view_proto.meta.current_version_number + if cvn > 0: + on_demand_feature_view_obj.current_version_number = cvn + elif cvn == 0 and spec_version and spec_version.lower() != "latest": + on_demand_feature_view_obj.current_version_number = 0 + else: + on_demand_feature_view_obj.current_version_number = None + + if skip_udf and on_demand_feature_view_proto.spec.HasField( + "feature_transformation" + ): + on_demand_feature_view_obj._raw_feature_transformation_proto = ( + on_demand_feature_view_proto.spec.feature_transformation + ) + # Set timestamps if present cls._set_timestamps_from_proto( on_demand_feature_view_proto, on_demand_feature_view_obj @@ -553,7 +768,7 @@ def from_proto( @classmethod def _parse_sources_from_proto( - cls, proto: OnDemandFeatureViewProto + cls, proto: OnDemandFeatureViewProto, skip_udf: bool = False ) -> List[OnDemandSourceType]: """Parse and convert sources from the protobuf representation.""" sources: List[OnDemandSourceType] = [] @@ -562,7 +777,9 @@ def _parse_sources_from_proto( if source_type == "feature_view": sources.append( - FeatureView.from_proto(on_demand_source.feature_view).projection + FeatureView.from_proto( + on_demand_source.feature_view, skip_udf=skip_udf + ).projection ) elif source_type == "feature_view_projection": sources.append( @@ -583,9 +800,12 @@ def _parse_sources_from_proto( @classmethod def _parse_transformation_from_proto( - cls, proto: OnDemandFeatureViewProto - ) -> Transformation: + cls, proto: OnDemandFeatureViewProto, skip_udf: bool = False + ) -> Optional[Transformation]: """Parse and convert the transformation from the protobuf representation.""" + if skip_udf: + return None + feature_transformation = proto.spec.feature_transformation transformation_type = feature_transformation.WhichOneof("transformation") mode = proto.spec.mode @@ -610,6 +830,8 @@ def _parse_transformation_from_proto( feature_transformation.substrait_transformation ) elif transformation_type is None: + if proto.spec.aggregations: + return None # Handle backward compatibility case where feature_transformation is cleared return cls._handle_backward_compatible_udf(proto) else: @@ -717,6 +939,10 @@ def get_request_data_schema(self) -> dict[str, ValueType]: raise TypeError( f"Request source schema is not correct type: ${str(type(request_source.schema))}" ) + # Include fields from the input_schema sentinel (stored privately) + if self._input_schema_sentinel is not None: + for field in self._input_schema_sentinel.schema: + schema[field.name] = field.dtype.to_value_type() return schema def _get_projected_feature_name(self, feature: str) -> str: @@ -808,6 +1034,7 @@ def transform_arrow( pa_table, columns_to_cleanup = self._preprocess_arrow_table(pa_table) # Apply the transformation + assert self.feature_transformation is not None transformed_table = self.feature_transformation.transform_arrow( pa_table, self.features ) @@ -893,6 +1120,7 @@ def transform_dict( ) # Apply the appropriate transformation based on mode + assert self.feature_transformation is not None if self.singleton and self.mode == "python": output_dict = self.feature_transformation.transform_singleton( preprocessed_dict @@ -934,6 +1162,14 @@ def _preprocess_feature_dict( return preprocessed_dict, columns_to_cleanup def infer_features(self) -> None: + if self.aggregations and not self.feature_transformation: + if not self.features: + raise RegistryInferenceFailure( + "OnDemandFeatureView", + f"Could not infer Features for the feature view '{self.name}'.", + ) + return + assert self.feature_transformation is not None random_input = self._construct_random_input(singleton=self.singleton) inferred_features = self.feature_transformation.infer_features( random_input=random_input, singleton=self.singleton @@ -989,7 +1225,7 @@ def _is_array_type(self, dtype) -> bool: """Check if the dtype represents an array type.""" # Use proper type checking instead of string comparison dtype_str = str(dtype) - return "Array" in dtype_str or "List" in dtype_str + return "Array" in dtype_str or "List" in dtype_str or "Set" in dtype_str def _construct_random_input( self, singleton: bool = False @@ -1034,6 +1270,13 @@ def _construct_random_input( sample_value = sample_values.get(value_type, default_value) feature_dict[field.name] = sample_value + # Add input_schema fields (stored privately outside source_request_sources) + if self._input_schema_sentinel is not None: + for field in self._input_schema_sentinel.schema: + value_type = field.dtype.to_value_type() + sample_value = sample_values.get(value_type, default_value) + feature_dict[field.name] = sample_value + return feature_dict def _get_sample_values_by_type(self) -> dict[ValueType, list[Any]]: @@ -1073,6 +1316,9 @@ def _get_sample_values_by_type(self) -> dict[ValueType, list[Any]]: # Special binary types ValueType.PDF_BYTES: [pdf_sample], ValueType.IMAGE_BYTES: [image_sample], + # UUID types + ValueType.UUID: [uuid.uuid4()], + ValueType.TIME_UUID: [uuid.uuid1()], # List types ValueType.BYTES_LIST: [[b"hello world"]], ValueType.STRING_LIST: [["hello world"]], @@ -1082,6 +1328,19 @@ def _get_sample_values_by_type(self) -> dict[ValueType, list[Any]]: ValueType.FLOAT_LIST: [[1.0]], ValueType.BOOL_LIST: [[True]], ValueType.UNIX_TIMESTAMP_LIST: [[_utc_now()]], + ValueType.UUID_LIST: [[uuid.uuid4(), uuid.uuid4()]], + ValueType.TIME_UUID_LIST: [[uuid.uuid1(), uuid.uuid1()]], + # Set types + ValueType.BYTES_SET: [{b"hello world", b"foo bar"}], + ValueType.STRING_SET: [{"hello world", "foo bar"}], + ValueType.INT32_SET: [{1, 2}], + ValueType.INT64_SET: [{1, 2}], + ValueType.DOUBLE_SET: [{1.0, 2.0}], + ValueType.FLOAT_SET: [{1.0, 2.0}], + ValueType.BOOL_SET: [{True, False}], + ValueType.UNIX_TIMESTAMP_SET: [{_utc_now()}], + ValueType.UUID_SET: [{uuid.uuid4(), uuid.uuid4()}], + ValueType.TIME_UUID_SET: [{uuid.uuid1(), uuid.uuid1()}], } @staticmethod @@ -1105,20 +1364,27 @@ def on_demand_feature_view( name: Optional[str] = None, entities: Optional[List[Entity]] = None, schema: list[Field], - sources: list[ - Union[ - FeatureView, - RequestSource, - FeatureViewProjection, + sources: Optional[ + list[ + Union[ + FeatureView, + RequestSource, + FeatureViewProjection, + ] ] - ], + ] = None, + input_schema: Optional[list[Field]] = None, + aggregations: Optional[List[Aggregation]] = None, mode: str = "pandas", description: str = "", tags: Optional[dict[str, str]] = None, owner: str = "", + org: str = "", write_to_online_store: bool = False, singleton: bool = False, + track_metrics: bool = False, explode: bool = False, + version: str = "latest", ): """ Creates an OnDemandFeatureView object with the given user function as udf. @@ -1131,15 +1397,23 @@ def on_demand_feature_view( sources: A map from input source names to the actual input sources, which may be feature views, or request data sources. These sources serve as inputs to the udf, which will refer to them by name. + input_schema (optional): A list of Fields describing data that is accepted as input + but not stored directly as features — e.g. aggregation columns, normalization + parameters, thresholds, or other contextual values passed at request time. + When provided, sources is not required. mode: The mode of execution (e.g,. Pandas or Python Native) description (optional): A human-readable description. tags (optional): A dictionary of key-value pairs to store arbitrary metadata. owner (optional): The owner of the on demand feature view, typically the email of the primary maintainer. + org (optional): The organizational unit that owns this on demand feature view + (e.g. "ads", "search"). Defaults to empty string. write_to_online_store (optional): A boolean that indicates whether to write the on demand feature view to the online store for faster retrieval. singleton (optional): A boolean that indicates whether the transformation is executed on a singleton (only applicable when mode="python"). + track_metrics (optional): Whether to emit Prometheus timing metrics for this ODFV. + Defaults to False. Set to True to opt in when the server is started with metrics. explode (optional): A boolean that indicates whether the transformation explodes the input data into multiple rows. """ @@ -1156,16 +1430,21 @@ def decorator(user_function): on_demand_feature_view_obj = OnDemandFeatureView( name=name if name is not None else user_function.__name__, sources=sources, + input_schema=input_schema, schema=schema, mode=mode, description=description, tags=tags, owner=owner, + org=org, write_to_online_store=write_to_online_store, entities=entities, singleton=singleton, + track_metrics=track_metrics, + aggregations=aggregations, udf=user_function, udf_string=udf_string, + version=version, ) functools.update_wrapper( wrapper=on_demand_feature_view_obj, wrapped=user_function diff --git a/sdk/python/feast/online_response.py b/sdk/python/feast/online_response.py index 2491a28badc..7b6b4806e4d 100644 --- a/sdk/python/feast/online_response.py +++ b/sdk/python/feast/online_response.py @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING, Any, Dict, List, TypeAlias, Union +import uuid as uuid_module +from typing import TYPE_CHECKING, Any, Dict, List, Optional, TypeAlias, Union import pandas as pd import pyarrow as pa @@ -21,6 +22,7 @@ from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse from feast.torch_wrapper import get_torch from feast.type_map import feast_value_type_to_python_type +from feast.value_type import ValueType if TYPE_CHECKING: import torch @@ -37,14 +39,20 @@ class OnlineResponse: Defines an online response in feast. """ - def __init__(self, online_response_proto: GetOnlineFeaturesResponse): + def __init__( + self, + online_response_proto: GetOnlineFeaturesResponse, + feature_types: Optional[Dict[str, ValueType]] = None, + ): """ Construct a native online response from its protobuf version. Args: online_response_proto: GetOnlineResponse proto object to construct from. + feature_types: Optional mapping of feature names to ValueType for type-aware deserialization. """ self.proto = online_response_proto + self._feature_types = feature_types or {} # Delete DUMMY_ENTITY_ID from proto if it exists for idx, val in enumerate(self.proto.metadata.feature_names.val): if val == DUMMY_ENTITY_ID: @@ -65,8 +73,10 @@ def to_dict(self, include_event_timestamps: bool = False) -> Dict[str, Any]: for feature_ref, feature_vector in zip( self.proto.metadata.feature_names.val, self.proto.results ): + feature_type = self._feature_types.get(feature_ref) response[feature_ref] = [ - feast_value_type_to_python_type(v) for v in feature_vector.values + feast_value_type_to_python_type(v, feature_type) + for v in feature_vector.values ] if include_event_timestamps: @@ -94,8 +104,9 @@ def to_arrow(self, include_event_timestamps: bool = False) -> pa.Table: Args: include_event_timestamps: bool Optionally include feature timestamps in the table """ - - return pa.Table.from_pydict(self.to_dict(include_event_timestamps)) + result = self.to_dict(include_event_timestamps) + result = _convert_uuids_for_arrow(result) + return pa.Table.from_pydict(result) def to_tensor( self, @@ -140,3 +151,31 @@ def to_tensor( values # Return as-is for strings or unsupported types ) return tensor_dict + + +def _convert_uuids_for_arrow(result: Dict[str, List[Any]]) -> Dict[str, List[Any]]: + """Convert uuid.UUID objects and sets to Arrow-compatible types.""" + for key, values in result.items(): + first_valid = next((v for v in values if v is not None), None) + if isinstance(first_valid, uuid_module.UUID): + result[key] = [ + str(v) if isinstance(v, uuid_module.UUID) else v for v in values + ] + elif isinstance(first_valid, list): + inner = next((e for e in first_valid if e is not None), None) + if isinstance(inner, uuid_module.UUID): + result[key] = [ + [str(e) if isinstance(e, uuid_module.UUID) else e for e in v] + if isinstance(v, list) + else v + for v in values + ] + elif isinstance(first_valid, set): + inner = next((e for e in first_valid if e is not None), None) + if isinstance(inner, uuid_module.UUID): + result[key] = [ + [str(e) for e in v] if isinstance(v, set) else v for v in values + ] + else: + result[key] = [list(v) if isinstance(v, set) else v for v in values] + return result diff --git a/sdk/python/feast/openlineage/__init__.py b/sdk/python/feast/openlineage/__init__.py index a8328417475..e32ae967004 100644 --- a/sdk/python/feast/openlineage/__init__.py +++ b/sdk/python/feast/openlineage/__init__.py @@ -35,27 +35,27 @@ Usage: Simply configure OpenLineage in your feature_store.yaml: - ```yaml - project: my_project - # ... other config ... - - openlineage: - enabled: true - transport_type: http - transport_url: http://localhost:5000 - transport_endpoint: api/v1/lineage - namespace: my_namespace # Optional: defaults to project name - ``` + .. code-block:: yaml + + project: my_project + # ... other config ... + + openlineage: + enabled: true + transport_type: http + transport_url: http://localhost:5000 + transport_endpoint: api/v1/lineage + namespace: my_namespace # Optional: defaults to project name Then use Feast normally - lineage events are emitted automatically! - ```python - from feast import FeatureStore + .. code-block:: python + + from feast import FeatureStore - fs = FeatureStore(repo_path="feature_repo") - fs.apply([entity, feature_view, feature_service]) # Emits lineage - fs.materialize(start, end) # Emits START/COMPLETE/FAIL events - ``` + fs = FeatureStore(repo_path="feature_repo") + fs.apply([entity, feature_view, feature_service]) # Emits lineage + fs.materialize(start, end) # Emits START/COMPLETE/FAIL events """ from feast.openlineage.client import FeastOpenLineageClient diff --git a/sdk/python/feast/openlineage/client.py b/sdk/python/feast/openlineage/client.py index 927f998ac3e..445231aae89 100644 --- a/sdk/python/feast/openlineage/client.py +++ b/sdk/python/feast/openlineage/client.py @@ -55,7 +55,8 @@ class FeastOpenLineageClient: from Feast operations like materialization, feature retrieval, and registry changes. - Example: + Example:: + from feast.openlineage import FeastOpenLineageClient, OpenLineageConfig config = OpenLineageConfig( @@ -105,9 +106,12 @@ def __init__( # Initialize the OpenLineage client try: transport_config = self._config.get_transport_config() - self._client = OpenLineageClient(config={"transport": transport_config}) + if transport_config is None: + self._client = OpenLineageClient() + else: + self._client = OpenLineageClient(config={"transport": transport_config}) logger.info( - f"OpenLineage client initialized with {self._config.transport_type} transport" + f"OpenLineage client initialized with {self._config.transport_type or 'default'} transport" ) except Exception as e: logger.error(f"Failed to initialize OpenLineage client: {e}") diff --git a/sdk/python/feast/openlineage/config.py b/sdk/python/feast/openlineage/config.py index 4d8b7684179..7c3b1fd9814 100644 --- a/sdk/python/feast/openlineage/config.py +++ b/sdk/python/feast/openlineage/config.py @@ -28,7 +28,8 @@ class OpenLineageConfig: Attributes: enabled: Whether OpenLineage integration is enabled - transport_type: Type of transport (http, console, file, kafka) + transport_type: Type of transport (http, console, file, kafka), or None to use + OpenLineage SDK defaults transport_url: URL for HTTP transport transport_endpoint: API endpoint for HTTP transport api_key: Optional API key for authentication @@ -40,7 +41,7 @@ class OpenLineageConfig: """ enabled: bool = True - transport_type: str = "console" + transport_type: Optional[str] = None transport_url: Optional[str] = None transport_endpoint: str = "api/v1/lineage" api_key: Optional[str] = None @@ -63,7 +64,7 @@ def from_dict(cls, config_dict: Dict[str, Any]) -> "OpenLineageConfig": """ return cls( enabled=config_dict.get("enabled", True), - transport_type=config_dict.get("transport_type", "console"), + transport_type=config_dict.get("transport_type"), transport_url=config_dict.get("transport_url"), transport_endpoint=config_dict.get("transport_endpoint", "api/v1/lineage"), api_key=config_dict.get("api_key"), @@ -81,7 +82,7 @@ def from_env(cls) -> "OpenLineageConfig": Environment variables: FEAST_OPENLINEAGE_ENABLED: Enable/disable OpenLineage (default: true) - FEAST_OPENLINEAGE_TRANSPORT_TYPE: Transport type (default: console) + FEAST_OPENLINEAGE_TRANSPORT_TYPE: Transport type (default: None, uses OL SDK defaults) FEAST_OPENLINEAGE_URL: HTTP transport URL FEAST_OPENLINEAGE_ENDPOINT: API endpoint (default: api/v1/lineage) FEAST_OPENLINEAGE_API_KEY: API key for authentication @@ -93,7 +94,7 @@ def from_env(cls) -> "OpenLineageConfig": """ return cls( enabled=os.getenv("FEAST_OPENLINEAGE_ENABLED", "true").lower() == "true", - transport_type=os.getenv("FEAST_OPENLINEAGE_TRANSPORT_TYPE", "console"), + transport_type=os.getenv("FEAST_OPENLINEAGE_TRANSPORT_TYPE"), transport_url=os.getenv("FEAST_OPENLINEAGE_URL"), transport_endpoint=os.getenv( "FEAST_OPENLINEAGE_ENDPOINT", "api/v1/lineage" @@ -129,13 +130,17 @@ def to_dict(self) -> Dict[str, Any]: "additional_config": self.additional_config, } - def get_transport_config(self) -> Dict[str, Any]: + def get_transport_config(self) -> Optional[Dict[str, Any]]: """ Get transport-specific configuration for OpenLineage client. Returns: - Dictionary with transport configuration + Dictionary with transport configuration, or None if transport_type + is not set (allowing the OpenLineage SDK to use its own defaults). """ + if not self.transport_type: + return None + config: Dict[str, Any] = {"type": self.transport_type} if self.transport_type == "http": diff --git a/sdk/python/feast/openlineage/emitter.py b/sdk/python/feast/openlineage/emitter.py index 1f63e39210e..b20168186c8 100644 --- a/sdk/python/feast/openlineage/emitter.py +++ b/sdk/python/feast/openlineage/emitter.py @@ -27,6 +27,7 @@ if TYPE_CHECKING: from feast import FeatureService, FeatureView from feast.infra.registry.base_registry import BaseRegistry + from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.stream_feature_view import StreamFeatureView @@ -140,12 +141,13 @@ def emit_registry_lineage( return [] from feast.feature_view import FeatureView + from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.stream_feature_view import StreamFeatureView results = [] - # Get all feature views at once (includes FeatureView, StreamFeatureView, OnDemandFeatureView) + # Get all feature views at once (includes FeatureView, StreamFeatureView, OnDemandFeatureView, LabelView) all_feature_views: list = [] try: all_feature_views = registry.list_all_feature_views( @@ -161,6 +163,8 @@ def emit_registry_lineage( result = self.emit_on_demand_feature_view_lineage(fv, project) elif isinstance(fv, StreamFeatureView): result = self.emit_stream_feature_view_lineage(fv, project) + elif isinstance(fv, LabelView): + result = self.emit_label_view_lineage(fv, project) elif isinstance(fv, FeatureView): result = self.emit_feature_view_lineage(fv, project) else: @@ -231,6 +235,50 @@ def emit_feature_view_lineage( ) return False + def emit_label_view_lineage( + self, + label_view: "LabelView", + project: str, + ) -> bool: + """ + Emit lineage for a label view definition. + + Args: + label_view: The label view + project: Project name + + Returns: + True if successful, False otherwise + """ + if not self.is_enabled: + return False + + from feast.openlineage.mappers import feature_view_to_job + + try: + namespace = self._get_namespace(project) + job, inputs, outputs = feature_view_to_job( + label_view, + namespace=namespace, + job_type="LABEL_VIEW", + ) + + result = self._client.emit_run_event( + job_name=job.name, + run_id=str(uuid.uuid4()), + event_type=RunState.COMPLETE, + inputs=inputs, + outputs=outputs, + job_facets=job.facets, + namespace=namespace, + ) + return result + except Exception as e: + logger.error( + f"Error emitting label view lineage for {label_view.name}: {e}" + ) + return False + def emit_stream_feature_view_lineage( self, stream_feature_view: "StreamFeatureView", @@ -644,11 +692,13 @@ def emit_apply( 1. feast_feature_views_{project}: DataSources + Entities → FeatureViews 2. feast_feature_services_{project}: FeatureViews → FeatureServices - This creates a lineage graph matching Feast UI: + This creates a lineage graph matching Feast UI:: + DataSource ──→ FeatureView ──→ FeatureService ↑ Entity + Args: objects: List of Feast objects being applied project: Project name diff --git a/sdk/python/feast/openlineage/mappers.py b/sdk/python/feast/openlineage/mappers.py index 9e6fa8557a5..9be9096aed2 100644 --- a/sdk/python/feast/openlineage/mappers.py +++ b/sdk/python/feast/openlineage/mappers.py @@ -25,6 +25,7 @@ from feast import Entity, FeatureService, FeatureView from feast.data_source import DataSource from feast.field import Field + from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.stream_feature_view import StreamFeatureView @@ -205,22 +206,24 @@ def _get_data_source_uri(data_source: "DataSource") -> str: def feature_view_to_job( - feature_view: "FeatureView", + feature_view: "Union[FeatureView, LabelView]", namespace: str = "feast", include_schema: bool = True, + job_type: str = "FEATURE_VIEW", ) -> Tuple["Job", List["InputDataset"], List["OutputDataset"]]: """ - Convert a Feast FeatureView to an OpenLineage Job with inputs/outputs. + Convert a Feast FeatureView or LabelView to an OpenLineage Job with inputs/outputs. - A FeatureView represents a transformation from data sources to features, + A FeatureView/LabelView represents a transformation from data sources to features/labels, so it maps to an OpenLineage Job with: - Inputs: The batch and stream sources - - Outputs: The feature view itself (as a logical dataset) + - Outputs: The feature/label view itself (as a logical dataset) Args: - feature_view: Feast FeatureView object + feature_view: Feast FeatureView or LabelView object namespace: OpenLineage namespace include_schema: Whether to include schema information + job_type: Type identifier (FEATURE_VIEW, LABEL_VIEW, etc.) Returns: Tuple of (Job, list of InputDatasets, list of OutputDatasets) diff --git a/sdk/python/feast/permissions/auth/oidc_token_parser.py b/sdk/python/feast/permissions/auth/oidc_token_parser.py index ffff7e7ad34..7940c9d7525 100644 --- a/sdk/python/feast/permissions/auth/oidc_token_parser.py +++ b/sdk/python/feast/permissions/auth/oidc_token_parser.py @@ -1,5 +1,6 @@ import logging import os +import ssl from typing import Optional from unittest.mock import Mock @@ -21,8 +22,13 @@ class OidcTokenParser(TokenParser): """ - A `TokenParser` to use an OIDC server to retrieve the user details. - Server settings are retrieved from the `auth` configurationof the Feature store. + A ``TokenParser`` to use an OIDC server to retrieve the user details. + Server settings are retrieved from the ``auth`` configuration of the Feature store. + + Incoming tokens that contain a ``kubernetes.io`` claim (i.e. Kubernetes + service-account tokens) are handled via a lightweight TokenReview that + extracts only the namespace — no RBAC queries needed. All other tokens + follow the standard OIDC/Keycloak JWKS validation path. """ _auth_config: OidcAuthConfig @@ -30,8 +36,11 @@ class OidcTokenParser(TokenParser): def __init__(self, auth_config: OidcAuthConfig): self._auth_config = auth_config self.oidc_discovery_service = OIDCDiscoveryService( - self._auth_config.auth_discovery_url + self._auth_config.auth_discovery_url, + verify_ssl=self._auth_config.verify_ssl, + ca_cert_path=self._auth_config.ca_cert_path, ) + self._k8s_auth_api = None async def _validate_token(self, access_token: str): """ @@ -50,79 +59,201 @@ async def _validate_token(self, access_token: str): await oauth_2_scheme(request=request) + @staticmethod + def _extract_username_or_raise_error(data: dict) -> str: + """Extract the username from the decoded JWT. Raises if missing — identity is mandatory. + + Checks ``preferred_username`` first (Keycloak default), then falls back + to ``upn`` (Azure AD / Entra ID). + """ + if "preferred_username" in data: + return data["preferred_username"] + if "upn" in data: + return data["upn"] + raise AuthenticationError( + "Missing preferred_username or upn field in access token." + ) + + @staticmethod + def _extract_claim(data: dict, *keys: str, expected_type: type = list): + """Walk *keys* into *data* and return the leaf value, or ``expected_type()`` if any key is missing or the wrong type.""" + node = data + path = ".".join(keys) + for key in keys: + if not isinstance(node, dict) or key not in node: + logger.debug( + f"Missing {key} in access token claim path '{path}'. Defaulting to {expected_type()}." + ) + return expected_type() + node = node[key] + if not isinstance(node, expected_type): + logger.debug( + f"Expected {expected_type.__name__} at '{path}', got {type(node).__name__}. Defaulting to {expected_type()}." + ) + return expected_type() + return node + + @staticmethod + def _is_ssl_error(exc: BaseException) -> bool: + """Walk the exception chain looking for SSL-related errors.""" + current: Optional[BaseException] = exc + while current is not None: + if isinstance(current, ssl.SSLError): + return True + current = current.__cause__ or current.__context__ + return False + + def _decode_token(self, access_token: str) -> dict: + """Fetch the JWKS signing key and decode + verify the JWT.""" + optional_custom_headers = {"User-agent": "custom-user-agent"} + ssl_ctx = ssl.create_default_context() + if not self._auth_config.verify_ssl: + ssl_ctx.check_hostname = False + ssl_ctx.verify_mode = ssl.CERT_NONE + elif self._auth_config.ca_cert_path and os.path.exists( + self._auth_config.ca_cert_path + ): + ssl_ctx.load_verify_locations(self._auth_config.ca_cert_path) + jwks_client = PyJWKClient( + self.oidc_discovery_service.get_jwks_url(), + headers=optional_custom_headers, + ssl_context=ssl_ctx, + ) + signing_key = jwks_client.get_signing_key_from_jwt(access_token) + return jwt.decode( + access_token, + signing_key.key, + algorithms=["RS256"], + audience="account", + options={ + "verify_aud": False, + "verify_signature": True, + "verify_exp": True, + }, + leeway=10, # accepts tokens generated up to 10 seconds in the past, in case of clock skew + ) + async def user_details_from_access_token(self, access_token: str) -> User: """ - Validate the access token then decode it to extract the user credential and roles. + Validate the access token then decode it to extract the user credentials, + roles, and groups. + + A single unverified decode is performed upfront for lightweight routing: + intra-server communication, Kubernetes SA tokens (identified by the + ``kubernetes.io`` claim), or standard OIDC/Keycloak JWKS validation. Returns: - User: Current user, with associated roles. + User: Current user, with associated roles, groups, or namespaces. Raises: AuthenticationError if any error happens. """ + try: + unverified = jwt.decode(access_token, options={"verify_signature": False}) + except jwt.exceptions.DecodeError as e: + raise AuthenticationError(f"Failed to decode token: {e}") - # check if intra server communication - user = self._get_intra_comm_user(access_token) + user = self._get_intra_comm_user(unverified) if user: return user + if isinstance(unverified.get("kubernetes.io"), dict): + logger.debug("Detected kubernetes.io claim — validating via TokenReview") + try: + return await self._validate_k8s_sa_token_and_extract_namespace( + access_token + ) + except AuthenticationError: + raise + except Exception as e: + logger.error(f"Kubernetes token validation failed: {e}") + raise AuthenticationError(f"Kubernetes token validation failed: {e}") + + # Standard OIDC / Keycloak flow try: await self._validate_token(access_token) logger.debug("Token successfully validated.") except Exception as e: + if self._is_ssl_error(e): + logger.error( + "OIDC provider SSL certificate verification failed. " + "If using a self-signed certificate, set verify_ssl: false " + "or provide a CA certificate via ca_cert_path." + ) logger.error(f"Token validation failed: {e}") raise AuthenticationError(f"Invalid token: {e}") - optional_custom_headers = {"User-agent": "custom-user-agent"} - jwks_client = PyJWKClient( - self.oidc_discovery_service.get_jwks_url(), headers=optional_custom_headers - ) - try: - signing_key = jwks_client.get_signing_key_from_jwt(access_token) - data = jwt.decode( - access_token, - signing_key.key, - algorithms=["RS256"], - audience="account", - options={ - "verify_aud": False, - "verify_signature": True, - "verify_exp": True, - }, - leeway=10, # accepts tokens generated up to 10 seconds in the past, in case of clock skew - ) + data = self._decode_token(access_token) - if "preferred_username" not in data: - raise AuthenticationError( - "Missing preferred_username field in access token." - ) - current_user = data["preferred_username"] - - if "resource_access" not in data: - logger.warning("Missing resource_access field in access token.") - client_id = self._auth_config.client_id - if client_id not in data["resource_access"]: - logger.warning( - f"Missing resource_access.{client_id} field in access token. Defaulting to empty roles." + current_user = self._extract_username_or_raise_error(data) + roles = ( + self._extract_claim( + data, "resource_access", self._auth_config.client_id, "roles" ) - roles = [] - else: - roles = data["resource_access"][client_id]["roles"] + if self._auth_config.client_id + else [] + ) + groups = self._extract_claim(data, "groups") - logger.info(f"Extracted user {current_user} and roles {roles}") - return User(username=current_user, roles=roles) - except jwt.exceptions.InvalidTokenError: + logger.info( + f"Extracted user {current_user} with roles {roles}, groups {groups}" + ) + return User( + username=current_user, + roles=roles, + groups=groups, + ) + except jwt.exceptions.PyJWTError as e: + if self._is_ssl_error(e): + logger.error( + "OIDC JWKS endpoint SSL certificate verification failed. " + "If using a self-signed certificate, set verify_ssl: false " + "or provide a CA certificate via ca_cert_path." + ) logger.exception("Exception while parsing the token:") raise AuthenticationError("Invalid token.") - def _get_intra_comm_user(self, access_token: str) -> Optional[User]: + async def _validate_k8s_sa_token_and_extract_namespace( + self, access_token: str + ) -> User: + """Validate a K8s SA token via TokenReview and extract the namespace. + + Lightweight alternative to full KubernetesTokenParser — only validates + the token and extracts the namespace from the authenticated identity. + No RBAC queries (RoleBindings, ClusterRoleBindings) are performed, + so the server SA needs only ``tokenreviews/create`` permission. + """ + from kubernetes import client, config + + if self._k8s_auth_api is None: + config.load_incluster_config() + self._k8s_auth_api = client.AuthenticationV1Api() + + token_review = client.V1TokenReview( + spec=client.V1TokenReviewSpec(token=access_token) + ) + auth_api: client.AuthenticationV1Api = self._k8s_auth_api + response = auth_api.create_token_review(token_review) + + if not response.status.authenticated: + raise AuthenticationError( + f"Kubernetes token validation failed: {response.status.error}" + ) + + username = getattr(response.status.user, "username", "") or "" + namespaces = [] + if username.startswith("system:serviceaccount:") and username.count(":") >= 3: + namespaces.append(username.split(":")[2]) + + logger.info(f"SA token validated — user: {username}, namespaces: {namespaces}") + return User(username=username, roles=[], groups=[], namespaces=namespaces) + + @staticmethod + def _get_intra_comm_user(decoded_token: dict) -> Optional[User]: intra_communication_base64 = os.getenv("INTRA_COMMUNICATION_BASE64") if intra_communication_base64: - decoded_token = jwt.decode( - access_token, options={"verify_signature": False} - ) if "preferred_username" in decoded_token: preferred_username: str = decoded_token["preferred_username"] if ( diff --git a/sdk/python/feast/permissions/auth_model.py b/sdk/python/feast/permissions/auth_model.py index 3690d62b728..aa38c0d8937 100644 --- a/sdk/python/feast/permissions/auth_model.py +++ b/sdk/python/feast/permissions/auth_model.py @@ -1,63 +1,68 @@ -# -------------------------------------------------------------------- -# Extends OIDC client auth model with an optional `token` field. -# Works on Pydantic v2-only. -# -# Accepted credential sets (exactly **one** of): -# 1 pre-issued `token` -# 2 `client_secret` (client-credentials flow) -# 3 `username` + `password` + `client_secret` (ROPG) -# -------------------------------------------------------------------- from __future__ import annotations -from typing import Literal, Optional +from typing import Literal, Optional, Tuple from pydantic import ConfigDict, model_validator from feast.repo_config import FeastConfigBaseModel +def _check_mutually_exclusive(**groups: Tuple[object, ...]) -> None: + """Validate that at most one named group is configured, and completely. + + Each *group* is a tuple of field values. + A group is **active** only when *all* its values are truthy. + A group is **partial** (error) when *any* but not *all* values are truthy. + At most one active group may exist. + """ + partial = [name for name, vals in groups.items() if any(vals) and not all(vals)] + if partial: + raise ValueError( + f"Incomplete configuration for '{partial[0]}': " + f"configure all of these fields together, or none at all. " + f"Check the documentation for valid credential combinations." + ) + active = [name for name, vals in groups.items() if all(vals)] + if len(active) > 1: + raise ValueError( + f"Only one of [{', '.join(groups)}] may be set, " + f"but got: {', '.join(active)}" + ) + + class AuthConfig(FeastConfigBaseModel): type: Literal["oidc", "kubernetes", "no_auth"] = "no_auth" class OidcAuthConfig(AuthConfig): auth_discovery_url: str - client_id: str + client_id: Optional[str] = None + verify_ssl: bool = True + ca_cert_path: str = "" class OidcClientAuthConfig(OidcAuthConfig): - # any **one** of the four fields below is sufficient + auth_discovery_url: Optional[str] = None # type: ignore[assignment] + client_id: Optional[str] = None + username: Optional[str] = None password: Optional[str] = None client_secret: Optional[str] = None - token: Optional[str] = None # pre-issued `token` + token: Optional[str] = None + token_env_var: Optional[str] = None @model_validator(mode="after") def _validate_credentials(self): - """Enforce exactly one valid credential set.""" - has_user_pass = bool(self.username) and bool(self.password) - has_secret = bool(self.client_secret) - has_token = bool(self.token) - - # 1 static token - if has_token and not (has_user_pass or has_secret): - return self - - # 2 client_credentials - if has_secret and not has_user_pass and not has_token: - return self - - # 3 ROPG - if has_user_pass and has_secret and not has_token: - return self - - raise ValueError( - "Invalid OIDC client auth combination: " - "provide either\n" - " • token\n" - " • client_secret (without username/password)\n" - " • username + password + client_secret" + network = (self.client_secret, self.auth_discovery_url, self.client_id) + if self.username or self.password: + network += (self.username, self.password) + + _check_mutually_exclusive( + token=(self.token,), + token_env_var=(self.token_env_var,), + client_credentials=network, ) + return self class NoAuthConfig(AuthConfig): @@ -65,7 +70,6 @@ class NoAuthConfig(AuthConfig): class KubernetesAuthConfig(AuthConfig): - # Optional user token for users (not service accounts) user_token: Optional[str] = None model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow") diff --git a/sdk/python/feast/permissions/client/intra_comm_authentication_client_manager.py b/sdk/python/feast/permissions/client/intra_comm_authentication_client_manager.py index 30476316c12..bdc6159a2f8 100644 --- a/sdk/python/feast/permissions/client/intra_comm_authentication_client_manager.py +++ b/sdk/python/feast/permissions/client/intra_comm_authentication_client_manager.py @@ -29,4 +29,4 @@ def get_token(self): f"No Auth client manager implemented for the auth type:{self.auth_config.type}" ) - return jwt.encode(payload, "") + return jwt.encode(payload, "", algorithm="none") diff --git a/sdk/python/feast/permissions/client/kubernetes_auth_client_manager.py b/sdk/python/feast/permissions/client/kubernetes_auth_client_manager.py index 0cee687d08f..ac94b8713ad 100644 --- a/sdk/python/feast/permissions/client/kubernetes_auth_client_manager.py +++ b/sdk/python/feast/permissions/client/kubernetes_auth_client_manager.py @@ -22,7 +22,7 @@ def get_token(self): "sub": f":::{intra_communication_base64}", # Subject claim } - return jwt.encode(payload, "") + return jwt.encode(payload, "", algorithm="none") # Check if user token is provided in config (for external users) if hasattr(self.auth_config, "user_token") and self.auth_config.user_token: diff --git a/sdk/python/feast/permissions/client/oidc_authentication_client_manager.py b/sdk/python/feast/permissions/client/oidc_authentication_client_manager.py index e7db600cab5..37e613dafc1 100644 --- a/sdk/python/feast/permissions/client/oidc_authentication_client_manager.py +++ b/sdk/python/feast/permissions/client/oidc_authentication_client_manager.py @@ -1,5 +1,6 @@ import logging import os +from typing import Optional import jwt import requests @@ -10,6 +11,8 @@ logger = logging.getLogger(__name__) +SA_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token" + class OidcAuthClientManager(AuthenticationClientManager): def __init__(self, auth_config: OidcClientAuthConfig): @@ -17,24 +20,66 @@ def __init__(self, auth_config: OidcClientAuthConfig): def get_token(self): intra_communication_base64 = os.getenv("INTRA_COMMUNICATION_BASE64") - # If intra server communication call if intra_communication_base64: payload = { - "preferred_username": f"{intra_communication_base64}", # Subject claim + "preferred_username": f"{intra_communication_base64}", } + return jwt.encode(payload, "", algorithm="none") - return jwt.encode(payload, "") + if self.auth_config.token: + return self.auth_config.token + elif self.auth_config.token_env_var: + env_token = os.getenv(self.auth_config.token_env_var) + if env_token: + return env_token + else: + raise PermissionError( + f"token_env_var='{self.auth_config.token_env_var}' is configured " + f"but the environment variable is not set or is empty." + ) + elif self.auth_config.client_secret: + return self._fetch_token_from_idp() + else: + env_token = os.getenv("FEAST_OIDC_TOKEN") + if env_token: + return env_token - # Fetch the token endpoint from the discovery URL - token_endpoint = OIDCDiscoveryService( - self.auth_config.auth_discovery_url - ).get_token_url() + sa_token = self._read_sa_token() + if sa_token: + return sa_token - # 1) pre-issued JWT supplied in config - if getattr(self.auth_config, "token", None): - return self.auth_config.token + raise PermissionError( + "No OIDC token source configured. Provide one of: " + "'token', 'token_env_var', 'client_secret' (with " + "'auth_discovery_url' and 'client_id'), set the " + "FEAST_OIDC_TOKEN environment variable, or run inside " + "a Kubernetes pod with a mounted service account token." + ) + + @staticmethod + def _read_sa_token() -> Optional[str]: + """Read the Kubernetes service account token from the standard mount path.""" + if os.path.isfile(SA_TOKEN_PATH): + with open(SA_TOKEN_PATH) as f: + token = f.read().strip() + if token: + return token + return None + + def _fetch_token_from_idp(self) -> str: + """Obtain an access token via client_credentials or ROPG flow.""" + if self.auth_config.auth_discovery_url is None: + raise ValueError( + "auth_discovery_url is required for IDP token fetch " + "(client_credentials or ROPG flow)." + ) + discovery = OIDCDiscoveryService( + self.auth_config.auth_discovery_url, + verify_ssl=self.auth_config.verify_ssl, + ca_cert_path=self.auth_config.ca_cert_path, + ) + token_endpoint = discovery.get_token_url() - # 2) client_credentials if self.auth_config.client_secret and not ( self.auth_config.username and self.auth_config.password ): @@ -43,7 +88,6 @@ def get_token(self): "client_id": self.auth_config.client_id, "client_secret": self.auth_config.client_secret, } - # 3) ROPG (username + password + client_secret) else: token_request_body = { "grant_type": "password", @@ -52,11 +96,15 @@ def get_token(self): "username": self.auth_config.username, "password": self.auth_config.password, } - headers = {"Content-Type": "application/x-www-form-urlencoded"} + headers = {"Content-Type": "application/x-www-form-urlencoded"} token_response = requests.post( - token_endpoint, data=token_request_body, headers=headers + token_endpoint, + data=token_request_body, + headers=headers, + verify=discovery._get_verify(), ) + if token_response.status_code == 200: access_token = token_response.json()["access_token"] if not access_token: diff --git a/sdk/python/feast/permissions/oidc_service.py b/sdk/python/feast/permissions/oidc_service.py index 73d0ec8f1b7..48edccd3d44 100644 --- a/sdk/python/feast/permissions/oidc_service.py +++ b/sdk/python/feast/permissions/oidc_service.py @@ -1,9 +1,15 @@ +import os + import requests class OIDCDiscoveryService: - def __init__(self, discovery_url: str): + def __init__( + self, discovery_url: str, verify_ssl: bool = True, ca_cert_path: str = "" + ): self.discovery_url = discovery_url + self._verify_ssl = verify_ssl + self._ca_cert_path = ca_cert_path self._discovery_data = None # Initialize it lazily. @property @@ -13,9 +19,16 @@ def discovery_data(self): self._discovery_data = self._fetch_discovery_data() return self._discovery_data + def _get_verify(self): + if not self._verify_ssl: + return False + if self._ca_cert_path and os.path.exists(self._ca_cert_path): + return self._ca_cert_path + return True + def _fetch_discovery_data(self) -> dict: try: - response = requests.get(self.discovery_url) + response = requests.get(self.discovery_url, verify=self._get_verify()) response.raise_for_status() return response.json() except requests.RequestException as e: diff --git a/sdk/python/feast/permissions/permission.py b/sdk/python/feast/permissions/permission.py index 964ca743e71..208575195e9 100644 --- a/sdk/python/feast/permissions/permission.py +++ b/sdk/python/feast/permissions/permission.py @@ -277,4 +277,5 @@ def get_type_class_from_permission_type(permission_type: str): "VALIDATION_REFERENCE": "feast.saved_dataset.ValidationReference", "SAVED_DATASET": "feast.saved_dataset.SavedDataset", "PERMISSION": "feast.permissions.permission.Permission", + "LABEL_VIEW": "feast.labeling.label_view.LabelView", } diff --git a/sdk/python/feast/proto_json.py b/sdk/python/feast/proto_json.py index 487dc4284f3..91cec0c2b66 100644 --- a/sdk/python/feast/proto_json.py +++ b/sdk/python/feast/proto_json.py @@ -63,6 +63,18 @@ def to_json_object(printer: _Printer, message: ProtoMessage) -> JsonObject: # to JSON. The parse back result will be different from original message. if which is None or which == "null_val": return None + elif which in ("list_val", "set_val"): + # Nested collection: RepeatedValue containing Values + repeated = getattr(message, which) + value: JsonObject = [ + printer._MessageToJsonObject(inner_val) for inner_val in repeated.val + ] + elif which == "zoned_timestamp_val": + # ZonedTimestamp is a message; render it as an ISO 8601 string in its + # stored zone so the result is JSON-serializable (the raw message is not). + from feast.feature_server_utils import _zoned_timestamp_to_str + + value = _zoned_timestamp_to_str(message.zoned_timestamp_val) elif "_list_" in which: value = list(getattr(message, which).val) else: @@ -86,6 +98,19 @@ def from_json_object( if len(value) == 0: # Clear will mark the struct as modified so it will be created even if there are no values message.int64_list_val.Clear() + elif isinstance(value[0], list) or ( + value[0] is None and any(isinstance(v, list) for v in value) + ): + # Nested collection (list of lists). + # Check any() to handle cases where the first element is None + # (empty inner collections round-trip through proto as None). + # Default to list_val since JSON transport loses the + # outer/inner set distinction. + rv = RepeatedValue() + for inner in value: + inner_val = rv.val.add() + from_json_object(parser, inner, inner_val) + message.list_val.CopyFrom(rv) elif isinstance(value[0], bool): message.bool_list_val.val.extend(value) elif isinstance(value[0], str): diff --git a/sdk/python/feast/protos/feast/core/Aggregation_pb2.py b/sdk/python/feast/protos/feast/core/Aggregation_pb2.py index 48f107b8eff..44013acd55d 100644 --- a/sdk/python/feast/protos/feast/core/Aggregation_pb2.py +++ b/sdk/python/feast/protos/feast/core/Aggregation_pb2.py @@ -15,7 +15,7 @@ from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cfeast/core/Aggregation.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\"\xd3\x01\n\x0bAggregation\x12\x16\n\x06column\x18\x01 \x01(\tR\x06column\x12\x1a\n\x08function\x18\x02 \x01(\tR\x08function\x12:\n\x0btime_window\x18\x03 \x01(\x0b2\x19.google.protobuf.DurationR\ntimeWindow\x12@\n\x0eslide_interval\x18\x04 \x01(\x0b2\x19.google.protobuf.DurationR\rslideInterval\x12\x12\n\x04name\x18\x05 \x01(\tR\x04nameBU\n\x10feast.proto.coreB\x10AggregationProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66\x65\x61st/core/Aggregation.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\"\xa0\x01\n\x0b\x41ggregation\x12\x0e\n\x06\x63olumn\x18\x01 \x01(\t\x12\x10\n\x08\x66unction\x18\x02 \x01(\t\x12.\n\x0btime_window\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0eslide_interval\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x0c\n\x04name\x18\x05 \x01(\tBU\n\x10\x66\x65\x61st.proto.coreB\x10\x41ggregationProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -24,5 +24,5 @@ _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\020AggregationProtoZ/github.com/feast-dev/feast/go/protos/feast/core' _globals['_AGGREGATION']._serialized_start=77 - _globals['_AGGREGATION']._serialized_end=288 + _globals['_AGGREGATION']._serialized_end=237 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/Aggregation_pb2.pyi b/sdk/python/feast/protos/feast/core/Aggregation_pb2.pyi index af9ec2b191f..4c6bd7c089c 100644 --- a/sdk/python/feast/protos/feast/core/Aggregation_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/Aggregation_pb2.pyi @@ -25,11 +25,11 @@ class Aggregation(google.protobuf.message.Message): NAME_FIELD_NUMBER: builtins.int column: builtins.str function: builtins.str - name: builtins.str @property def time_window(self) -> google.protobuf.duration_pb2.Duration: ... @property def slide_interval(self) -> google.protobuf.duration_pb2.Duration: ... + name: builtins.str def __init__( self, *, diff --git a/sdk/python/feast/protos/feast/core/DataSource_pb2.py b/sdk/python/feast/protos/feast/core/DataSource_pb2.py index f3086233584..51dee5652a2 100644 --- a/sdk/python/feast/protos/feast/core/DataSource_pb2.py +++ b/sdk/python/feast/protos/feast/core/DataSource_pb2.py @@ -19,7 +19,7 @@ from feast.protos.feast.core import Feature_pb2 as feast_dot_core_dot_Feature__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x66\x65\x61st/core/DataSource.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/DataFormat.proto\x1a\x17\x66\x65\x61st/types/Value.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\"\x89\x18\n\nDataSource\x12\x0c\n\x04name\x18\x14 \x01(\t\x12\x0f\n\x07project\x18\x15 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x17 \x01(\t\x12.\n\x04tags\x18\x18 \x03(\x0b\x32 .feast.core.DataSource.TagsEntry\x12\r\n\x05owner\x18\x19 \x01(\t\x12/\n\x04type\x18\x01 \x01(\x0e\x32!.feast.core.DataSource.SourceType\x12?\n\rfield_mapping\x18\x02 \x03(\x0b\x32(.feast.core.DataSource.FieldMappingEntry\x12\x17\n\x0ftimestamp_field\x18\x03 \x01(\t\x12\x1d\n\x15\x64\x61te_partition_column\x18\x04 \x01(\t\x12 \n\x18\x63reated_timestamp_column\x18\x05 \x01(\t\x12\x1e\n\x16\x64\x61ta_source_class_type\x18\x11 \x01(\t\x12,\n\x0c\x62\x61tch_source\x18\x1a \x01(\x0b\x32\x16.feast.core.DataSource\x12/\n\x04meta\x18\x32 \x01(\x0b\x32!.feast.core.DataSource.SourceMeta\x12:\n\x0c\x66ile_options\x18\x0b \x01(\x0b\x32\".feast.core.DataSource.FileOptionsH\x00\x12\x42\n\x10\x62igquery_options\x18\x0c \x01(\x0b\x32&.feast.core.DataSource.BigQueryOptionsH\x00\x12<\n\rkafka_options\x18\r \x01(\x0b\x32#.feast.core.DataSource.KafkaOptionsH\x00\x12@\n\x0fkinesis_options\x18\x0e \x01(\x0b\x32%.feast.core.DataSource.KinesisOptionsH\x00\x12\x42\n\x10redshift_options\x18\x0f \x01(\x0b\x32&.feast.core.DataSource.RedshiftOptionsH\x00\x12I\n\x14request_data_options\x18\x12 \x01(\x0b\x32).feast.core.DataSource.RequestDataOptionsH\x00\x12\x44\n\x0e\x63ustom_options\x18\x10 \x01(\x0b\x32*.feast.core.DataSource.CustomSourceOptionsH\x00\x12\x44\n\x11snowflake_options\x18\x13 \x01(\x0b\x32\'.feast.core.DataSource.SnowflakeOptionsH\x00\x12:\n\x0cpush_options\x18\x16 \x01(\x0b\x32\".feast.core.DataSource.PushOptionsH\x00\x12<\n\rspark_options\x18\x1b \x01(\x0b\x32#.feast.core.DataSource.SparkOptionsH\x00\x12<\n\rtrino_options\x18\x1e \x01(\x0b\x32#.feast.core.DataSource.TrinoOptionsH\x00\x12>\n\x0e\x61thena_options\x18# \x01(\x0b\x32$.feast.core.DataSource.AthenaOptionsH\x00\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x33\n\x11\x46ieldMappingEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xf5\x01\n\nSourceMeta\x12:\n\x16\x65\x61rliestEventTimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14latestEventTimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x35\n\x11\x63reated_timestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a\x65\n\x0b\x46ileOptions\x12+\n\x0b\x66ile_format\x18\x01 \x01(\x0b\x32\x16.feast.core.FileFormat\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x1c\n\x14s3_endpoint_override\x18\x03 \x01(\t\x1a/\n\x0f\x42igQueryOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x1a,\n\x0cTrinoOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x1a\xae\x01\n\x0cKafkaOptions\x12\x1f\n\x17kafka_bootstrap_servers\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x30\n\x0emessage_format\x18\x03 \x01(\x0b\x32\x18.feast.core.StreamFormat\x12<\n\x19watermark_delay_threshold\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\x66\n\x0eKinesisOptions\x12\x0e\n\x06region\x18\x01 \x01(\t\x12\x13\n\x0bstream_name\x18\x02 \x01(\t\x12/\n\rrecord_format\x18\x03 \x01(\x0b\x32\x18.feast.core.StreamFormat\x1aQ\n\x0fRedshiftOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0e\n\x06schema\x18\x03 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x04 \x01(\t\x1aT\n\rAthenaOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x61ta_source\x18\x04 \x01(\t\x1aX\n\x10SnowflakeOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0e\n\x06schema\x18\x03 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06\x1a\xa4\x01\n\x0cSparkOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\x12\x13\n\x0b\x66ile_format\x18\x04 \x01(\t\x12$\n\x1c\x64\x61te_partition_column_format\x18\x05 \x01(\t\x12-\n\x0ctable_format\x18\x06 \x01(\x0b\x32\x17.feast.core.TableFormat\x1a,\n\x13\x43ustomSourceOptions\x12\x15\n\rconfiguration\x18\x01 \x01(\x0c\x1a\xf7\x01\n\x12RequestDataOptions\x12Z\n\x11\x64\x65precated_schema\x18\x02 \x03(\x0b\x32?.feast.core.DataSource.RequestDataOptions.DeprecatedSchemaEntry\x12)\n\x06schema\x18\x03 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x1aT\n\x15\x44\x65precatedSchemaEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0e\x32\x1b.feast.types.ValueType.Enum:\x02\x38\x01J\x04\x08\x01\x10\x02\x1a\x13\n\x0bPushOptionsJ\x04\x08\x01\x10\x02\"\xf8\x01\n\nSourceType\x12\x0b\n\x07INVALID\x10\x00\x12\x0e\n\nBATCH_FILE\x10\x01\x12\x13\n\x0f\x42\x41TCH_SNOWFLAKE\x10\x08\x12\x12\n\x0e\x42\x41TCH_BIGQUERY\x10\x02\x12\x12\n\x0e\x42\x41TCH_REDSHIFT\x10\x05\x12\x10\n\x0cSTREAM_KAFKA\x10\x03\x12\x12\n\x0eSTREAM_KINESIS\x10\x04\x12\x11\n\rCUSTOM_SOURCE\x10\x06\x12\x12\n\x0eREQUEST_SOURCE\x10\x07\x12\x0f\n\x0bPUSH_SOURCE\x10\t\x12\x0f\n\x0b\x42\x41TCH_TRINO\x10\n\x12\x0f\n\x0b\x42\x41TCH_SPARK\x10\x0b\x12\x10\n\x0c\x42\x41TCH_ATHENA\x10\x0c\x42\t\n\x07optionsJ\x04\x08\x06\x10\x0b\"=\n\x0e\x44\x61taSourceList\x12+\n\x0b\x64\x61tasources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSourceBT\n\x10\x66\x65\x61st.proto.coreB\x0f\x44\x61taSourceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x66\x65\x61st/core/DataSource.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/DataFormat.proto\x1a\x17\x66\x65\x61st/types/Value.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\"\xa7\x18\n\nDataSource\x12\x0c\n\x04name\x18\x14 \x01(\t\x12\x0f\n\x07project\x18\x15 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x17 \x01(\t\x12.\n\x04tags\x18\x18 \x03(\x0b\x32 .feast.core.DataSource.TagsEntry\x12\r\n\x05owner\x18\x19 \x01(\t\x12/\n\x04type\x18\x01 \x01(\x0e\x32!.feast.core.DataSource.SourceType\x12?\n\rfield_mapping\x18\x02 \x03(\x0b\x32(.feast.core.DataSource.FieldMappingEntry\x12\x17\n\x0ftimestamp_field\x18\x03 \x01(\t\x12\x1d\n\x15\x64\x61te_partition_column\x18\x04 \x01(\t\x12 \n\x18\x63reated_timestamp_column\x18\x05 \x01(\t\x12\x1c\n\x14timestamp_field_type\x18\x1c \x01(\t\x12\x1e\n\x16\x64\x61ta_source_class_type\x18\x11 \x01(\t\x12,\n\x0c\x62\x61tch_source\x18\x1a \x01(\x0b\x32\x16.feast.core.DataSource\x12/\n\x04meta\x18\x32 \x01(\x0b\x32!.feast.core.DataSource.SourceMeta\x12:\n\x0c\x66ile_options\x18\x0b \x01(\x0b\x32\".feast.core.DataSource.FileOptionsH\x00\x12\x42\n\x10\x62igquery_options\x18\x0c \x01(\x0b\x32&.feast.core.DataSource.BigQueryOptionsH\x00\x12<\n\rkafka_options\x18\r \x01(\x0b\x32#.feast.core.DataSource.KafkaOptionsH\x00\x12@\n\x0fkinesis_options\x18\x0e \x01(\x0b\x32%.feast.core.DataSource.KinesisOptionsH\x00\x12\x42\n\x10redshift_options\x18\x0f \x01(\x0b\x32&.feast.core.DataSource.RedshiftOptionsH\x00\x12I\n\x14request_data_options\x18\x12 \x01(\x0b\x32).feast.core.DataSource.RequestDataOptionsH\x00\x12\x44\n\x0e\x63ustom_options\x18\x10 \x01(\x0b\x32*.feast.core.DataSource.CustomSourceOptionsH\x00\x12\x44\n\x11snowflake_options\x18\x13 \x01(\x0b\x32\'.feast.core.DataSource.SnowflakeOptionsH\x00\x12:\n\x0cpush_options\x18\x16 \x01(\x0b\x32\".feast.core.DataSource.PushOptionsH\x00\x12<\n\rspark_options\x18\x1b \x01(\x0b\x32#.feast.core.DataSource.SparkOptionsH\x00\x12<\n\rtrino_options\x18\x1e \x01(\x0b\x32#.feast.core.DataSource.TrinoOptionsH\x00\x12>\n\x0e\x61thena_options\x18# \x01(\x0b\x32$.feast.core.DataSource.AthenaOptionsH\x00\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x33\n\x11\x46ieldMappingEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xf5\x01\n\nSourceMeta\x12:\n\x16\x65\x61rliestEventTimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14latestEventTimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x35\n\x11\x63reated_timestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a\x65\n\x0b\x46ileOptions\x12+\n\x0b\x66ile_format\x18\x01 \x01(\x0b\x32\x16.feast.core.FileFormat\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x1c\n\x14s3_endpoint_override\x18\x03 \x01(\t\x1a/\n\x0f\x42igQueryOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x1a,\n\x0cTrinoOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x1a\xae\x01\n\x0cKafkaOptions\x12\x1f\n\x17kafka_bootstrap_servers\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x30\n\x0emessage_format\x18\x03 \x01(\x0b\x32\x18.feast.core.StreamFormat\x12<\n\x19watermark_delay_threshold\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\x66\n\x0eKinesisOptions\x12\x0e\n\x06region\x18\x01 \x01(\t\x12\x13\n\x0bstream_name\x18\x02 \x01(\t\x12/\n\rrecord_format\x18\x03 \x01(\x0b\x32\x18.feast.core.StreamFormat\x1aQ\n\x0fRedshiftOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0e\n\x06schema\x18\x03 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x04 \x01(\t\x1aT\n\rAthenaOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x61ta_source\x18\x04 \x01(\t\x1aX\n\x10SnowflakeOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0e\n\x06schema\x18\x03 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06\x1a\xa4\x01\n\x0cSparkOptions\x12\r\n\x05table\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\x12\x13\n\x0b\x66ile_format\x18\x04 \x01(\t\x12$\n\x1c\x64\x61te_partition_column_format\x18\x05 \x01(\t\x12-\n\x0ctable_format\x18\x06 \x01(\x0b\x32\x17.feast.core.TableFormat\x1a,\n\x13\x43ustomSourceOptions\x12\x15\n\rconfiguration\x18\x01 \x01(\x0c\x1a\xf7\x01\n\x12RequestDataOptions\x12Z\n\x11\x64\x65precated_schema\x18\x02 \x03(\x0b\x32?.feast.core.DataSource.RequestDataOptions.DeprecatedSchemaEntry\x12)\n\x06schema\x18\x03 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x1aT\n\x15\x44\x65precatedSchemaEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0e\x32\x1b.feast.types.ValueType.Enum:\x02\x38\x01J\x04\x08\x01\x10\x02\x1a\x13\n\x0bPushOptionsJ\x04\x08\x01\x10\x02\"\xf8\x01\n\nSourceType\x12\x0b\n\x07INVALID\x10\x00\x12\x0e\n\nBATCH_FILE\x10\x01\x12\x13\n\x0f\x42\x41TCH_SNOWFLAKE\x10\x08\x12\x12\n\x0e\x42\x41TCH_BIGQUERY\x10\x02\x12\x12\n\x0e\x42\x41TCH_REDSHIFT\x10\x05\x12\x10\n\x0cSTREAM_KAFKA\x10\x03\x12\x12\n\x0eSTREAM_KINESIS\x10\x04\x12\x11\n\rCUSTOM_SOURCE\x10\x06\x12\x12\n\x0eREQUEST_SOURCE\x10\x07\x12\x0f\n\x0bPUSH_SOURCE\x10\t\x12\x0f\n\x0b\x42\x41TCH_TRINO\x10\n\x12\x0f\n\x0b\x42\x41TCH_SPARK\x10\x0b\x12\x10\n\x0c\x42\x41TCH_ATHENA\x10\x0c\x42\t\n\x07optionsJ\x04\x08\x06\x10\x0b\"=\n\x0e\x44\x61taSourceList\x12+\n\x0b\x64\x61tasources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSourceBT\n\x10\x66\x65\x61st.proto.coreB\x0f\x44\x61taSourceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -34,41 +34,41 @@ _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._options = None _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._serialized_options = b'8\001' _globals['_DATASOURCE']._serialized_start=189 - _globals['_DATASOURCE']._serialized_end=3270 - _globals['_DATASOURCE_TAGSENTRY']._serialized_start=1436 - _globals['_DATASOURCE_TAGSENTRY']._serialized_end=1479 - _globals['_DATASOURCE_FIELDMAPPINGENTRY']._serialized_start=1481 - _globals['_DATASOURCE_FIELDMAPPINGENTRY']._serialized_end=1532 - _globals['_DATASOURCE_SOURCEMETA']._serialized_start=1535 - _globals['_DATASOURCE_SOURCEMETA']._serialized_end=1780 - _globals['_DATASOURCE_FILEOPTIONS']._serialized_start=1782 - _globals['_DATASOURCE_FILEOPTIONS']._serialized_end=1883 - _globals['_DATASOURCE_BIGQUERYOPTIONS']._serialized_start=1885 - _globals['_DATASOURCE_BIGQUERYOPTIONS']._serialized_end=1932 - _globals['_DATASOURCE_TRINOOPTIONS']._serialized_start=1934 - _globals['_DATASOURCE_TRINOOPTIONS']._serialized_end=1978 - _globals['_DATASOURCE_KAFKAOPTIONS']._serialized_start=1981 - _globals['_DATASOURCE_KAFKAOPTIONS']._serialized_end=2155 - _globals['_DATASOURCE_KINESISOPTIONS']._serialized_start=2157 - _globals['_DATASOURCE_KINESISOPTIONS']._serialized_end=2259 - _globals['_DATASOURCE_REDSHIFTOPTIONS']._serialized_start=2261 - _globals['_DATASOURCE_REDSHIFTOPTIONS']._serialized_end=2342 - _globals['_DATASOURCE_ATHENAOPTIONS']._serialized_start=2344 - _globals['_DATASOURCE_ATHENAOPTIONS']._serialized_end=2428 - _globals['_DATASOURCE_SNOWFLAKEOPTIONS']._serialized_start=2430 - _globals['_DATASOURCE_SNOWFLAKEOPTIONS']._serialized_end=2518 - _globals['_DATASOURCE_SPARKOPTIONS']._serialized_start=2521 - _globals['_DATASOURCE_SPARKOPTIONS']._serialized_end=2685 - _globals['_DATASOURCE_CUSTOMSOURCEOPTIONS']._serialized_start=2687 - _globals['_DATASOURCE_CUSTOMSOURCEOPTIONS']._serialized_end=2731 - _globals['_DATASOURCE_REQUESTDATAOPTIONS']._serialized_start=2734 - _globals['_DATASOURCE_REQUESTDATAOPTIONS']._serialized_end=2981 - _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._serialized_start=2891 - _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._serialized_end=2975 - _globals['_DATASOURCE_PUSHOPTIONS']._serialized_start=2983 - _globals['_DATASOURCE_PUSHOPTIONS']._serialized_end=3002 - _globals['_DATASOURCE_SOURCETYPE']._serialized_start=3005 - _globals['_DATASOURCE_SOURCETYPE']._serialized_end=3253 - _globals['_DATASOURCELIST']._serialized_start=3272 - _globals['_DATASOURCELIST']._serialized_end=3333 + _globals['_DATASOURCE']._serialized_end=3300 + _globals['_DATASOURCE_TAGSENTRY']._serialized_start=1466 + _globals['_DATASOURCE_TAGSENTRY']._serialized_end=1509 + _globals['_DATASOURCE_FIELDMAPPINGENTRY']._serialized_start=1511 + _globals['_DATASOURCE_FIELDMAPPINGENTRY']._serialized_end=1562 + _globals['_DATASOURCE_SOURCEMETA']._serialized_start=1565 + _globals['_DATASOURCE_SOURCEMETA']._serialized_end=1810 + _globals['_DATASOURCE_FILEOPTIONS']._serialized_start=1812 + _globals['_DATASOURCE_FILEOPTIONS']._serialized_end=1913 + _globals['_DATASOURCE_BIGQUERYOPTIONS']._serialized_start=1915 + _globals['_DATASOURCE_BIGQUERYOPTIONS']._serialized_end=1962 + _globals['_DATASOURCE_TRINOOPTIONS']._serialized_start=1964 + _globals['_DATASOURCE_TRINOOPTIONS']._serialized_end=2008 + _globals['_DATASOURCE_KAFKAOPTIONS']._serialized_start=2011 + _globals['_DATASOURCE_KAFKAOPTIONS']._serialized_end=2185 + _globals['_DATASOURCE_KINESISOPTIONS']._serialized_start=2187 + _globals['_DATASOURCE_KINESISOPTIONS']._serialized_end=2289 + _globals['_DATASOURCE_REDSHIFTOPTIONS']._serialized_start=2291 + _globals['_DATASOURCE_REDSHIFTOPTIONS']._serialized_end=2372 + _globals['_DATASOURCE_ATHENAOPTIONS']._serialized_start=2374 + _globals['_DATASOURCE_ATHENAOPTIONS']._serialized_end=2458 + _globals['_DATASOURCE_SNOWFLAKEOPTIONS']._serialized_start=2460 + _globals['_DATASOURCE_SNOWFLAKEOPTIONS']._serialized_end=2548 + _globals['_DATASOURCE_SPARKOPTIONS']._serialized_start=2551 + _globals['_DATASOURCE_SPARKOPTIONS']._serialized_end=2715 + _globals['_DATASOURCE_CUSTOMSOURCEOPTIONS']._serialized_start=2717 + _globals['_DATASOURCE_CUSTOMSOURCEOPTIONS']._serialized_end=2761 + _globals['_DATASOURCE_REQUESTDATAOPTIONS']._serialized_start=2764 + _globals['_DATASOURCE_REQUESTDATAOPTIONS']._serialized_end=3011 + _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._serialized_start=2921 + _globals['_DATASOURCE_REQUESTDATAOPTIONS_DEPRECATEDSCHEMAENTRY']._serialized_end=3005 + _globals['_DATASOURCE_PUSHOPTIONS']._serialized_start=3013 + _globals['_DATASOURCE_PUSHOPTIONS']._serialized_end=3032 + _globals['_DATASOURCE_SOURCETYPE']._serialized_start=3035 + _globals['_DATASOURCE_SOURCETYPE']._serialized_end=3283 + _globals['_DATASOURCELIST']._serialized_start=3302 + _globals['_DATASOURCELIST']._serialized_end=3363 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi b/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi index 7876e1adc98..36cd327a298 100644 --- a/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi @@ -39,7 +39,7 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class DataSource(google.protobuf.message.Message): """Defines a Data Source that can be used source Feature data - Next available id: 28 + Next available id: 29 """ DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -469,6 +469,7 @@ class DataSource(google.protobuf.message.Message): TIMESTAMP_FIELD_FIELD_NUMBER: builtins.int DATE_PARTITION_COLUMN_FIELD_NUMBER: builtins.int CREATED_TIMESTAMP_COLUMN_FIELD_NUMBER: builtins.int + TIMESTAMP_FIELD_TYPE_FIELD_NUMBER: builtins.int DATA_SOURCE_CLASS_TYPE_FIELD_NUMBER: builtins.int BATCH_SOURCE_FIELD_NUMBER: builtins.int META_FIELD_NUMBER: builtins.int @@ -506,6 +507,10 @@ class DataSource(google.protobuf.message.Message): """ created_timestamp_column: builtins.str """Must specify creation timestamp column name""" + timestamp_field_type: builtins.str + """(Optional) Type of the timestamp_field column ("TIMESTAMP" or "DATE"). + When set to "DATE", SQL generation uses date-only comparisons. + """ data_source_class_type: builtins.str """This is an internal field that is represents the python class for the data source object a proto object represents. This should be set by feast, and not by users. @@ -554,6 +559,7 @@ class DataSource(google.protobuf.message.Message): timestamp_field: builtins.str = ..., date_partition_column: builtins.str = ..., created_timestamp_column: builtins.str = ..., + timestamp_field_type: builtins.str = ..., data_source_class_type: builtins.str = ..., batch_source: global___DataSource | None = ..., meta: global___DataSource.SourceMeta | None = ..., @@ -571,7 +577,7 @@ class DataSource(google.protobuf.message.Message): athena_options: global___DataSource.AthenaOptions | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["athena_options", b"athena_options", "batch_source", b"batch_source", "bigquery_options", b"bigquery_options", "custom_options", b"custom_options", "file_options", b"file_options", "kafka_options", b"kafka_options", "kinesis_options", b"kinesis_options", "meta", b"meta", "options", b"options", "push_options", b"push_options", "redshift_options", b"redshift_options", "request_data_options", b"request_data_options", "snowflake_options", b"snowflake_options", "spark_options", b"spark_options", "trino_options", b"trino_options"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["athena_options", b"athena_options", "batch_source", b"batch_source", "bigquery_options", b"bigquery_options", "created_timestamp_column", b"created_timestamp_column", "custom_options", b"custom_options", "data_source_class_type", b"data_source_class_type", "date_partition_column", b"date_partition_column", "description", b"description", "field_mapping", b"field_mapping", "file_options", b"file_options", "kafka_options", b"kafka_options", "kinesis_options", b"kinesis_options", "meta", b"meta", "name", b"name", "options", b"options", "owner", b"owner", "project", b"project", "push_options", b"push_options", "redshift_options", b"redshift_options", "request_data_options", b"request_data_options", "snowflake_options", b"snowflake_options", "spark_options", b"spark_options", "tags", b"tags", "timestamp_field", b"timestamp_field", "trino_options", b"trino_options", "type", b"type"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["athena_options", b"athena_options", "batch_source", b"batch_source", "bigquery_options", b"bigquery_options", "created_timestamp_column", b"created_timestamp_column", "custom_options", b"custom_options", "data_source_class_type", b"data_source_class_type", "date_partition_column", b"date_partition_column", "description", b"description", "field_mapping", b"field_mapping", "file_options", b"file_options", "kafka_options", b"kafka_options", "kinesis_options", b"kinesis_options", "meta", b"meta", "name", b"name", "options", b"options", "owner", b"owner", "project", b"project", "push_options", b"push_options", "redshift_options", b"redshift_options", "request_data_options", b"request_data_options", "snowflake_options", b"snowflake_options", "spark_options", b"spark_options", "tags", b"tags", "timestamp_field", b"timestamp_field", "timestamp_field_type", b"timestamp_field_type", "trino_options", b"trino_options", "type", b"type"]) -> None: ... def WhichOneof(self, oneof_group: typing_extensions.Literal["options", b"options"]) -> typing_extensions.Literal["file_options", "bigquery_options", "kafka_options", "kinesis_options", "redshift_options", "request_data_options", "custom_options", "snowflake_options", "push_options", "spark_options", "trino_options", "athena_options"] | None: ... global___DataSource = DataSource diff --git a/sdk/python/feast/protos/feast/core/FeatureService_pb2.py b/sdk/python/feast/protos/feast/core/FeatureService_pb2.py index 7ef36079691..24940b4ca33 100644 --- a/sdk/python/feast/protos/feast/core/FeatureService_pb2.py +++ b/sdk/python/feast/protos/feast/core/FeatureService_pb2.py @@ -16,7 +16,7 @@ from feast.protos.feast.core import FeatureViewProjection_pb2 as feast_dot_core_dot_FeatureViewProjection__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x66\x65\x61st/core/FeatureService.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\x1a&feast/core/FeatureViewProjection.proto\"l\n\x0e\x46\x65\x61tureService\x12,\n\x04spec\x18\x01 \x01(\x0b\x32\x1e.feast.core.FeatureServiceSpec\x12,\n\x04meta\x18\x02 \x01(\x0b\x32\x1e.feast.core.FeatureServiceMeta\"\xa4\x02\n\x12\x46\x65\x61tureServiceSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x33\n\x08\x66\x65\x61tures\x18\x03 \x03(\x0b\x32!.feast.core.FeatureViewProjection\x12\x36\n\x04tags\x18\x04 \x03(\x0b\x32(.feast.core.FeatureServiceSpec.TagsEntry\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12\r\n\x05owner\x18\x06 \x01(\t\x12\x31\n\x0elogging_config\x18\x07 \x01(\x0b\x32\x19.feast.core.LoggingConfig\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x01\n\x12\x46\x65\x61tureServiceMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd1\x08\n\rLoggingConfig\x12\x13\n\x0bsample_rate\x18\x01 \x01(\x02\x12\x45\n\x10\x66ile_destination\x18\x03 \x01(\x0b\x32).feast.core.LoggingConfig.FileDestinationH\x00\x12M\n\x14\x62igquery_destination\x18\x04 \x01(\x0b\x32-.feast.core.LoggingConfig.BigQueryDestinationH\x00\x12M\n\x14redshift_destination\x18\x05 \x01(\x0b\x32-.feast.core.LoggingConfig.RedshiftDestinationH\x00\x12O\n\x15snowflake_destination\x18\x06 \x01(\x0b\x32..feast.core.LoggingConfig.SnowflakeDestinationH\x00\x12I\n\x12\x63ustom_destination\x18\x07 \x01(\x0b\x32+.feast.core.LoggingConfig.CustomDestinationH\x00\x12I\n\x12\x61thena_destination\x18\x08 \x01(\x0b\x32+.feast.core.LoggingConfig.AthenaDestinationH\x00\x12`\n\x1e\x63ouchbase_columnar_destination\x18\t \x01(\x0b\x32\x36.feast.core.LoggingConfig.CouchbaseColumnarDestinationH\x00\x1aS\n\x0f\x46ileDestination\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x1c\n\x14s3_endpoint_override\x18\x02 \x01(\t\x12\x14\n\x0cpartition_by\x18\x03 \x03(\t\x1a(\n\x13\x42igQueryDestination\x12\x11\n\ttable_ref\x18\x01 \x01(\t\x1a)\n\x13RedshiftDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a\'\n\x11\x41thenaDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a*\n\x14SnowflakeDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a\x99\x01\n\x11\x43ustomDestination\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12G\n\x06\x63onfig\x18\x02 \x03(\x0b\x32\x37.feast.core.LoggingConfig.CustomDestination.ConfigEntry\x1a-\n\x0b\x43onfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aS\n\x1c\x43ouchbaseColumnarDestination\x12\x10\n\x08\x64\x61tabase\x18\x01 \x01(\t\x12\r\n\x05scope\x18\x02 \x01(\t\x12\x12\n\ncollection\x18\x03 \x01(\tB\r\n\x0b\x64\x65stination\"I\n\x12\x46\x65\x61tureServiceList\x12\x33\n\x0f\x66\x65\x61tureservices\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureServiceBX\n\x10\x66\x65\x61st.proto.coreB\x13\x46\x65\x61tureServiceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x66\x65\x61st/core/FeatureService.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\x1a&feast/core/FeatureViewProjection.proto\"l\n\x0e\x46\x65\x61tureService\x12,\n\x04spec\x18\x01 \x01(\x0b\x32\x1e.feast.core.FeatureServiceSpec\x12,\n\x04meta\x18\x02 \x01(\x0b\x32\x1e.feast.core.FeatureServiceMeta\"\xbf\x02\n\x12\x46\x65\x61tureServiceSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x33\n\x08\x66\x65\x61tures\x18\x03 \x03(\x0b\x32!.feast.core.FeatureViewProjection\x12\x36\n\x04tags\x18\x04 \x03(\x0b\x32(.feast.core.FeatureServiceSpec.TagsEntry\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12\r\n\x05owner\x18\x06 \x01(\t\x12\x31\n\x0elogging_config\x18\x07 \x01(\x0b\x32\x19.feast.core.LoggingConfig\x12\x19\n\x11precompute_online\x18\x08 \x01(\x08\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x01\n\x12\x46\x65\x61tureServiceMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd1\x08\n\rLoggingConfig\x12\x13\n\x0bsample_rate\x18\x01 \x01(\x02\x12\x45\n\x10\x66ile_destination\x18\x03 \x01(\x0b\x32).feast.core.LoggingConfig.FileDestinationH\x00\x12M\n\x14\x62igquery_destination\x18\x04 \x01(\x0b\x32-.feast.core.LoggingConfig.BigQueryDestinationH\x00\x12M\n\x14redshift_destination\x18\x05 \x01(\x0b\x32-.feast.core.LoggingConfig.RedshiftDestinationH\x00\x12O\n\x15snowflake_destination\x18\x06 \x01(\x0b\x32..feast.core.LoggingConfig.SnowflakeDestinationH\x00\x12I\n\x12\x63ustom_destination\x18\x07 \x01(\x0b\x32+.feast.core.LoggingConfig.CustomDestinationH\x00\x12I\n\x12\x61thena_destination\x18\x08 \x01(\x0b\x32+.feast.core.LoggingConfig.AthenaDestinationH\x00\x12`\n\x1e\x63ouchbase_columnar_destination\x18\t \x01(\x0b\x32\x36.feast.core.LoggingConfig.CouchbaseColumnarDestinationH\x00\x1aS\n\x0f\x46ileDestination\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x1c\n\x14s3_endpoint_override\x18\x02 \x01(\t\x12\x14\n\x0cpartition_by\x18\x03 \x03(\t\x1a(\n\x13\x42igQueryDestination\x12\x11\n\ttable_ref\x18\x01 \x01(\t\x1a)\n\x13RedshiftDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a\'\n\x11\x41thenaDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a*\n\x14SnowflakeDestination\x12\x12\n\ntable_name\x18\x01 \x01(\t\x1a\x99\x01\n\x11\x43ustomDestination\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12G\n\x06\x63onfig\x18\x02 \x03(\x0b\x32\x37.feast.core.LoggingConfig.CustomDestination.ConfigEntry\x1a-\n\x0b\x43onfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aS\n\x1c\x43ouchbaseColumnarDestination\x12\x10\n\x08\x64\x61tabase\x18\x01 \x01(\t\x12\r\n\x05scope\x18\x02 \x01(\t\x12\x12\n\ncollection\x18\x03 \x01(\tB\r\n\x0b\x64\x65stination\"I\n\x12\x46\x65\x61tureServiceList\x12\x33\n\x0f\x66\x65\x61tureservices\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureServiceBX\n\x10\x66\x65\x61st.proto.coreB\x13\x46\x65\x61tureServiceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,29 +31,29 @@ _globals['_FEATURESERVICE']._serialized_start=120 _globals['_FEATURESERVICE']._serialized_end=228 _globals['_FEATURESERVICESPEC']._serialized_start=231 - _globals['_FEATURESERVICESPEC']._serialized_end=523 - _globals['_FEATURESERVICESPEC_TAGSENTRY']._serialized_start=480 - _globals['_FEATURESERVICESPEC_TAGSENTRY']._serialized_end=523 - _globals['_FEATURESERVICEMETA']._serialized_start=526 - _globals['_FEATURESERVICEMETA']._serialized_end=661 - _globals['_LOGGINGCONFIG']._serialized_start=664 - _globals['_LOGGINGCONFIG']._serialized_end=1769 - _globals['_LOGGINGCONFIG_FILEDESTINATION']._serialized_start=1260 - _globals['_LOGGINGCONFIG_FILEDESTINATION']._serialized_end=1343 - _globals['_LOGGINGCONFIG_BIGQUERYDESTINATION']._serialized_start=1345 - _globals['_LOGGINGCONFIG_BIGQUERYDESTINATION']._serialized_end=1385 - _globals['_LOGGINGCONFIG_REDSHIFTDESTINATION']._serialized_start=1387 - _globals['_LOGGINGCONFIG_REDSHIFTDESTINATION']._serialized_end=1428 - _globals['_LOGGINGCONFIG_ATHENADESTINATION']._serialized_start=1430 - _globals['_LOGGINGCONFIG_ATHENADESTINATION']._serialized_end=1469 - _globals['_LOGGINGCONFIG_SNOWFLAKEDESTINATION']._serialized_start=1471 - _globals['_LOGGINGCONFIG_SNOWFLAKEDESTINATION']._serialized_end=1513 - _globals['_LOGGINGCONFIG_CUSTOMDESTINATION']._serialized_start=1516 - _globals['_LOGGINGCONFIG_CUSTOMDESTINATION']._serialized_end=1669 - _globals['_LOGGINGCONFIG_CUSTOMDESTINATION_CONFIGENTRY']._serialized_start=1624 - _globals['_LOGGINGCONFIG_CUSTOMDESTINATION_CONFIGENTRY']._serialized_end=1669 - _globals['_LOGGINGCONFIG_COUCHBASECOLUMNARDESTINATION']._serialized_start=1671 - _globals['_LOGGINGCONFIG_COUCHBASECOLUMNARDESTINATION']._serialized_end=1754 - _globals['_FEATURESERVICELIST']._serialized_start=1771 - _globals['_FEATURESERVICELIST']._serialized_end=1844 + _globals['_FEATURESERVICESPEC']._serialized_end=550 + _globals['_FEATURESERVICESPEC_TAGSENTRY']._serialized_start=507 + _globals['_FEATURESERVICESPEC_TAGSENTRY']._serialized_end=550 + _globals['_FEATURESERVICEMETA']._serialized_start=553 + _globals['_FEATURESERVICEMETA']._serialized_end=688 + _globals['_LOGGINGCONFIG']._serialized_start=691 + _globals['_LOGGINGCONFIG']._serialized_end=1796 + _globals['_LOGGINGCONFIG_FILEDESTINATION']._serialized_start=1287 + _globals['_LOGGINGCONFIG_FILEDESTINATION']._serialized_end=1370 + _globals['_LOGGINGCONFIG_BIGQUERYDESTINATION']._serialized_start=1372 + _globals['_LOGGINGCONFIG_BIGQUERYDESTINATION']._serialized_end=1412 + _globals['_LOGGINGCONFIG_REDSHIFTDESTINATION']._serialized_start=1414 + _globals['_LOGGINGCONFIG_REDSHIFTDESTINATION']._serialized_end=1455 + _globals['_LOGGINGCONFIG_ATHENADESTINATION']._serialized_start=1457 + _globals['_LOGGINGCONFIG_ATHENADESTINATION']._serialized_end=1496 + _globals['_LOGGINGCONFIG_SNOWFLAKEDESTINATION']._serialized_start=1498 + _globals['_LOGGINGCONFIG_SNOWFLAKEDESTINATION']._serialized_end=1540 + _globals['_LOGGINGCONFIG_CUSTOMDESTINATION']._serialized_start=1543 + _globals['_LOGGINGCONFIG_CUSTOMDESTINATION']._serialized_end=1696 + _globals['_LOGGINGCONFIG_CUSTOMDESTINATION_CONFIGENTRY']._serialized_start=1651 + _globals['_LOGGINGCONFIG_CUSTOMDESTINATION_CONFIGENTRY']._serialized_end=1696 + _globals['_LOGGINGCONFIG_COUCHBASECOLUMNARDESTINATION']._serialized_start=1698 + _globals['_LOGGINGCONFIG_COUCHBASECOLUMNARDESTINATION']._serialized_end=1781 + _globals['_FEATURESERVICELIST']._serialized_start=1798 + _globals['_FEATURESERVICELIST']._serialized_end=1871 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/FeatureService_pb2.pyi b/sdk/python/feast/protos/feast/core/FeatureService_pb2.pyi index 6d5879e52cb..a3e6158ad91 100644 --- a/sdk/python/feast/protos/feast/core/FeatureService_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/FeatureService_pb2.pyi @@ -65,6 +65,7 @@ class FeatureServiceSpec(google.protobuf.message.Message): DESCRIPTION_FIELD_NUMBER: builtins.int OWNER_FIELD_NUMBER: builtins.int LOGGING_CONFIG_FIELD_NUMBER: builtins.int + PRECOMPUTE_ONLINE_FIELD_NUMBER: builtins.int name: builtins.str """Name of the Feature Service. Must be unique. Not updated.""" project: builtins.str @@ -84,6 +85,10 @@ class FeatureServiceSpec(google.protobuf.message.Message): @property def logging_config(self) -> global___LoggingConfig: """(optional) if provided logging will be enabled for this feature service.""" + precompute_online: builtins.bool + """When true, a pre-computed feature vector is maintained per entity for this + service, enabling single-read online retrieval instead of per-feature-view reads. + """ def __init__( self, *, @@ -94,9 +99,10 @@ class FeatureServiceSpec(google.protobuf.message.Message): description: builtins.str = ..., owner: builtins.str = ..., logging_config: global___LoggingConfig | None = ..., + precompute_online: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["logging_config", b"logging_config"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "features", b"features", "logging_config", b"logging_config", "name", b"name", "owner", b"owner", "project", b"project", "tags", b"tags"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "features", b"features", "logging_config", b"logging_config", "name", b"name", "owner", b"owner", "precompute_online", b"precompute_online", "project", b"project", "tags", b"tags"]) -> None: ... global___FeatureServiceSpec = FeatureServiceSpec diff --git a/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.py b/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.py index b47d4fe392f..67839983d81 100644 --- a/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.py +++ b/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.py @@ -16,7 +16,7 @@ from feast.protos.feast.core import DataSource_pb2 as feast_dot_core_dot_DataSource__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&feast/core/FeatureViewProjection.proto\x12\nfeast.core\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\"\xba\x03\n\x15\x46\x65\x61tureViewProjection\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x1f\n\x17\x66\x65\x61ture_view_name_alias\x18\x03 \x01(\t\x12\x32\n\x0f\x66\x65\x61ture_columns\x18\x02 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12G\n\x0cjoin_key_map\x18\x04 \x03(\x0b\x32\x31.feast.core.FeatureViewProjection.JoinKeyMapEntry\x12\x17\n\x0ftimestamp_field\x18\x05 \x01(\t\x12\x1d\n\x15\x64\x61te_partition_column\x18\x06 \x01(\t\x12 \n\x18\x63reated_timestamp_column\x18\x07 \x01(\t\x12,\n\x0c\x62\x61tch_source\x18\x08 \x01(\x0b\x32\x16.feast.core.DataSource\x12-\n\rstream_source\x18\t \x01(\x0b\x32\x16.feast.core.DataSource\x1a\x31\n\x0fJoinKeyMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42Z\n\x10\x66\x65\x61st.proto.coreB\x15\x46\x65\x61tureReferenceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&feast/core/FeatureViewProjection.proto\x12\nfeast.core\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\"\xf7\x03\n\x15\x46\x65\x61tureViewProjection\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x1f\n\x17\x66\x65\x61ture_view_name_alias\x18\x03 \x01(\t\x12\x32\n\x0f\x66\x65\x61ture_columns\x18\x02 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12G\n\x0cjoin_key_map\x18\x04 \x03(\x0b\x32\x31.feast.core.FeatureViewProjection.JoinKeyMapEntry\x12\x17\n\x0ftimestamp_field\x18\x05 \x01(\t\x12\x1d\n\x15\x64\x61te_partition_column\x18\x06 \x01(\t\x12 \n\x18\x63reated_timestamp_column\x18\x07 \x01(\t\x12,\n\x0c\x62\x61tch_source\x18\x08 \x01(\x0b\x32\x16.feast.core.DataSource\x12-\n\rstream_source\x18\t \x01(\x0b\x32\x16.feast.core.DataSource\x12\x18\n\x0bversion_tag\x18\n \x01(\x05H\x00\x88\x01\x01\x12\x11\n\tview_type\x18\x0b \x01(\t\x1a\x31\n\x0fJoinKeyMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0e\n\x0c_version_tagBZ\n\x10\x66\x65\x61st.proto.coreB\x15\x46\x65\x61tureReferenceProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,7 +27,7 @@ _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._options = None _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._serialized_options = b'8\001' _globals['_FEATUREVIEWPROJECTION']._serialized_start=110 - _globals['_FEATUREVIEWPROJECTION']._serialized_end=552 - _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._serialized_start=503 - _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._serialized_end=552 + _globals['_FEATUREVIEWPROJECTION']._serialized_end=613 + _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._serialized_start=548 + _globals['_FEATUREVIEWPROJECTION_JOINKEYMAPENTRY']._serialized_end=597 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.pyi b/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.pyi index 6b44ad4a931..4566cfd5aec 100644 --- a/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/FeatureViewProjection_pb2.pyi @@ -49,6 +49,8 @@ class FeatureViewProjection(google.protobuf.message.Message): CREATED_TIMESTAMP_COLUMN_FIELD_NUMBER: builtins.int BATCH_SOURCE_FIELD_NUMBER: builtins.int STREAM_SOURCE_FIELD_NUMBER: builtins.int + VERSION_TAG_FIELD_NUMBER: builtins.int + VIEW_TYPE_FIELD_NUMBER: builtins.int feature_view_name: builtins.str """The feature view name""" feature_view_name_alias: builtins.str @@ -68,6 +70,12 @@ class FeatureViewProjection(google.protobuf.message.Message): @property def stream_source(self) -> feast.core.DataSource_pb2.DataSource: """Streaming DataSource from where this view can consume "online" feature data.""" + version_tag: builtins.int + """Optional version tag for version-qualified feature references (e.g., @v2).""" + view_type: builtins.str + """Distinguishes the source view type (e.g., "featureView", "labelView"). + Empty string or unset means "featureView" for backward compatibility. + """ def __init__( self, *, @@ -80,8 +88,11 @@ class FeatureViewProjection(google.protobuf.message.Message): created_timestamp_column: builtins.str = ..., batch_source: feast.core.DataSource_pb2.DataSource | None = ..., stream_source: feast.core.DataSource_pb2.DataSource | None = ..., + version_tag: builtins.int | None = ..., + view_type: builtins.str = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "stream_source", b"stream_source"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "created_timestamp_column", b"created_timestamp_column", "date_partition_column", b"date_partition_column", "feature_columns", b"feature_columns", "feature_view_name", b"feature_view_name", "feature_view_name_alias", b"feature_view_name_alias", "join_key_map", b"join_key_map", "stream_source", b"stream_source", "timestamp_field", b"timestamp_field"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_version_tag", b"_version_tag", "batch_source", b"batch_source", "stream_source", b"stream_source", "version_tag", b"version_tag"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_version_tag", b"_version_tag", "batch_source", b"batch_source", "created_timestamp_column", b"created_timestamp_column", "date_partition_column", b"date_partition_column", "feature_columns", b"feature_columns", "feature_view_name", b"feature_view_name", "feature_view_name_alias", b"feature_view_name_alias", "join_key_map", b"join_key_map", "stream_source", b"stream_source", "timestamp_field", b"timestamp_field", "version_tag", b"version_tag", "view_type", b"view_type"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["_version_tag", b"_version_tag"]) -> typing_extensions.Literal["version_tag"] | None: ... global___FeatureViewProjection = FeatureViewProjection diff --git a/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.py b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.py new file mode 100644 index 00000000000..88bc21c2a8f --- /dev/null +++ b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: feast/core/FeatureViewVersion.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#feast/core/FeatureViewVersion.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf8\x01\n\x18\x46\x65\x61tureViewVersionRecord\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x12\n\nproject_id\x18\x02 \x01(\t\x12\x16\n\x0eversion_number\x18\x03 \x01(\x05\x12\x19\n\x11\x66\x65\x61ture_view_type\x18\x04 \x01(\t\x12\x1a\n\x12\x66\x65\x61ture_view_proto\x18\x05 \x01(\x0c\x12\x35\n\x11\x63reated_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nversion_id\x18\x08 \x01(\t\"R\n\x19\x46\x65\x61tureViewVersionHistory\x12\x35\n\x07records\x18\x01 \x03(\x0b\x32$.feast.core.FeatureViewVersionRecordB\\\n\x10\x66\x65\x61st.proto.coreB\x17\x46\x65\x61tureViewVersionProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'feast.core.FeatureViewVersion_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\027FeatureViewVersionProtoZ/github.com/feast-dev/feast/go/protos/feast/core' + _globals['_FEATUREVIEWVERSIONRECORD']._serialized_start=85 + _globals['_FEATUREVIEWVERSIONRECORD']._serialized_end=333 + _globals['_FEATUREVIEWVERSIONHISTORY']._serialized_start=335 + _globals['_FEATUREVIEWVERSIONHISTORY']._serialized_end=417 +# @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.pyi b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.pyi new file mode 100644 index 00000000000..a6dba9d53d4 --- /dev/null +++ b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2.pyi @@ -0,0 +1,87 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file + +Copyright 2024 The Feast Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class FeatureViewVersionRecord(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FEATURE_VIEW_NAME_FIELD_NUMBER: builtins.int + PROJECT_ID_FIELD_NUMBER: builtins.int + VERSION_NUMBER_FIELD_NUMBER: builtins.int + FEATURE_VIEW_TYPE_FIELD_NUMBER: builtins.int + FEATURE_VIEW_PROTO_FIELD_NUMBER: builtins.int + CREATED_TIMESTAMP_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + VERSION_ID_FIELD_NUMBER: builtins.int + feature_view_name: builtins.str + project_id: builtins.str + version_number: builtins.int + feature_view_type: builtins.str + """"feature_view" | "stream_feature_view" | "on_demand_feature_view" """ + feature_view_proto: builtins.bytes + """serialized FV proto snapshot""" + @property + def created_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + description: builtins.str + version_id: builtins.str + """auto-generated UUID for unique identification""" + def __init__( + self, + *, + feature_view_name: builtins.str = ..., + project_id: builtins.str = ..., + version_number: builtins.int = ..., + feature_view_type: builtins.str = ..., + feature_view_proto: builtins.bytes = ..., + created_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + description: builtins.str = ..., + version_id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "description", b"description", "feature_view_name", b"feature_view_name", "feature_view_proto", b"feature_view_proto", "feature_view_type", b"feature_view_type", "project_id", b"project_id", "version_id", b"version_id", "version_number", b"version_number"]) -> None: ... + +global___FeatureViewVersionRecord = FeatureViewVersionRecord + +class FeatureViewVersionHistory(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RECORDS_FIELD_NUMBER: builtins.int + @property + def records(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FeatureViewVersionRecord]: ... + def __init__( + self, + *, + records: collections.abc.Iterable[global___FeatureViewVersionRecord] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["records", b"records"]) -> None: ... + +global___FeatureViewVersionHistory = FeatureViewVersionHistory diff --git a/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2_grpc.py b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2_grpc.py new file mode 100644 index 00000000000..2daafffebfc --- /dev/null +++ b/sdk/python/feast/protos/feast/core/FeatureViewVersion_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/sdk/python/feast/protos/feast/core/FeatureView_pb2.py b/sdk/python/feast/protos/feast/core/FeatureView_pb2.py index 0221a96031b..71766558c82 100644 --- a/sdk/python/feast/protos/feast/core/FeatureView_pb2.py +++ b/sdk/python/feast/protos/feast/core/FeatureView_pb2.py @@ -19,7 +19,7 @@ from feast.protos.feast.core import Transformation_pb2 as feast_dot_core_dot_Transformation__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66\x65\x61st/core/FeatureView.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\"c\n\x0b\x46\x65\x61tureView\x12)\n\x04spec\x18\x01 \x01(\x0b\x32\x1b.feast.core.FeatureViewSpec\x12)\n\x04meta\x18\x02 \x01(\x0b\x32\x1b.feast.core.FeatureViewMeta\"\xef\x04\n\x0f\x46\x65\x61tureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x10\n\x08\x65ntities\x18\x03 \x03(\t\x12+\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x33\n\x04tags\x18\x05 \x03(\x0b\x32%.feast.core.FeatureViewSpec.TagsEntry\x12&\n\x03ttl\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\x0c\x62\x61tch_source\x18\x07 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0e\n\x06online\x18\x08 \x01(\x08\x12-\n\rstream_source\x18\t \x01(\x0b\x32\x16.feast.core.DataSource\x12\x13\n\x0b\x64\x65scription\x18\n \x01(\t\x12\r\n\x05owner\x18\x0b \x01(\t\x12\x31\n\x0e\x65ntity_columns\x18\x0c \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x0f\n\x07offline\x18\r \x01(\x08\x12\x31\n\x0csource_views\x18\x0e \x03(\x0b\x32\x1b.feast.core.FeatureViewSpec\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\x0f \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x0c\n\x04mode\x18\x10 \x01(\t\x12\x19\n\x11\x65nable_validation\x18\x11 \x01(\x08\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xcc\x01\n\x0f\x46\x65\x61tureViewMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x46\n\x19materialization_intervals\x18\x03 \x03(\x0b\x32#.feast.core.MaterializationInterval\"w\n\x17MaterializationInterval\x12.\n\nstart_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"@\n\x0f\x46\x65\x61tureViewList\x12-\n\x0c\x66\x65\x61tureviews\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureViewBU\n\x10\x66\x65\x61st.proto.coreB\x10\x46\x65\x61tureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66\x65\x61st/core/FeatureView.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\"c\n\x0b\x46\x65\x61tureView\x12)\n\x04spec\x18\x01 \x01(\x0b\x32\x1b.feast.core.FeatureViewSpec\x12)\n\x04meta\x18\x02 \x01(\x0b\x32\x1b.feast.core.FeatureViewMeta\"\x9f\x05\n\x0f\x46\x65\x61tureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x10\n\x08\x65ntities\x18\x03 \x03(\t\x12+\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x33\n\x04tags\x18\x05 \x03(\x0b\x32%.feast.core.FeatureViewSpec.TagsEntry\x12&\n\x03ttl\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\x0c\x62\x61tch_source\x18\x07 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0e\n\x06online\x18\x08 \x01(\x08\x12-\n\rstream_source\x18\t \x01(\x0b\x32\x16.feast.core.DataSource\x12\x13\n\x0b\x64\x65scription\x18\n \x01(\t\x12\r\n\x05owner\x18\x0b \x01(\t\x12\x31\n\x0e\x65ntity_columns\x18\x0c \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x0f\n\x07offline\x18\r \x01(\x08\x12\x31\n\x0csource_views\x18\x0e \x03(\x0b\x32\x1b.feast.core.FeatureViewSpec\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\x0f \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x0c\n\x04mode\x18\x10 \x01(\t\x12\x19\n\x11\x65nable_validation\x18\x11 \x01(\x08\x12\x0f\n\x07version\x18\x12 \x01(\t\x12\x0b\n\x03org\x18\x13 \x01(\t\x12\x10\n\x08\x64isabled\x18\x14 \x01(\x08\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xad\x02\n\x0f\x46\x65\x61tureViewMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x46\n\x19materialization_intervals\x18\x03 \x03(\x0b\x32#.feast.core.MaterializationInterval\x12\x1e\n\x16\x63urrent_version_number\x18\x04 \x01(\x05\x12\x12\n\nversion_id\x18\x05 \x01(\t\x12+\n\x05state\x18\x06 \x01(\x0e\x32\x1c.feast.core.FeatureViewState\"w\n\x17MaterializationInterval\x12.\n\nstart_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"@\n\x0f\x46\x65\x61tureViewList\x12-\n\x0c\x66\x65\x61tureviews\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureView*n\n\x10\x46\x65\x61tureViewState\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x0b\n\x07\x43REATED\x10\x01\x12\r\n\tGENERATED\x10\x02\x12\x11\n\rMATERIALIZING\x10\x03\x12\x14\n\x10\x41VAILABLE_ONLINE\x10\x04\x42U\n\x10\x66\x65\x61st.proto.coreB\x10\x46\x65\x61tureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -29,16 +29,18 @@ _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\020FeatureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/core' _globals['_FEATUREVIEWSPEC_TAGSENTRY']._options = None _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_options = b'8\001' + _globals['_FEATUREVIEWSTATE']._serialized_start=1463 + _globals['_FEATUREVIEWSTATE']._serialized_end=1573 _globals['_FEATUREVIEW']._serialized_start=197 _globals['_FEATUREVIEW']._serialized_end=296 _globals['_FEATUREVIEWSPEC']._serialized_start=299 - _globals['_FEATUREVIEWSPEC']._serialized_end=922 - _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_start=879 - _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_end=922 - _globals['_FEATUREVIEWMETA']._serialized_start=925 - _globals['_FEATUREVIEWMETA']._serialized_end=1129 - _globals['_MATERIALIZATIONINTERVAL']._serialized_start=1131 - _globals['_MATERIALIZATIONINTERVAL']._serialized_end=1250 - _globals['_FEATUREVIEWLIST']._serialized_start=1252 - _globals['_FEATUREVIEWLIST']._serialized_end=1316 + _globals['_FEATUREVIEWSPEC']._serialized_end=970 + _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_start=927 + _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_end=970 + _globals['_FEATUREVIEWMETA']._serialized_start=973 + _globals['_FEATUREVIEWMETA']._serialized_end=1274 + _globals['_MATERIALIZATIONINTERVAL']._serialized_start=1276 + _globals['_MATERIALIZATIONINTERVAL']._serialized_end=1395 + _globals['_FEATUREVIEWLIST']._serialized_start=1397 + _globals['_FEATUREVIEWLIST']._serialized_end=1461 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi b/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi index c5a54394320..e73bc66a555 100644 --- a/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi @@ -24,17 +24,59 @@ import feast.core.Transformation_pb2 import google.protobuf.descriptor import google.protobuf.duration_pb2 import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import google.protobuf.timestamp_pb2 import sys +import typing -if sys.version_info >= (3, 8): +if sys.version_info >= (3, 10): import typing as typing_extensions else: import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor +class _FeatureViewState: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _FeatureViewStateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FeatureViewState.ValueType], builtins.type): # noqa: F821 + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STATE_UNSPECIFIED: _FeatureViewState.ValueType # 0 + """Default value for backward compatibility. Treated as AVAILABLE_ONLINE + for existing feature views that predate the state machine. + """ + CREATED: _FeatureViewState.ValueType # 1 + """Feature view has been registered via feast apply but no data is available.""" + GENERATED: _FeatureViewState.ValueType # 2 + """Feature engineering / offline data generation is complete. + The feature view is ready to be materialized. + """ + MATERIALIZING: _FeatureViewState.ValueType # 3 + """Materialization is currently in progress.""" + AVAILABLE_ONLINE: _FeatureViewState.ValueType # 4 + """Materialization completed. Features are available in the online store.""" + +class FeatureViewState(_FeatureViewState, metaclass=_FeatureViewStateEnumTypeWrapper): + """Lifecycle state of a feature view.""" + +STATE_UNSPECIFIED: FeatureViewState.ValueType # 0 +"""Default value for backward compatibility. Treated as AVAILABLE_ONLINE +for existing feature views that predate the state machine. +""" +CREATED: FeatureViewState.ValueType # 1 +"""Feature view has been registered via feast apply but no data is available.""" +GENERATED: FeatureViewState.ValueType # 2 +"""Feature engineering / offline data generation is complete. +The feature view is ready to be materialized. +""" +MATERIALIZING: FeatureViewState.ValueType # 3 +"""Materialization is currently in progress.""" +AVAILABLE_ONLINE: FeatureViewState.ValueType # 4 +"""Materialization completed. Features are available in the online store.""" +global___FeatureViewState = FeatureViewState + class FeatureView(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -58,7 +100,7 @@ class FeatureView(google.protobuf.message.Message): global___FeatureView = FeatureView class FeatureViewSpec(google.protobuf.message.Message): - """Next available id: 18 + """Next available id: 20 TODO(adchia): refactor common fields from this and ODFV into separate metadata proto """ @@ -96,6 +138,9 @@ class FeatureViewSpec(google.protobuf.message.Message): FEATURE_TRANSFORMATION_FIELD_NUMBER: builtins.int MODE_FIELD_NUMBER: builtins.int ENABLE_VALIDATION_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int + DISABLED_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -118,14 +163,18 @@ class FeatureViewSpec(google.protobuf.message.Message): """ @property def batch_source(self) -> feast.core.DataSource_pb2.DataSource: - """Batch/Offline DataSource where this view can retrieve offline feature data.""" + """Batch/Offline DataSource where this view can retrieve offline feature data. + Optional: if not set, the feature view has no associated batch data source (e.g. purely derived views). + """ online: builtins.bool """Whether these features should be served online or not This is also used to determine whether the features should be written to the online store """ @property def stream_source(self) -> feast.core.DataSource_pb2.DataSource: - """Streaming DataSource from where this view can consume "online" feature data.""" + """Streaming DataSource from where this view can consume "online" feature data. + Optional: only required for streaming feature views. + """ description: builtins.str """Description of the feature view.""" owner: builtins.str @@ -144,6 +193,15 @@ class FeatureViewSpec(google.protobuf.message.Message): """The transformation mode (e.g., "python", "pandas", "spark", "sql", "ray")""" enable_validation: builtins.bool """Whether schema validation is enabled during materialization""" + version: builtins.str + """User-specified version pin (e.g. "latest", "v2", "version2")""" + org: builtins.str + """Organizational unit that owns this feature view (e.g. "ads", "search").""" + disabled: builtins.bool + """Whether this feature view is disabled for serving and materialization. + When true, the feature view will not serve online features or be materialized. + Defaults to false (enabled) for backward compatibility. + """ def __init__( self, *, @@ -164,9 +222,12 @@ class FeatureViewSpec(google.protobuf.message.Message): feature_transformation: feast.core.Transformation_pb2.FeatureTransformationV2 | None = ..., mode: builtins.str = ..., enable_validation: builtins.bool = ..., + version: builtins.str = ..., + org: builtins.str = ..., + disabled: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "feature_transformation", b"feature_transformation", "stream_source", b"stream_source", "ttl", b"ttl"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "description", b"description", "enable_validation", b"enable_validation", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "offline", b"offline", "online", b"online", "owner", b"owner", "project", b"project", "source_views", b"source_views", "stream_source", b"stream_source", "tags", b"tags", "ttl", b"ttl"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "description", b"description", "disabled", b"disabled", "enable_validation", b"enable_validation", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "offline", b"offline", "online", b"online", "org", b"org", "owner", b"owner", "project", b"project", "source_views", b"source_views", "stream_source", b"stream_source", "tags", b"tags", "ttl", b"ttl", "version", b"version"]) -> None: ... global___FeatureViewSpec = FeatureViewSpec @@ -176,6 +237,9 @@ class FeatureViewMeta(google.protobuf.message.Message): CREATED_TIMESTAMP_FIELD_NUMBER: builtins.int LAST_UPDATED_TIMESTAMP_FIELD_NUMBER: builtins.int MATERIALIZATION_INTERVALS_FIELD_NUMBER: builtins.int + CURRENT_VERSION_NUMBER_FIELD_NUMBER: builtins.int + VERSION_ID_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int @property def created_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: """Time where this Feature View is created""" @@ -185,15 +249,24 @@ class FeatureViewMeta(google.protobuf.message.Message): @property def materialization_intervals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___MaterializationInterval]: """List of pairs (start_time, end_time) for which this feature view has been materialized.""" + current_version_number: builtins.int + """The current version number of this feature view in the version history.""" + version_id: builtins.str + """Auto-generated UUID identifying this specific version.""" + state: global___FeatureViewState.ValueType + """Lifecycle state of this feature view.""" def __init__( self, *, created_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., last_updated_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., materialization_intervals: collections.abc.Iterable[global___MaterializationInterval] | None = ..., + current_version_number: builtins.int = ..., + version_id: builtins.str = ..., + state: global___FeatureViewState.ValueType = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp", "materialization_intervals", b"materialization_intervals"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "current_version_number", b"current_version_number", "last_updated_timestamp", b"last_updated_timestamp", "materialization_intervals", b"materialization_intervals", "state", b"state", "version_id", b"version_id"]) -> None: ... global___FeatureViewMeta = FeatureViewMeta diff --git a/sdk/python/feast/protos/feast/core/LabelView_pb2.py b/sdk/python/feast/protos/feast/core/LabelView_pb2.py new file mode 100644 index 00000000000..d8fb720a1e2 --- /dev/null +++ b/sdk/python/feast/protos/feast/core/LabelView_pb2.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: feast/core/LabelView.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from feast.protos.feast.core import DataSource_pb2 as feast_dot_core_dot_DataSource__pb2 +from feast.protos.feast.core import Feature_pb2 as feast_dot_core_dot_Feature__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1a\x66\x65\x61st/core/LabelView.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\"]\n\tLabelView\x12\'\n\x04spec\x18\x01 \x01(\x0b\x32\x19.feast.core.LabelViewSpec\x12\'\n\x04meta\x18\x02 \x01(\x0b\x32\x19.feast.core.LabelViewMeta\"\x96\x04\n\rLabelViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x10\n\x08\x65ntities\x18\x03 \x03(\t\x12+\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x31\n\x04tags\x18\x05 \x03(\x0b\x32#.feast.core.LabelViewSpec.TagsEntry\x12&\n\x03ttl\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12&\n\x06source\x18\x07 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0e\n\x06online\x18\x08 \x01(\x08\x12\x13\n\x0b\x64\x65scription\x18\t \x01(\t\x12\r\n\x05owner\x18\n \x01(\t\x12\x31\n\x0e\x65ntity_columns\x18\x0b \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x15\n\rlabeler_field\x18\x0c \x01(\t\x12=\n\x0f\x63onflict_policy\x18\r \x01(\x0e\x32$.feast.core.ConflictResolutionPolicy\x12\x1a\n\x0eretain_history\x18\x0e \x01(\x08\x42\x02\x18\x01\x12\x1e\n\x16reference_feature_view\x18\x0f \x01(\t\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x82\x01\n\rLabelViewMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp*X\n\x18\x43onflictResolutionPolicy\x12\x13\n\x0fLAST_WRITE_WINS\x10\x00\x12\x14\n\x10LABELER_PRIORITY\x10\x01\x12\x11\n\rMAJORITY_VOTE\x10\x02\x42S\n\x10\x66\x65\x61st.proto.coreB\x0eLabelViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'feast.core.LabelView_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\016LabelViewProtoZ/github.com/feast-dev/feast/go/protos/feast/core' + _globals['_LABELVIEWSPEC_TAGSENTRY']._options = None + _globals['_LABELVIEWSPEC_TAGSENTRY']._serialized_options = b'8\001' + _globals['_LABELVIEWSPEC'].fields_by_name['retain_history']._options = None + _globals['_LABELVIEWSPEC'].fields_by_name['retain_history']._serialized_options = b'\030\001' + _globals['_CONFLICTRESOLUTIONPOLICY']._serialized_start=927 + _globals['_CONFLICTRESOLUTIONPOLICY']._serialized_end=1015 + _globals['_LABELVIEW']._serialized_start=162 + _globals['_LABELVIEW']._serialized_end=255 + _globals['_LABELVIEWSPEC']._serialized_start=258 + _globals['_LABELVIEWSPEC']._serialized_end=792 + _globals['_LABELVIEWSPEC_TAGSENTRY']._serialized_start=749 + _globals['_LABELVIEWSPEC_TAGSENTRY']._serialized_end=792 + _globals['_LABELVIEWMETA']._serialized_start=795 + _globals['_LABELVIEWMETA']._serialized_end=925 +# @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/LabelView_pb2.pyi b/sdk/python/feast/protos/feast/core/LabelView_pb2.pyi new file mode 100644 index 00000000000..e8f70a82000 --- /dev/null +++ b/sdk/python/feast/protos/feast/core/LabelView_pb2.pyi @@ -0,0 +1,195 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file + +Copyright 2026 The Feast Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import feast.core.DataSource_pb2 +import feast.core.Feature_pb2 +import google.protobuf.descriptor +import google.protobuf.duration_pb2 +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _ConflictResolutionPolicy: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _ConflictResolutionPolicyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ConflictResolutionPolicy.ValueType], builtins.type): # noqa: F821 + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LAST_WRITE_WINS: _ConflictResolutionPolicy.ValueType # 0 + LABELER_PRIORITY: _ConflictResolutionPolicy.ValueType # 1 + MAJORITY_VOTE: _ConflictResolutionPolicy.ValueType # 2 + +class ConflictResolutionPolicy(_ConflictResolutionPolicy, metaclass=_ConflictResolutionPolicyEnumTypeWrapper): ... + +LAST_WRITE_WINS: ConflictResolutionPolicy.ValueType # 0 +LABELER_PRIORITY: ConflictResolutionPolicy.ValueType # 1 +MAJORITY_VOTE: ConflictResolutionPolicy.ValueType # 2 +global___ConflictResolutionPolicy = ConflictResolutionPolicy + +class LabelView(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SPEC_FIELD_NUMBER: builtins.int + META_FIELD_NUMBER: builtins.int + @property + def spec(self) -> global___LabelViewSpec: ... + @property + def meta(self) -> global___LabelViewMeta: ... + def __init__( + self, + *, + spec: global___LabelViewSpec | None = ..., + meta: global___LabelViewMeta | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["meta", b"meta", "spec", b"spec"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["meta", b"meta", "spec", b"spec"]) -> None: ... + +global___LabelView = LabelView + +class LabelViewSpec(google.protobuf.message.Message): + """Next available id: 16""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class TagsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + + NAME_FIELD_NUMBER: builtins.int + PROJECT_FIELD_NUMBER: builtins.int + ENTITIES_FIELD_NUMBER: builtins.int + FEATURES_FIELD_NUMBER: builtins.int + TAGS_FIELD_NUMBER: builtins.int + TTL_FIELD_NUMBER: builtins.int + SOURCE_FIELD_NUMBER: builtins.int + ONLINE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + OWNER_FIELD_NUMBER: builtins.int + ENTITY_COLUMNS_FIELD_NUMBER: builtins.int + LABELER_FIELD_FIELD_NUMBER: builtins.int + CONFLICT_POLICY_FIELD_NUMBER: builtins.int + RETAIN_HISTORY_FIELD_NUMBER: builtins.int + REFERENCE_FEATURE_VIEW_FIELD_NUMBER: builtins.int + name: builtins.str + """Name of the label view. Must be unique. Not updated.""" + project: builtins.str + """Name of Feast project that this label view belongs to.""" + @property + def entities(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """List of names of entities associated with this label view.""" + @property + def features(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Feature_pb2.FeatureSpecV2]: + """List of specifications for each label field defined as part of this label view.""" + @property + def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: + """User defined metadata.""" + @property + def ttl(self) -> google.protobuf.duration_pb2.Duration: + """Labels older than ttl will be excluded from online serving.""" + @property + def source(self) -> feast.core.DataSource_pb2.DataSource: + """DataSource (typically a PushSource) that feeds label data into this view.""" + online: builtins.bool + """Whether labels should be served from the online store.""" + description: builtins.str + """Description of the label view.""" + owner: builtins.str + """Owner of the label view.""" + @property + def entity_columns(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Feature_pb2.FeatureSpecV2]: + """List of specifications for each entity column.""" + labeler_field: builtins.str + """The schema field that identifies the labeler (e.g. "labeler").""" + conflict_policy: global___ConflictResolutionPolicy.ValueType + """How conflicting labels from different labelers are resolved. + Enforced for offline store reads; online store uses LAST_WRITE_WINS. + """ + retain_history: builtins.bool + """DEPRECATED: retain_history is always true (offline store always appends). + Field kept for backwards wire compatibility; ignored by the SDK. + """ + reference_feature_view: builtins.str + """Optional name of the FeatureView whose entities this label view annotates.""" + def __init__( + self, + *, + name: builtins.str = ..., + project: builtins.str = ..., + entities: collections.abc.Iterable[builtins.str] | None = ..., + features: collections.abc.Iterable[feast.core.Feature_pb2.FeatureSpecV2] | None = ..., + tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + ttl: google.protobuf.duration_pb2.Duration | None = ..., + source: feast.core.DataSource_pb2.DataSource | None = ..., + online: builtins.bool = ..., + description: builtins.str = ..., + owner: builtins.str = ..., + entity_columns: collections.abc.Iterable[feast.core.Feature_pb2.FeatureSpecV2] | None = ..., + labeler_field: builtins.str = ..., + conflict_policy: global___ConflictResolutionPolicy.ValueType = ..., + retain_history: builtins.bool = ..., + reference_feature_view: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["source", b"source", "ttl", b"ttl"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["conflict_policy", b"conflict_policy", "description", b"description", "entities", b"entities", "entity_columns", b"entity_columns", "features", b"features", "labeler_field", b"labeler_field", "name", b"name", "online", b"online", "owner", b"owner", "project", b"project", "reference_feature_view", b"reference_feature_view", "retain_history", b"retain_history", "source", b"source", "tags", b"tags", "ttl", b"ttl"]) -> None: ... + +global___LabelViewSpec = LabelViewSpec + +class LabelViewMeta(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CREATED_TIMESTAMP_FIELD_NUMBER: builtins.int + LAST_UPDATED_TIMESTAMP_FIELD_NUMBER: builtins.int + @property + def created_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Time when this Label View was created.""" + @property + def last_updated_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Time when this Label View was last updated.""" + def __init__( + self, + *, + created_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + last_updated_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> None: ... + +global___LabelViewMeta = LabelViewMeta diff --git a/sdk/python/feast/protos/feast/core/LabelView_pb2_grpc.py b/sdk/python/feast/protos/feast/core/LabelView_pb2_grpc.py new file mode 100644 index 00000000000..2daafffebfc --- /dev/null +++ b/sdk/python/feast/protos/feast/core/LabelView_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py b/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py index 5b8ec9b11f6..1c264ec06c5 100644 --- a/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py +++ b/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py @@ -21,7 +21,7 @@ from feast.protos.feast.core import Aggregation_pb2 as feast_dot_core_dot_Aggregation__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$feast/core/OnDemandFeatureView.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a&feast/core/FeatureViewProjection.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\x1a\x1c\x66\x65\x61st/core/Aggregation.proto\"{\n\x13OnDemandFeatureView\x12\x31\n\x04spec\x18\x01 \x01(\x0b\x32#.feast.core.OnDemandFeatureViewSpec\x12\x31\n\x04meta\x18\x02 \x01(\x0b\x32#.feast.core.OnDemandFeatureViewMeta\"\xbf\x05\n\x17OnDemandFeatureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12+\n\x08\x66\x65\x61tures\x18\x03 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x41\n\x07sources\x18\x04 \x03(\x0b\x32\x30.feast.core.OnDemandFeatureViewSpec.SourcesEntry\x12\x42\n\x15user_defined_function\x18\x05 \x01(\x0b\x32\x1f.feast.core.UserDefinedFunctionB\x02\x18\x01\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\n \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12;\n\x04tags\x18\x07 \x03(\x0b\x32-.feast.core.OnDemandFeatureViewSpec.TagsEntry\x12\r\n\x05owner\x18\x08 \x01(\t\x12\x0c\n\x04mode\x18\x0b \x01(\t\x12\x1d\n\x15write_to_online_store\x18\x0c \x01(\x08\x12\x10\n\x08\x65ntities\x18\r \x03(\t\x12\x31\n\x0e\x65ntity_columns\x18\x0e \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x11\n\tsingleton\x18\x0f \x01(\x08\x12-\n\x0c\x61ggregations\x18\x10 \x03(\x0b\x32\x17.feast.core.Aggregation\x1aJ\n\x0cSourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.core.OnDemandSource:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8c\x01\n\x17OnDemandFeatureViewMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xc8\x01\n\x0eOnDemandSource\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x44\n\x17\x66\x65\x61ture_view_projection\x18\x03 \x01(\x0b\x32!.feast.core.FeatureViewProjectionH\x00\x12\x35\n\x13request_data_source\x18\x02 \x01(\x0b\x32\x16.feast.core.DataSourceH\x00\x42\x08\n\x06source\"H\n\x13UserDefinedFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x62ody\x18\x02 \x01(\x0c\x12\x11\n\tbody_text\x18\x03 \x01(\t:\x02\x18\x01\"X\n\x17OnDemandFeatureViewList\x12=\n\x14ondemandfeatureviews\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureViewB]\n\x10\x66\x65\x61st.proto.coreB\x18OnDemandFeatureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$feast/core/OnDemandFeatureView.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a&feast/core/FeatureViewProjection.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\x1a\x1c\x66\x65\x61st/core/Aggregation.proto\"{\n\x13OnDemandFeatureView\x12\x31\n\x04spec\x18\x01 \x01(\x0b\x32#.feast.core.OnDemandFeatureViewSpec\x12\x31\n\x04meta\x18\x02 \x01(\x0b\x32#.feast.core.OnDemandFeatureViewMeta\"\xef\x05\n\x17OnDemandFeatureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12+\n\x08\x66\x65\x61tures\x18\x03 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x41\n\x07sources\x18\x04 \x03(\x0b\x32\x30.feast.core.OnDemandFeatureViewSpec.SourcesEntry\x12\x42\n\x15user_defined_function\x18\x05 \x01(\x0b\x32\x1f.feast.core.UserDefinedFunctionB\x02\x18\x01\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\n \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12;\n\x04tags\x18\x07 \x03(\x0b\x32-.feast.core.OnDemandFeatureViewSpec.TagsEntry\x12\r\n\x05owner\x18\x08 \x01(\t\x12\x0c\n\x04mode\x18\x0b \x01(\t\x12\x1d\n\x15write_to_online_store\x18\x0c \x01(\x08\x12\x10\n\x08\x65ntities\x18\r \x03(\t\x12\x31\n\x0e\x65ntity_columns\x18\x0e \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x11\n\tsingleton\x18\x0f \x01(\x08\x12-\n\x0c\x61ggregations\x18\x10 \x03(\x0b\x32\x17.feast.core.Aggregation\x12\x0f\n\x07version\x18\x11 \x01(\t\x12\x0b\n\x03org\x18\x12 \x01(\t\x12\x10\n\x08\x64isabled\x18\x13 \x01(\x08\x1aJ\n\x0cSourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.core.OnDemandSource:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xed\x01\n\x17OnDemandFeatureViewMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1e\n\x16\x63urrent_version_number\x18\x03 \x01(\x05\x12\x12\n\nversion_id\x18\x04 \x01(\t\x12+\n\x05state\x18\x05 \x01(\x0e\x32\x1c.feast.core.FeatureViewState\"\xc8\x01\n\x0eOnDemandSource\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x44\n\x17\x66\x65\x61ture_view_projection\x18\x03 \x01(\x0b\x32!.feast.core.FeatureViewProjectionH\x00\x12\x35\n\x13request_data_source\x18\x02 \x01(\x0b\x32\x16.feast.core.DataSourceH\x00\x42\x08\n\x06source\"H\n\x13UserDefinedFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x62ody\x18\x02 \x01(\x0c\x12\x11\n\tbody_text\x18\x03 \x01(\t:\x02\x18\x01\"X\n\x17OnDemandFeatureViewList\x12=\n\x14ondemandfeatureviews\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureViewB]\n\x10\x66\x65\x61st.proto.coreB\x18OnDemandFeatureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -40,17 +40,17 @@ _globals['_ONDEMANDFEATUREVIEW']._serialized_start=273 _globals['_ONDEMANDFEATUREVIEW']._serialized_end=396 _globals['_ONDEMANDFEATUREVIEWSPEC']._serialized_start=399 - _globals['_ONDEMANDFEATUREVIEWSPEC']._serialized_end=1102 - _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_start=983 - _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_end=1057 - _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1059 - _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1102 - _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_start=1105 - _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_end=1245 - _globals['_ONDEMANDSOURCE']._serialized_start=1248 - _globals['_ONDEMANDSOURCE']._serialized_end=1448 - _globals['_USERDEFINEDFUNCTION']._serialized_start=1450 - _globals['_USERDEFINEDFUNCTION']._serialized_end=1522 - _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_start=1524 - _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_end=1612 + _globals['_ONDEMANDFEATUREVIEWSPEC']._serialized_end=1150 + _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_start=1031 + _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_end=1105 + _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1107 + _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1150 + _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_start=1153 + _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_end=1390 + _globals['_ONDEMANDSOURCE']._serialized_start=1393 + _globals['_ONDEMANDSOURCE']._serialized_end=1593 + _globals['_USERDEFINEDFUNCTION']._serialized_start=1595 + _globals['_USERDEFINEDFUNCTION']._serialized_end=1667 + _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_start=1669 + _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_end=1757 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyi b/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyi index c424c442ee7..9b5db304df7 100644 --- a/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyi @@ -59,7 +59,7 @@ class OnDemandFeatureView(google.protobuf.message.Message): global___OnDemandFeatureView = OnDemandFeatureView class OnDemandFeatureViewSpec(google.protobuf.message.Message): - """Next available id: 9""" + """Next available id: 19""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -110,6 +110,9 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): ENTITY_COLUMNS_FIELD_NUMBER: builtins.int SINGLETON_FIELD_NUMBER: builtins.int AGGREGATIONS_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int + DISABLED_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -144,6 +147,15 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): @property def aggregations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Aggregation_pb2.Aggregation]: """Aggregation definitions""" + version: builtins.str + """User-specified version pin (e.g. "latest", "v2", "version2")""" + org: builtins.str + """Organizational unit that owns this feature view (e.g. "ads", "search").""" + disabled: builtins.bool + """Whether this feature view is disabled for serving. + When true, the feature view will not serve features. + Defaults to false (enabled) for backward compatibility. + """ def __init__( self, *, @@ -162,9 +174,12 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): entity_columns: collections.abc.Iterable[feast.core.Feature_pb2.FeatureSpecV2] | None = ..., singleton: builtins.bool = ..., aggregations: collections.abc.Iterable[feast.core.Aggregation_pb2.Aggregation] | None = ..., + version: builtins.str = ..., + org: builtins.str = ..., + disabled: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["feature_transformation", b"feature_transformation", "user_defined_function", b"user_defined_function"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["aggregations", b"aggregations", "description", b"description", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "owner", b"owner", "project", b"project", "singleton", b"singleton", "sources", b"sources", "tags", b"tags", "user_defined_function", b"user_defined_function", "write_to_online_store", b"write_to_online_store"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["aggregations", b"aggregations", "description", b"description", "disabled", b"disabled", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "org", b"org", "owner", b"owner", "project", b"project", "singleton", b"singleton", "sources", b"sources", "tags", b"tags", "user_defined_function", b"user_defined_function", "version", b"version", "write_to_online_store", b"write_to_online_store"]) -> None: ... global___OnDemandFeatureViewSpec = OnDemandFeatureViewSpec @@ -173,20 +188,32 @@ class OnDemandFeatureViewMeta(google.protobuf.message.Message): CREATED_TIMESTAMP_FIELD_NUMBER: builtins.int LAST_UPDATED_TIMESTAMP_FIELD_NUMBER: builtins.int + CURRENT_VERSION_NUMBER_FIELD_NUMBER: builtins.int + VERSION_ID_FIELD_NUMBER: builtins.int + STATE_FIELD_NUMBER: builtins.int @property def created_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: """Time where this Feature View is created""" @property def last_updated_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: """Time where this Feature View is last updated""" + current_version_number: builtins.int + """The current version number of this feature view in the version history.""" + version_id: builtins.str + """Auto-generated UUID identifying this specific version.""" + state: feast.core.FeatureView_pb2.FeatureViewState.ValueType + """Lifecycle state of this feature view.""" def __init__( self, *, created_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., last_updated_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + current_version_number: builtins.int = ..., + version_id: builtins.str = ..., + state: feast.core.FeatureView_pb2.FeatureViewState.ValueType = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "current_version_number", b"current_version_number", "last_updated_timestamp", b"last_updated_timestamp", "state", b"state", "version_id", b"version_id"]) -> None: ... global___OnDemandFeatureViewMeta = OnDemandFeatureViewMeta diff --git a/sdk/python/feast/protos/feast/core/Permission_pb2.py b/sdk/python/feast/protos/feast/core/Permission_pb2.py index 706fd2eec47..f44540c45e0 100644 --- a/sdk/python/feast/protos/feast/core/Permission_pb2.py +++ b/sdk/python/feast/protos/feast/core/Permission_pb2.py @@ -16,7 +16,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x66\x65\x61st/core/Permission.proto\x12\nfeast.core\x1a\x17\x66\x65\x61st/core/Policy.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"`\n\nPermission\x12(\n\x04spec\x18\x01 \x01(\x0b\x32\x1a.feast.core.PermissionSpec\x12(\n\x04meta\x18\x02 \x01(\x0b\x32\x1a.feast.core.PermissionMeta\"\xa0\x06\n\x0ePermissionSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\x05types\x18\x03 \x03(\x0e\x32\x1f.feast.core.PermissionSpec.Type\x12\x15\n\rname_patterns\x18\x04 \x03(\t\x12\x43\n\rrequired_tags\x18\x05 \x03(\x0b\x32,.feast.core.PermissionSpec.RequiredTagsEntry\x12\x39\n\x07\x61\x63tions\x18\x06 \x03(\x0e\x32(.feast.core.PermissionSpec.AuthzedAction\x12\"\n\x06policy\x18\x07 \x01(\x0b\x32\x12.feast.core.Policy\x12\x32\n\x04tags\x18\x08 \x03(\x0b\x32$.feast.core.PermissionSpec.TagsEntry\x1a\x33\n\x11RequiredTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x89\x01\n\rAuthzedAction\x12\n\n\x06\x43REATE\x10\x00\x12\x0c\n\x08\x44\x45SCRIBE\x10\x01\x12\n\n\x06UPDATE\x10\x02\x12\n\n\x06\x44\x45LETE\x10\x03\x12\x0f\n\x0bREAD_ONLINE\x10\x04\x12\x10\n\x0cREAD_OFFLINE\x10\x05\x12\x10\n\x0cWRITE_ONLINE\x10\x06\x12\x11\n\rWRITE_OFFLINE\x10\x07\"\xe1\x01\n\x04Type\x12\x10\n\x0c\x46\x45\x41TURE_VIEW\x10\x00\x12\x1a\n\x16ON_DEMAND_FEATURE_VIEW\x10\x01\x12\x16\n\x12\x42\x41TCH_FEATURE_VIEW\x10\x02\x12\x17\n\x13STREAM_FEATURE_VIEW\x10\x03\x12\n\n\x06\x45NTITY\x10\x04\x12\x13\n\x0f\x46\x45\x41TURE_SERVICE\x10\x05\x12\x0f\n\x0b\x44\x41TA_SOURCE\x10\x06\x12\x18\n\x14VALIDATION_REFERENCE\x10\x07\x12\x11\n\rSAVED_DATASET\x10\x08\x12\x0e\n\nPERMISSION\x10\t\x12\x0b\n\x07PROJECT\x10\n\"\x83\x01\n\x0ePermissionMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampBT\n\x10\x66\x65\x61st.proto.coreB\x0fPermissionProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x66\x65\x61st/core/Permission.proto\x12\nfeast.core\x1a\x17\x66\x65\x61st/core/Policy.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"`\n\nPermission\x12(\n\x04spec\x18\x01 \x01(\x0b\x32\x1a.feast.core.PermissionSpec\x12(\n\x04meta\x18\x02 \x01(\x0b\x32\x1a.feast.core.PermissionMeta\"\xb0\x06\n\x0ePermissionSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\x05types\x18\x03 \x03(\x0e\x32\x1f.feast.core.PermissionSpec.Type\x12\x15\n\rname_patterns\x18\x04 \x03(\t\x12\x43\n\rrequired_tags\x18\x05 \x03(\x0b\x32,.feast.core.PermissionSpec.RequiredTagsEntry\x12\x39\n\x07\x61\x63tions\x18\x06 \x03(\x0e\x32(.feast.core.PermissionSpec.AuthzedAction\x12\"\n\x06policy\x18\x07 \x01(\x0b\x32\x12.feast.core.Policy\x12\x32\n\x04tags\x18\x08 \x03(\x0b\x32$.feast.core.PermissionSpec.TagsEntry\x1a\x33\n\x11RequiredTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x89\x01\n\rAuthzedAction\x12\n\n\x06\x43REATE\x10\x00\x12\x0c\n\x08\x44\x45SCRIBE\x10\x01\x12\n\n\x06UPDATE\x10\x02\x12\n\n\x06\x44\x45LETE\x10\x03\x12\x0f\n\x0bREAD_ONLINE\x10\x04\x12\x10\n\x0cREAD_OFFLINE\x10\x05\x12\x10\n\x0cWRITE_ONLINE\x10\x06\x12\x11\n\rWRITE_OFFLINE\x10\x07\"\xf1\x01\n\x04Type\x12\x10\n\x0c\x46\x45\x41TURE_VIEW\x10\x00\x12\x1a\n\x16ON_DEMAND_FEATURE_VIEW\x10\x01\x12\x16\n\x12\x42\x41TCH_FEATURE_VIEW\x10\x02\x12\x17\n\x13STREAM_FEATURE_VIEW\x10\x03\x12\n\n\x06\x45NTITY\x10\x04\x12\x13\n\x0f\x46\x45\x41TURE_SERVICE\x10\x05\x12\x0f\n\x0b\x44\x41TA_SOURCE\x10\x06\x12\x18\n\x14VALIDATION_REFERENCE\x10\x07\x12\x11\n\rSAVED_DATASET\x10\x08\x12\x0e\n\nPERMISSION\x10\t\x12\x0b\n\x07PROJECT\x10\n\x12\x0e\n\nLABEL_VIEW\x10\x0b\"\x83\x01\n\x0ePermissionMeta\x12\x35\n\x11\x63reated_timestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampBT\n\x10\x66\x65\x61st.proto.coreB\x0fPermissionProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -31,7 +31,7 @@ _globals['_PERMISSION']._serialized_start=101 _globals['_PERMISSION']._serialized_end=197 _globals['_PERMISSIONSPEC']._serialized_start=200 - _globals['_PERMISSIONSPEC']._serialized_end=1000 + _globals['_PERMISSIONSPEC']._serialized_end=1016 _globals['_PERMISSIONSPEC_REQUIREDTAGSENTRY']._serialized_start=536 _globals['_PERMISSIONSPEC_REQUIREDTAGSENTRY']._serialized_end=587 _globals['_PERMISSIONSPEC_TAGSENTRY']._serialized_start=589 @@ -39,7 +39,7 @@ _globals['_PERMISSIONSPEC_AUTHZEDACTION']._serialized_start=635 _globals['_PERMISSIONSPEC_AUTHZEDACTION']._serialized_end=772 _globals['_PERMISSIONSPEC_TYPE']._serialized_start=775 - _globals['_PERMISSIONSPEC_TYPE']._serialized_end=1000 - _globals['_PERMISSIONMETA']._serialized_start=1003 - _globals['_PERMISSIONMETA']._serialized_end=1134 + _globals['_PERMISSIONSPEC_TYPE']._serialized_end=1016 + _globals['_PERMISSIONMETA']._serialized_start=1019 + _globals['_PERMISSIONMETA']._serialized_end=1150 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/Permission_pb2.pyi b/sdk/python/feast/protos/feast/core/Permission_pb2.pyi index b2387d29465..9f9ec301728 100644 --- a/sdk/python/feast/protos/feast/core/Permission_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/Permission_pb2.pyi @@ -87,6 +87,7 @@ class PermissionSpec(google.protobuf.message.Message): SAVED_DATASET: PermissionSpec._Type.ValueType # 8 PERMISSION: PermissionSpec._Type.ValueType # 9 PROJECT: PermissionSpec._Type.ValueType # 10 + LABEL_VIEW: PermissionSpec._Type.ValueType # 11 class Type(_Type, metaclass=_TypeEnumTypeWrapper): ... FEATURE_VIEW: PermissionSpec.Type.ValueType # 0 @@ -100,6 +101,7 @@ class PermissionSpec(google.protobuf.message.Message): SAVED_DATASET: PermissionSpec.Type.ValueType # 8 PERMISSION: PermissionSpec.Type.ValueType # 9 PROJECT: PermissionSpec.Type.ValueType # 10 + LABEL_VIEW: PermissionSpec.Type.ValueType # 11 class RequiredTagsEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor diff --git a/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.py b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.py new file mode 100644 index 00000000000..f86f32238cb --- /dev/null +++ b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: feast/core/PrecomputedFeatureVector.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from feast.protos.feast.types import Value_pb2 as feast_dot_types_dot_Value__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)feast/core/PrecomputedFeatureVector.proto\x12\nfeast.core\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17\x66\x65\x61st/types/Value.proto\"\xc2\x01\n\x18PrecomputedFeatureVector\x12\x15\n\rfeature_names\x18\x01 \x03(\t\x12\"\n\x06values\x18\x02 \x03(\x0b\x32\x12.feast.types.Value\x12\x37\n\rfv_timestamps\x18\x03 \x03(\x0b\x32 .feast.core.FeatureViewTimestamp\x12\x32\n\x0eprecomputed_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"f\n\x14\x46\x65\x61tureViewTimestamp\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x33\n\x0f\x65vent_timestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampBb\n\x10\x66\x65\x61st.proto.coreB\x1dPrecomputedFeatureVectorProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'feast.core.PrecomputedFeatureVector_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\035PrecomputedFeatureVectorProtoZ/github.com/feast-dev/feast/go/protos/feast/core' + _globals['_PRECOMPUTEDFEATUREVECTOR']._serialized_start=116 + _globals['_PRECOMPUTEDFEATUREVECTOR']._serialized_end=310 + _globals['_FEATUREVIEWTIMESTAMP']._serialized_start=312 + _globals['_FEATUREVIEWTIMESTAMP']._serialized_end=414 +# @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.pyi b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.pyi new file mode 100644 index 00000000000..919f1b59973 --- /dev/null +++ b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2.pyi @@ -0,0 +1,76 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import collections.abc +import feast.types.Value_pb2 +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import google.protobuf.timestamp_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class PrecomputedFeatureVector(google.protobuf.message.Message): + """A pre-computed feature vector stores all features for a FeatureService + as a single serialized blob per entity, enabling O(1) online retrieval. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FEATURE_NAMES_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + FV_TIMESTAMPS_FIELD_NUMBER: builtins.int + PRECOMPUTED_AT_FIELD_NUMBER: builtins.int + @property + def feature_names(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Fully-qualified feature names in deterministic order, e.g. "fv1__feat1".""" + @property + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.types.Value_pb2.Value]: + """Feature values in the same order as feature_names.""" + @property + def fv_timestamps(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FeatureViewTimestamp]: + """Per-feature-view event timestamps for TTL enforcement at read time.""" + @property + def precomputed_at(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Wall-clock time when this vector was assembled.""" + def __init__( + self, + *, + feature_names: collections.abc.Iterable[builtins.str] | None = ..., + values: collections.abc.Iterable[feast.types.Value_pb2.Value] | None = ..., + fv_timestamps: collections.abc.Iterable[global___FeatureViewTimestamp] | None = ..., + precomputed_at: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["precomputed_at", b"precomputed_at"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["feature_names", b"feature_names", "fv_timestamps", b"fv_timestamps", "precomputed_at", b"precomputed_at", "values", b"values"]) -> None: ... + +global___PrecomputedFeatureVector = PrecomputedFeatureVector + +class FeatureViewTimestamp(google.protobuf.message.Message): + """Event timestamp associated with a specific feature view within the vector.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FEATURE_VIEW_NAME_FIELD_NUMBER: builtins.int + EVENT_TIMESTAMP_FIELD_NUMBER: builtins.int + feature_view_name: builtins.str + @property + def event_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + def __init__( + self, + *, + feature_view_name: builtins.str = ..., + event_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["event_timestamp", b"event_timestamp"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["event_timestamp", b"event_timestamp", "feature_view_name", b"feature_view_name"]) -> None: ... + +global___FeatureViewTimestamp = FeatureViewTimestamp diff --git a/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2_grpc.py b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2_grpc.py new file mode 100644 index 00000000000..2daafffebfc --- /dev/null +++ b/sdk/python/feast/protos/feast/core/PrecomputedFeatureVector_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/sdk/python/feast/protos/feast/core/Registry_pb2.py b/sdk/python/feast/protos/feast/core/Registry_pb2.py index 671958d80c7..1c20c3ae654 100644 --- a/sdk/python/feast/protos/feast/core/Registry_pb2.py +++ b/sdk/python/feast/protos/feast/core/Registry_pb2.py @@ -25,9 +25,11 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 from feast.protos.feast.core import Permission_pb2 as feast_dot_core_dot_Permission__pb2 from feast.protos.feast.core import Project_pb2 as feast_dot_core_dot_Project__pb2 +from feast.protos.feast.core import FeatureViewVersion_pb2 as feast_dot_core_dot_FeatureViewVersion__pb2 +from feast.protos.feast.core import LabelView_pb2 as feast_dot_core_dot_LabelView__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x66\x65\x61st/core/Registry.proto\x12\nfeast.core\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/FeatureTable.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\"\xff\x05\n\x08Registry\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\x12\x30\n\x0e\x66\x65\x61ture_tables\x18\x02 \x03(\x0b\x32\x18.feast.core.FeatureTable\x12.\n\rfeature_views\x18\x06 \x03(\x0b\x32\x17.feast.core.FeatureView\x12,\n\x0c\x64\x61ta_sources\x18\x0c \x03(\x0b\x32\x16.feast.core.DataSource\x12@\n\x17on_demand_feature_views\x18\x08 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\x12;\n\x14stream_feature_views\x18\x0e \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\x12\x34\n\x10\x66\x65\x61ture_services\x18\x07 \x03(\x0b\x32\x1a.feast.core.FeatureService\x12\x30\n\x0esaved_datasets\x18\x0b \x03(\x0b\x32\x18.feast.core.SavedDataset\x12>\n\x15validation_references\x18\r \x03(\x0b\x32\x1f.feast.core.ValidationReference\x12 \n\x05infra\x18\n \x01(\x0b\x32\x11.feast.core.Infra\x12\x39\n\x10project_metadata\x18\x0f \x03(\x0b\x32\x1b.feast.core.ProjectMetadataB\x02\x18\x01\x12\x1f\n\x17registry_schema_version\x18\x03 \x01(\t\x12\x12\n\nversion_id\x18\x04 \x01(\t\x12\x30\n\x0clast_updated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x0bpermissions\x18\x10 \x03(\x0b\x32\x16.feast.core.Permission\x12%\n\x08projects\x18\x11 \x03(\x0b\x32\x13.feast.core.Project\"8\n\x0fProjectMetadata\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0cproject_uuid\x18\x02 \x01(\tBR\n\x10\x66\x65\x61st.proto.coreB\rRegistryProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x66\x65\x61st/core/Registry.proto\x12\nfeast.core\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/FeatureTable.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\x1a#feast/core/FeatureViewVersion.proto\x1a\x1a\x66\x65\x61st/core/LabelView.proto\"\xf8\x06\n\x08Registry\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\x12\x30\n\x0e\x66\x65\x61ture_tables\x18\x02 \x03(\x0b\x32\x18.feast.core.FeatureTable\x12.\n\rfeature_views\x18\x06 \x03(\x0b\x32\x17.feast.core.FeatureView\x12,\n\x0c\x64\x61ta_sources\x18\x0c \x03(\x0b\x32\x16.feast.core.DataSource\x12@\n\x17on_demand_feature_views\x18\x08 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\x12;\n\x14stream_feature_views\x18\x0e \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\x12\x34\n\x10\x66\x65\x61ture_services\x18\x07 \x03(\x0b\x32\x1a.feast.core.FeatureService\x12\x30\n\x0esaved_datasets\x18\x0b \x03(\x0b\x32\x18.feast.core.SavedDataset\x12>\n\x15validation_references\x18\r \x03(\x0b\x32\x1f.feast.core.ValidationReference\x12 \n\x05infra\x18\n \x01(\x0b\x32\x11.feast.core.Infra\x12\x39\n\x10project_metadata\x18\x0f \x03(\x0b\x32\x1b.feast.core.ProjectMetadataB\x02\x18\x01\x12\x1f\n\x17registry_schema_version\x18\x03 \x01(\t\x12\x12\n\nversion_id\x18\x04 \x01(\t\x12\x30\n\x0clast_updated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x0bpermissions\x18\x10 \x03(\x0b\x32\x16.feast.core.Permission\x12%\n\x08projects\x18\x11 \x03(\x0b\x32\x13.feast.core.Project\x12K\n\x1c\x66\x65\x61ture_view_version_history\x18\x12 \x01(\x0b\x32%.feast.core.FeatureViewVersionHistory\x12*\n\x0blabel_views\x18\x13 \x03(\x0b\x32\x15.feast.core.LabelView\"8\n\x0fProjectMetadata\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0cproject_uuid\x18\x02 \x01(\tBR\n\x10\x66\x65\x61st.proto.coreB\rRegistryProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -37,8 +39,8 @@ _globals['DESCRIPTOR']._serialized_options = b'\n\020feast.proto.coreB\rRegistryProtoZ/github.com/feast-dev/feast/go/protos/feast/core' _globals['_REGISTRY'].fields_by_name['project_metadata']._options = None _globals['_REGISTRY'].fields_by_name['project_metadata']._serialized_options = b'\030\001' - _globals['_REGISTRY']._serialized_start=449 - _globals['_REGISTRY']._serialized_end=1216 - _globals['_PROJECTMETADATA']._serialized_start=1218 - _globals['_PROJECTMETADATA']._serialized_end=1274 + _globals['_REGISTRY']._serialized_start=514 + _globals['_REGISTRY']._serialized_end=1402 + _globals['_PROJECTMETADATA']._serialized_start=1404 + _globals['_PROJECTMETADATA']._serialized_end=1460 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/Registry_pb2.pyi b/sdk/python/feast/protos/feast/core/Registry_pb2.pyi index fca49c75481..55c6e5600d8 100644 --- a/sdk/python/feast/protos/feast/core/Registry_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/Registry_pb2.pyi @@ -1,19 +1,19 @@ """ @generated by mypy-protobuf. Do not edit manually! isort:skip_file - -* Copyright 2020 The Feast Authors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and + +* Copyright 2020 The Feast Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* https://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and * limitations under the License. """ import builtins @@ -22,8 +22,10 @@ import feast.core.DataSource_pb2 import feast.core.Entity_pb2 import feast.core.FeatureService_pb2 import feast.core.FeatureTable_pb2 +import feast.core.FeatureViewVersion_pb2 import feast.core.FeatureView_pb2 import feast.core.InfraObject_pb2 +import feast.core.LabelView_pb2 import feast.core.OnDemandFeatureView_pb2 import feast.core.Permission_pb2 import feast.core.Project_pb2 @@ -44,7 +46,7 @@ else: DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class Registry(google.protobuf.message.Message): - """Next id: 18""" + """Next id: 20""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -64,6 +66,8 @@ class Registry(google.protobuf.message.Message): LAST_UPDATED_FIELD_NUMBER: builtins.int PERMISSIONS_FIELD_NUMBER: builtins.int PROJECTS_FIELD_NUMBER: builtins.int + FEATURE_VIEW_VERSION_HISTORY_FIELD_NUMBER: builtins.int + LABEL_VIEWS_FIELD_NUMBER: builtins.int @property def entities(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Entity_pb2.Entity]: ... @property @@ -97,6 +101,10 @@ class Registry(google.protobuf.message.Message): def permissions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Permission_pb2.Permission]: ... @property def projects(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Project_pb2.Project]: ... + @property + def feature_view_version_history(self) -> feast.core.FeatureViewVersion_pb2.FeatureViewVersionHistory: ... + @property + def label_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.LabelView_pb2.LabelView]: ... def __init__( self, *, @@ -116,9 +124,11 @@ class Registry(google.protobuf.message.Message): last_updated: google.protobuf.timestamp_pb2.Timestamp | None = ..., permissions: collections.abc.Iterable[feast.core.Permission_pb2.Permission] | None = ..., projects: collections.abc.Iterable[feast.core.Project_pb2.Project] | None = ..., + feature_view_version_history: feast.core.FeatureViewVersion_pb2.FeatureViewVersionHistory | None = ..., + label_views: collections.abc.Iterable[feast.core.LabelView_pb2.LabelView] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["infra", b"infra", "last_updated", b"last_updated"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["data_sources", b"data_sources", "entities", b"entities", "feature_services", b"feature_services", "feature_tables", b"feature_tables", "feature_views", b"feature_views", "infra", b"infra", "last_updated", b"last_updated", "on_demand_feature_views", b"on_demand_feature_views", "permissions", b"permissions", "project_metadata", b"project_metadata", "projects", b"projects", "registry_schema_version", b"registry_schema_version", "saved_datasets", b"saved_datasets", "stream_feature_views", b"stream_feature_views", "validation_references", b"validation_references", "version_id", b"version_id"]) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["feature_view_version_history", b"feature_view_version_history", "infra", b"infra", "last_updated", b"last_updated"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["data_sources", b"data_sources", "entities", b"entities", "feature_services", b"feature_services", "feature_tables", b"feature_tables", "feature_view_version_history", b"feature_view_version_history", "feature_views", b"feature_views", "infra", b"infra", "label_views", b"label_views", "last_updated", b"last_updated", "on_demand_feature_views", b"on_demand_feature_views", "permissions", b"permissions", "project_metadata", b"project_metadata", "projects", b"projects", "registry_schema_version", b"registry_schema_version", "saved_datasets", b"saved_datasets", "stream_feature_views", b"stream_feature_views", "validation_references", b"validation_references", "version_id", b"version_id"]) -> None: ... global___Registry = Registry diff --git a/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py b/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py index cd3ec690574..9222c1bd2ae 100644 --- a/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py +++ b/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py @@ -21,7 +21,7 @@ from feast.protos.feast.core import Transformation_pb2 as feast_dot_core_dot_Transformation__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"feast/core/StreamFeatureView.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/Aggregation.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\"o\n\x11StreamFeatureView\x12/\n\x04spec\x18\x01 \x01(\x0b\x32!.feast.core.StreamFeatureViewSpec\x12)\n\x04meta\x18\x02 \x01(\x0b\x32\x1b.feast.core.FeatureViewMeta\"\x8e\x06\n\x15StreamFeatureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x10\n\x08\x65ntities\x18\x03 \x03(\t\x12+\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x31\n\x0e\x65ntity_columns\x18\x05 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x39\n\x04tags\x18\x07 \x03(\x0b\x32+.feast.core.StreamFeatureViewSpec.TagsEntry\x12\r\n\x05owner\x18\x08 \x01(\t\x12&\n\x03ttl\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\x0c\x62\x61tch_source\x18\n \x01(\x0b\x32\x16.feast.core.DataSource\x12-\n\rstream_source\x18\x0b \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0e\n\x06online\x18\x0c \x01(\x08\x12\x42\n\x15user_defined_function\x18\r \x01(\x0b\x32\x1f.feast.core.UserDefinedFunctionB\x02\x18\x01\x12\x0c\n\x04mode\x18\x0e \x01(\t\x12-\n\x0c\x61ggregations\x18\x0f \x03(\x0b\x32\x17.feast.core.Aggregation\x12\x17\n\x0ftimestamp_field\x18\x10 \x01(\t\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\x11 \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x15\n\renable_tiling\x18\x12 \x01(\x08\x12\x32\n\x0ftiling_hop_size\x18\x13 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x65nable_validation\x18\x14 \x01(\x08\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42[\n\x10\x66\x65\x61st.proto.coreB\x16StreamFeatureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"feast/core/StreamFeatureView.proto\x12\nfeast.core\x1a\x1egoogle/protobuf/duration.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\x18\x66\x65\x61st/core/Feature.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/Aggregation.proto\x1a\x1f\x66\x65\x61st/core/Transformation.proto\"o\n\x11StreamFeatureView\x12/\n\x04spec\x18\x01 \x01(\x0b\x32!.feast.core.StreamFeatureViewSpec\x12)\n\x04meta\x18\x02 \x01(\x0b\x32\x1b.feast.core.FeatureViewMeta\"\xbe\x06\n\x15StreamFeatureViewSpec\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x10\n\x08\x65ntities\x18\x03 \x03(\t\x12+\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x31\n\x0e\x65ntity_columns\x18\x05 \x03(\x0b\x32\x19.feast.core.FeatureSpecV2\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x39\n\x04tags\x18\x07 \x03(\x0b\x32+.feast.core.StreamFeatureViewSpec.TagsEntry\x12\r\n\x05owner\x18\x08 \x01(\t\x12&\n\x03ttl\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\x0c\x62\x61tch_source\x18\n \x01(\x0b\x32\x16.feast.core.DataSource\x12-\n\rstream_source\x18\x0b \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0e\n\x06online\x18\x0c \x01(\x08\x12\x42\n\x15user_defined_function\x18\r \x01(\x0b\x32\x1f.feast.core.UserDefinedFunctionB\x02\x18\x01\x12\x0c\n\x04mode\x18\x0e \x01(\t\x12-\n\x0c\x61ggregations\x18\x0f \x03(\x0b\x32\x17.feast.core.Aggregation\x12\x17\n\x0ftimestamp_field\x18\x10 \x01(\t\x12\x43\n\x16\x66\x65\x61ture_transformation\x18\x11 \x01(\x0b\x32#.feast.core.FeatureTransformationV2\x12\x15\n\renable_tiling\x18\x12 \x01(\x08\x12\x32\n\x0ftiling_hop_size\x18\x13 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x65nable_validation\x18\x14 \x01(\x08\x12\x0f\n\x07version\x18\x15 \x01(\t\x12\x0b\n\x03org\x18\x16 \x01(\t\x12\x10\n\x08\x64isabled\x18\x17 \x01(\x08\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42[\n\x10\x66\x65\x61st.proto.coreB\x16StreamFeatureViewProtoZ/github.com/feast-dev/feast/go/protos/feast/coreb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -36,7 +36,7 @@ _globals['_STREAMFEATUREVIEW']._serialized_start=268 _globals['_STREAMFEATUREVIEW']._serialized_end=379 _globals['_STREAMFEATUREVIEWSPEC']._serialized_start=382 - _globals['_STREAMFEATUREVIEWSPEC']._serialized_end=1164 - _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1121 - _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1164 + _globals['_STREAMFEATUREVIEWSPEC']._serialized_end=1212 + _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1169 + _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1212 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.pyi b/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.pyi index 853ada60a27..3fa504654f4 100644 --- a/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.pyi @@ -59,7 +59,7 @@ class StreamFeatureView(google.protobuf.message.Message): global___StreamFeatureView = StreamFeatureView class StreamFeatureViewSpec(google.protobuf.message.Message): - """Next available id: 21""" + """Next available id: 23""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -98,6 +98,9 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): ENABLE_TILING_FIELD_NUMBER: builtins.int TILING_HOP_SIZE_FIELD_NUMBER: builtins.int ENABLE_VALIDATION_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int + DISABLED_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -155,6 +158,15 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): """ enable_validation: builtins.bool """Whether schema validation is enabled during materialization""" + version: builtins.str + """User-specified version pin (e.g. "latest", "v2", "version2")""" + org: builtins.str + """Organizational unit that owns this stream feature view (e.g. "ads", "search").""" + disabled: builtins.bool + """Whether this feature view is disabled for serving and materialization. + When true, the feature view will not serve online features or be materialized. + Defaults to false (enabled) for backward compatibility. + """ def __init__( self, *, @@ -178,8 +190,11 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): enable_tiling: builtins.bool = ..., tiling_hop_size: google.protobuf.duration_pb2.Duration | None = ..., enable_validation: builtins.bool = ..., + version: builtins.str = ..., + org: builtins.str = ..., + disabled: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["batch_source", b"batch_source", "feature_transformation", b"feature_transformation", "stream_source", b"stream_source", "tiling_hop_size", b"tiling_hop_size", "ttl", b"ttl", "user_defined_function", b"user_defined_function"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["aggregations", b"aggregations", "batch_source", b"batch_source", "description", b"description", "enable_tiling", b"enable_tiling", "enable_validation", b"enable_validation", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "online", b"online", "owner", b"owner", "project", b"project", "stream_source", b"stream_source", "tags", b"tags", "tiling_hop_size", b"tiling_hop_size", "timestamp_field", b"timestamp_field", "ttl", b"ttl", "user_defined_function", b"user_defined_function"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["aggregations", b"aggregations", "batch_source", b"batch_source", "description", b"description", "disabled", b"disabled", "enable_tiling", b"enable_tiling", "enable_validation", b"enable_validation", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "online", b"online", "org", b"org", "owner", b"owner", "project", b"project", "stream_source", b"stream_source", "tags", b"tags", "tiling_hop_size", b"tiling_hop_size", "timestamp_field", b"timestamp_field", "ttl", b"ttl", "user_defined_function", b"user_defined_function", "version", b"version"]) -> None: ... global___StreamFeatureViewSpec = StreamFeatureViewSpec diff --git a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py index 8b346fcd672..8fa18d331c4 100644 --- a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py +++ b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.py @@ -24,11 +24,12 @@ from feast.protos.feast.core import SavedDataset_pb2 as feast_dot_core_dot_SavedDataset__pb2 from feast.protos.feast.core import ValidationProfile_pb2 as feast_dot_core_dot_ValidationProfile__pb2 from feast.protos.feast.core import InfraObject_pb2 as feast_dot_core_dot_InfraObject__pb2 +from feast.protos.feast.core import LabelView_pb2 as feast_dot_core_dot_LabelView__pb2 from feast.protos.feast.core import Permission_pb2 as feast_dot_core_dot_Permission__pb2 from feast.protos.feast.core import Project_pb2 as feast_dot_core_dot_Project__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#feast/registry/RegistryServer.proto\x12\x0e\x66\x65\x61st.registry\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x66\x65\x61st/core/Registry.proto\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\"/\n\x10PaginationParams\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\"4\n\rSortingParams\x12\x0f\n\x07sort_by\x18\x01 \x01(\t\x12\x12\n\nsort_order\x18\x02 \x01(\t\"\x83\x01\n\x12PaginationMetadata\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\x12\x13\n\x0btotal_count\x18\x03 \x01(\x05\x12\x13\n\x0btotal_pages\x18\x04 \x01(\x05\x12\x10\n\x08has_next\x18\x05 \x01(\x08\x12\x14\n\x0chas_previous\x18\x06 \x01(\x08\"!\n\x0eRefreshRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\"W\n\x12UpdateInfraRequest\x12 \n\x05infra\x18\x01 \x01(\x0b\x32\x11.feast.core.Infra\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"7\n\x0fGetInfraRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"B\n\x1aListProjectMetadataRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"T\n\x1bListProjectMetadataResponse\x12\x35\n\x10project_metadata\x18\x01 \x03(\x0b\x32\x1b.feast.core.ProjectMetadata\"\xcb\x01\n\x1b\x41pplyMaterializationRequest\x12-\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureView\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\nstart_date\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\"Y\n\x12\x41pplyEntityRequest\x12\"\n\x06\x65ntity\x18\x01 \x01(\x0b\x32\x12.feast.core.Entity\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"F\n\x10GetEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x8b\x02\n\x13ListEntitiesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12;\n\x04tags\x18\x03 \x03(\x0b\x32-.feast.registry.ListEntitiesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"t\n\x14ListEntitiesResponse\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"D\n\x13\x44\x65leteEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"f\n\x16\x41pplyDataSourceRequest\x12+\n\x0b\x64\x61ta_source\x18\x01 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListDataSourcesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListDataSourcesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x7f\n\x17ListDataSourcesResponse\x12,\n\x0c\x64\x61ta_sources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSource\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65leteDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x02\n\x17\x41pplyFeatureViewRequest\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x12\x0f\n\x07project\x18\x04 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\x42\x13\n\x11\x62\x61se_feature_view\"K\n\x15GetFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x93\x02\n\x17ListFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12?\n\x04tags\x18\x03 \x03(\x0b\x32\x31.feast.registry.ListFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x82\x01\n\x18ListFeatureViewsResponse\x12.\n\rfeature_views\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"I\n\x18\x44\x65leteFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\xd6\x01\n\x0e\x41nyFeatureView\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x42\x12\n\x10\x61ny_feature_view\"N\n\x18GetAnyFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"U\n\x19GetAnyFeatureViewResponse\x12\x38\n\x10\x61ny_feature_view\x18\x01 \x01(\x0b\x32\x1e.feast.registry.AnyFeatureView\"\xe8\x02\n\x1aListAllFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListAllFeatureViewsRequest.TagsEntry\x12\x0e\n\x06\x65ntity\x18\x04 \x01(\t\x12\x0f\n\x07\x66\x65\x61ture\x18\x05 \x01(\t\x12\x17\n\x0f\x66\x65\x61ture_service\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x61ta_source\x18\x07 \x01(\t\x12\x34\n\npagination\x18\x08 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\t \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8c\x01\n\x1bListAllFeatureViewsResponse\x12\x35\n\rfeature_views\x18\x01 \x03(\x0b\x32\x1e.feast.registry.AnyFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n\x1bGetStreamFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x9f\x02\n\x1dListStreamFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x45\n\x04tags\x18\x03 \x03(\x0b\x32\x37.feast.registry.ListStreamFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x95\x01\n\x1eListStreamFeatureViewsResponse\x12;\n\x14stream_feature_views\x18\x01 \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"S\n\x1dGetOnDemandFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListOnDemandFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListOnDemandFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9c\x01\n ListOnDemandFeatureViewsResponse\x12@\n\x17on_demand_feature_views\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"r\n\x1a\x41pplyFeatureServiceRequest\x12\x33\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\x0b\x32\x1a.feast.core.FeatureService\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"N\n\x18GetFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xaf\x02\n\x1aListFeatureServicesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListFeatureServicesRequest.TagsEntry\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x04 \x01(\t\x12\x34\n\npagination\x18\x05 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x06 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8b\x01\n\x1bListFeatureServicesResponse\x12\x34\n\x10\x66\x65\x61ture_services\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureService\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"L\n\x1b\x44\x65leteFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"l\n\x18\x41pplySavedDatasetRequest\x12/\n\rsaved_dataset\x18\x01 \x01(\x0b\x32\x18.feast.core.SavedDataset\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"L\n\x16GetSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x95\x02\n\x18ListSavedDatasetsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12@\n\x04tags\x18\x03 \x03(\x0b\x32\x32.feast.registry.ListSavedDatasetsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x85\x01\n\x19ListSavedDatasetsResponse\x12\x30\n\x0esaved_datasets\x18\x01 \x03(\x0b\x32\x18.feast.core.SavedDataset\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"J\n\x19\x44\x65leteSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x01\n\x1f\x41pplyValidationReferenceRequest\x12=\n\x14validation_reference\x18\x01 \x01(\x0b\x32\x1f.feast.core.ValidationReference\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"S\n\x1dGetValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListValidationReferencesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListValidationReferencesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9a\x01\n ListValidationReferencesResponse\x12>\n\x15validation_references\x18\x01 \x03(\x0b\x32\x1f.feast.core.ValidationReference\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n DeleteValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"e\n\x16\x41pplyPermissionRequest\x12*\n\npermission\x18\x01 \x01(\x0b\x32\x16.feast.core.Permission\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetPermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListPermissionsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListPermissionsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"~\n\x17ListPermissionsResponse\x12+\n\x0bpermissions\x18\x01 \x03(\x0b\x32\x16.feast.core.Permission\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65letePermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"K\n\x13\x41pplyProjectRequest\x12$\n\x07project\x18\x01 \x01(\x0b\x32\x13.feast.core.Project\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"6\n\x11GetProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"\xfa\x01\n\x13ListProjectsRequest\x12\x13\n\x0b\x61llow_cache\x18\x01 \x01(\x08\x12;\n\x04tags\x18\x02 \x03(\x0b\x32-.feast.registry.ListProjectsRequest.TagsEntry\x12\x34\n\npagination\x18\x03 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x04 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"u\n\x14ListProjectsResponse\x12%\n\x08projects\x18\x01 \x03(\x0b\x32\x13.feast.core.Project\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"4\n\x14\x44\x65leteProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"-\n\x0f\x45ntityReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\x0e\x45ntityRelation\x12/\n\x06source\x18\x01 \x01(\x0b\x32\x1f.feast.registry.EntityReference\x12/\n\x06target\x18\x02 \x01(\x0b\x32\x1f.feast.registry.EntityReference\"\xdf\x01\n\x19GetRegistryLineageRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x1a\n\x12\x66ilter_object_type\x18\x03 \x01(\t\x12\x1a\n\x12\x66ilter_object_name\x18\x04 \x01(\t\x12\x34\n\npagination\x18\x05 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x06 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\xa8\x02\n\x1aGetRegistryLineageResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12>\n\x16indirect_relationships\x18\x02 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x44\n\x18relationships_pagination\x18\x03 \x01(\x0b\x32\".feast.registry.PaginationMetadata\x12M\n!indirect_relationships_pagination\x18\x04 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"\xef\x01\n\x1dGetObjectRelationshipsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0bobject_type\x18\x02 \x01(\t\x12\x13\n\x0bobject_name\x18\x03 \x01(\t\x12\x18\n\x10include_indirect\x18\x04 \x01(\x08\x12\x13\n\x0b\x61llow_cache\x18\x05 \x01(\x08\x12\x34\n\npagination\x18\x06 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x07 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\x8f\x01\n\x1eGetObjectRelationshipsResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"\xb0\x02\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05owner\x18\x05 \x01(\t\x12\x35\n\x11\x63reated_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x04tags\x18\x08 \x03(\x0b\x32!.feast.registry.Feature.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc5\x01\n\x13ListFeaturesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x06 \x01(\x08\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"y\n\x14ListFeaturesResponse\x12)\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32\x17.feast.registry.Feature\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"]\n\x11GetFeatureRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x04 \x01(\x08\x32\xde#\n\x0eRegistryServer\x12K\n\x0b\x41pplyEntity\x12\".feast.registry.ApplyEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\tGetEntity\x12 .feast.registry.GetEntityRequest\x1a\x12.feast.core.Entity\"\x00\x12[\n\x0cListEntities\x12#.feast.registry.ListEntitiesRequest\x1a$.feast.registry.ListEntitiesResponse\"\x00\x12M\n\x0c\x44\x65leteEntity\x12#.feast.registry.DeleteEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyDataSource\x12&.feast.registry.ApplyDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetDataSource\x12$.feast.registry.GetDataSourceRequest\x1a\x16.feast.core.DataSource\"\x00\x12\x64\n\x0fListDataSources\x12&.feast.registry.ListDataSourcesRequest\x1a\'.feast.registry.ListDataSourcesResponse\"\x00\x12U\n\x10\x44\x65leteDataSource\x12\'.feast.registry.DeleteDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x10\x41pplyFeatureView\x12\'.feast.registry.ApplyFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x44\x65leteFeatureView\x12(.feast.registry.DeleteFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x11GetAnyFeatureView\x12(.feast.registry.GetAnyFeatureViewRequest\x1a).feast.registry.GetAnyFeatureViewResponse\"\x00\x12p\n\x13ListAllFeatureViews\x12*.feast.registry.ListAllFeatureViewsRequest\x1a+.feast.registry.ListAllFeatureViewsResponse\"\x00\x12R\n\x0eGetFeatureView\x12%.feast.registry.GetFeatureViewRequest\x1a\x17.feast.core.FeatureView\"\x00\x12g\n\x10ListFeatureViews\x12\'.feast.registry.ListFeatureViewsRequest\x1a(.feast.registry.ListFeatureViewsResponse\"\x00\x12\x64\n\x14GetStreamFeatureView\x12+.feast.registry.GetStreamFeatureViewRequest\x1a\x1d.feast.core.StreamFeatureView\"\x00\x12y\n\x16ListStreamFeatureViews\x12-.feast.registry.ListStreamFeatureViewsRequest\x1a..feast.registry.ListStreamFeatureViewsResponse\"\x00\x12j\n\x16GetOnDemandFeatureView\x12-.feast.registry.GetOnDemandFeatureViewRequest\x1a\x1f.feast.core.OnDemandFeatureView\"\x00\x12\x7f\n\x18ListOnDemandFeatureViews\x12/.feast.registry.ListOnDemandFeatureViewsRequest\x1a\x30.feast.registry.ListOnDemandFeatureViewsResponse\"\x00\x12[\n\x13\x41pplyFeatureService\x12*.feast.registry.ApplyFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12[\n\x11GetFeatureService\x12(.feast.registry.GetFeatureServiceRequest\x1a\x1a.feast.core.FeatureService\"\x00\x12p\n\x13ListFeatureServices\x12*.feast.registry.ListFeatureServicesRequest\x1a+.feast.registry.ListFeatureServicesResponse\"\x00\x12]\n\x14\x44\x65leteFeatureService\x12+.feast.registry.DeleteFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x41pplySavedDataset\x12(.feast.registry.ApplySavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x0fGetSavedDataset\x12&.feast.registry.GetSavedDatasetRequest\x1a\x18.feast.core.SavedDataset\"\x00\x12j\n\x11ListSavedDatasets\x12(.feast.registry.ListSavedDatasetsRequest\x1a).feast.registry.ListSavedDatasetsResponse\"\x00\x12Y\n\x12\x44\x65leteSavedDataset\x12).feast.registry.DeleteSavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x65\n\x18\x41pplyValidationReference\x12/.feast.registry.ApplyValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x16GetValidationReference\x12-.feast.registry.GetValidationReferenceRequest\x1a\x1f.feast.core.ValidationReference\"\x00\x12\x7f\n\x18ListValidationReferences\x12/.feast.registry.ListValidationReferencesRequest\x1a\x30.feast.registry.ListValidationReferencesResponse\"\x00\x12g\n\x19\x44\x65leteValidationReference\x12\x30.feast.registry.DeleteValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyPermission\x12&.feast.registry.ApplyPermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetPermission\x12$.feast.registry.GetPermissionRequest\x1a\x16.feast.core.Permission\"\x00\x12\x64\n\x0fListPermissions\x12&.feast.registry.ListPermissionsRequest\x1a\'.feast.registry.ListPermissionsResponse\"\x00\x12U\n\x10\x44\x65letePermission\x12\'.feast.registry.DeletePermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0c\x41pplyProject\x12#.feast.registry.ApplyProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\nGetProject\x12!.feast.registry.GetProjectRequest\x1a\x13.feast.core.Project\"\x00\x12[\n\x0cListProjects\x12#.feast.registry.ListProjectsRequest\x1a$.feast.registry.ListProjectsResponse\"\x00\x12O\n\rDeleteProject\x12$.feast.registry.DeleteProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12]\n\x14\x41pplyMaterialization\x12+.feast.registry.ApplyMaterializationRequest\x1a\x16.google.protobuf.Empty\"\x00\x12p\n\x13ListProjectMetadata\x12*.feast.registry.ListProjectMetadataRequest\x1a+.feast.registry.ListProjectMetadataResponse\"\x00\x12K\n\x0bUpdateInfra\x12\".feast.registry.UpdateInfraRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x08GetInfra\x12\x1f.feast.registry.GetInfraRequest\x1a\x11.feast.core.Infra\"\x00\x12:\n\x06\x43ommit\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\x07Refresh\x12\x1e.feast.registry.RefreshRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\x05Proto\x12\x16.google.protobuf.Empty\x1a\x14.feast.core.Registry\"\x00\x12m\n\x12GetRegistryLineage\x12).feast.registry.GetRegistryLineageRequest\x1a*.feast.registry.GetRegistryLineageResponse\"\x00\x12y\n\x16GetObjectRelationships\x12-.feast.registry.GetObjectRelationshipsRequest\x1a..feast.registry.GetObjectRelationshipsResponse\"\x00\x12[\n\x0cListFeatures\x12#.feast.registry.ListFeaturesRequest\x1a$.feast.registry.ListFeaturesResponse\"\x00\x12J\n\nGetFeature\x12!.feast.registry.GetFeatureRequest\x1a\x17.feast.registry.Feature\"\x00\x42\x35Z3github.com/feast-dev/feast/go/protos/feast/registryb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#feast/registry/RegistryServer.proto\x12\x0e\x66\x65\x61st.registry\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x66\x65\x61st/core/Registry.proto\x1a\x17\x66\x65\x61st/core/Entity.proto\x1a\x1b\x66\x65\x61st/core/DataSource.proto\x1a\x1c\x66\x65\x61st/core/FeatureView.proto\x1a\"feast/core/StreamFeatureView.proto\x1a$feast/core/OnDemandFeatureView.proto\x1a\x1f\x66\x65\x61st/core/FeatureService.proto\x1a\x1d\x66\x65\x61st/core/SavedDataset.proto\x1a\"feast/core/ValidationProfile.proto\x1a\x1c\x66\x65\x61st/core/InfraObject.proto\x1a\x1a\x66\x65\x61st/core/LabelView.proto\x1a\x1b\x66\x65\x61st/core/Permission.proto\x1a\x18\x66\x65\x61st/core/Project.proto\"/\n\x10PaginationParams\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\"4\n\rSortingParams\x12\x0f\n\x07sort_by\x18\x01 \x01(\t\x12\x12\n\nsort_order\x18\x02 \x01(\t\"\x83\x01\n\x12PaginationMetadata\x12\x0c\n\x04page\x18\x01 \x01(\x05\x12\r\n\x05limit\x18\x02 \x01(\x05\x12\x13\n\x0btotal_count\x18\x03 \x01(\x05\x12\x13\n\x0btotal_pages\x18\x04 \x01(\x05\x12\x10\n\x08has_next\x18\x05 \x01(\x08\x12\x14\n\x0chas_previous\x18\x06 \x01(\x08\"!\n\x0eRefreshRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\"W\n\x12UpdateInfraRequest\x12 \n\x05infra\x18\x01 \x01(\x0b\x32\x11.feast.core.Infra\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"7\n\x0fGetInfraRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"B\n\x1aListProjectMetadataRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"T\n\x1bListProjectMetadataResponse\x12\x35\n\x10project_metadata\x18\x01 \x03(\x0b\x32\x1b.feast.core.ProjectMetadata\"\xcb\x01\n\x1b\x41pplyMaterializationRequest\x12-\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureView\x12\x0f\n\x07project\x18\x02 \x01(\t\x12.\n\nstart_date\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\"Y\n\x12\x41pplyEntityRequest\x12\"\n\x06\x65ntity\x18\x01 \x01(\x0b\x32\x12.feast.core.Entity\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"F\n\x10GetEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x8b\x02\n\x13ListEntitiesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12;\n\x04tags\x18\x03 \x03(\x0b\x32-.feast.registry.ListEntitiesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"t\n\x14ListEntitiesResponse\x12$\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x12.feast.core.Entity\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"D\n\x13\x44\x65leteEntityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"f\n\x16\x41pplyDataSourceRequest\x12+\n\x0b\x64\x61ta_source\x18\x01 \x01(\x0b\x32\x16.feast.core.DataSource\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListDataSourcesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListDataSourcesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x7f\n\x17ListDataSourcesResponse\x12,\n\x0c\x64\x61ta_sources\x18\x01 \x03(\x0b\x32\x16.feast.core.DataSource\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65leteDataSourceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\xae\x02\n\x17\x41pplyFeatureViewRequest\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x12+\n\nlabel_view\x18\x06 \x01(\x0b\x32\x15.feast.core.LabelViewH\x00\x12\x0f\n\x07project\x18\x04 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x05 \x01(\x08\x42\x13\n\x11\x62\x61se_feature_view\"K\n\x15GetFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x93\x02\n\x17ListFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12?\n\x04tags\x18\x03 \x03(\x0b\x32\x31.feast.registry.ListFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x82\x01\n\x18ListFeatureViewsResponse\x12.\n\rfeature_views\x18\x01 \x03(\x0b\x32\x17.feast.core.FeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"I\n\x18\x44\x65leteFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x83\x02\n\x0e\x41nyFeatureView\x12/\n\x0c\x66\x65\x61ture_view\x18\x01 \x01(\x0b\x32\x17.feast.core.FeatureViewH\x00\x12\x41\n\x16on_demand_feature_view\x18\x02 \x01(\x0b\x32\x1f.feast.core.OnDemandFeatureViewH\x00\x12<\n\x13stream_feature_view\x18\x03 \x01(\x0b\x32\x1d.feast.core.StreamFeatureViewH\x00\x12+\n\nlabel_view\x18\x04 \x01(\x0b\x32\x15.feast.core.LabelViewH\x00\x42\x12\n\x10\x61ny_feature_view\"N\n\x18GetAnyFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"U\n\x19GetAnyFeatureViewResponse\x12\x38\n\x10\x61ny_feature_view\x18\x01 \x01(\x0b\x32\x1e.feast.registry.AnyFeatureView\"\xe8\x02\n\x1aListAllFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListAllFeatureViewsRequest.TagsEntry\x12\x0e\n\x06\x65ntity\x18\x04 \x01(\t\x12\x0f\n\x07\x66\x65\x61ture\x18\x05 \x01(\t\x12\x17\n\x0f\x66\x65\x61ture_service\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x61ta_source\x18\x07 \x01(\t\x12\x34\n\npagination\x18\x08 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\t \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8c\x01\n\x1bListAllFeatureViewsResponse\x12\x35\n\rfeature_views\x18\x01 \x03(\x0b\x32\x1e.feast.registry.AnyFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n\x1bGetStreamFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x9f\x02\n\x1dListStreamFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x45\n\x04tags\x18\x03 \x03(\x0b\x32\x37.feast.registry.ListStreamFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x95\x01\n\x1eListStreamFeatureViewsResponse\x12;\n\x14stream_feature_views\x18\x01 \x03(\x0b\x32\x1d.feast.core.StreamFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"S\n\x1dGetOnDemandFeatureViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListOnDemandFeatureViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListOnDemandFeatureViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9c\x01\n ListOnDemandFeatureViewsResponse\x12@\n\x17on_demand_feature_views\x18\x01 \x03(\x0b\x32\x1f.feast.core.OnDemandFeatureView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"I\n\x13GetLabelViewRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x8f\x02\n\x15ListLabelViewsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12=\n\x04tags\x18\x03 \x03(\x0b\x32/.feast.registry.ListLabelViewsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"|\n\x16ListLabelViewsResponse\x12*\n\x0blabel_views\x18\x01 \x03(\x0b\x32\x15.feast.core.LabelView\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"r\n\x1a\x41pplyFeatureServiceRequest\x12\x33\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\x0b\x32\x1a.feast.core.FeatureService\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"N\n\x18GetFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xaf\x02\n\x1aListFeatureServicesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x42\n\x04tags\x18\x03 \x03(\x0b\x32\x34.feast.registry.ListFeatureServicesRequest.TagsEntry\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x04 \x01(\t\x12\x34\n\npagination\x18\x05 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x06 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x8b\x01\n\x1bListFeatureServicesResponse\x12\x34\n\x10\x66\x65\x61ture_services\x18\x01 \x03(\x0b\x32\x1a.feast.core.FeatureService\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"L\n\x1b\x44\x65leteFeatureServiceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"l\n\x18\x41pplySavedDatasetRequest\x12/\n\rsaved_dataset\x18\x01 \x01(\x0b\x32\x18.feast.core.SavedDataset\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"L\n\x16GetSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x95\x02\n\x18ListSavedDatasetsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12@\n\x04tags\x18\x03 \x03(\x0b\x32\x32.feast.registry.ListSavedDatasetsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x85\x01\n\x19ListSavedDatasetsResponse\x12\x30\n\x0esaved_datasets\x18\x01 \x03(\x0b\x32\x18.feast.core.SavedDataset\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"J\n\x19\x44\x65leteSavedDatasetRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"\x81\x01\n\x1f\x41pplyValidationReferenceRequest\x12=\n\x14validation_reference\x18\x01 \x01(\x0b\x32\x1f.feast.core.ValidationReference\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"S\n\x1dGetValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\xa3\x02\n\x1fListValidationReferencesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12G\n\x04tags\x18\x03 \x03(\x0b\x32\x39.feast.registry.ListValidationReferencesRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x9a\x01\n ListValidationReferencesResponse\x12>\n\x15validation_references\x18\x01 \x03(\x0b\x32\x1f.feast.core.ValidationReference\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"Q\n DeleteValidationReferenceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"e\n\x16\x41pplyPermissionRequest\x12*\n\npermission\x18\x01 \x01(\x0b\x32\x16.feast.core.Permission\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"J\n\x14GetPermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x03 \x01(\x08\"\x91\x02\n\x16ListPermissionsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12>\n\x04tags\x18\x03 \x03(\x0b\x32\x30.feast.registry.ListPermissionsRequest.TagsEntry\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"~\n\x17ListPermissionsResponse\x12+\n\x0bpermissions\x18\x01 \x03(\x0b\x32\x16.feast.core.Permission\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"H\n\x17\x44\x65letePermissionRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x03 \x01(\x08\"K\n\x13\x41pplyProjectRequest\x12$\n\x07project\x18\x01 \x01(\x0b\x32\x13.feast.core.Project\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"6\n\x11GetProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\"\xfa\x01\n\x13ListProjectsRequest\x12\x13\n\x0b\x61llow_cache\x18\x01 \x01(\x08\x12;\n\x04tags\x18\x02 \x03(\x0b\x32-.feast.registry.ListProjectsRequest.TagsEntry\x12\x34\n\npagination\x18\x03 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x04 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"u\n\x14ListProjectsResponse\x12%\n\x08projects\x18\x01 \x03(\x0b\x32\x13.feast.core.Project\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"4\n\x14\x44\x65leteProjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x02 \x01(\x08\"-\n\x0f\x45ntityReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\x0e\x45ntityRelation\x12/\n\x06source\x18\x01 \x01(\x0b\x32\x1f.feast.registry.EntityReference\x12/\n\x06target\x18\x02 \x01(\x0b\x32\x1f.feast.registry.EntityReference\"\xdf\x01\n\x19GetRegistryLineageRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x02 \x01(\x08\x12\x1a\n\x12\x66ilter_object_type\x18\x03 \x01(\t\x12\x1a\n\x12\x66ilter_object_name\x18\x04 \x01(\t\x12\x34\n\npagination\x18\x05 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x06 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\xa8\x02\n\x1aGetRegistryLineageResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12>\n\x16indirect_relationships\x18\x02 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x44\n\x18relationships_pagination\x18\x03 \x01(\x0b\x32\".feast.registry.PaginationMetadata\x12M\n!indirect_relationships_pagination\x18\x04 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"\xef\x01\n\x1dGetObjectRelationshipsRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x13\n\x0bobject_type\x18\x02 \x01(\t\x12\x13\n\x0bobject_name\x18\x03 \x01(\t\x12\x18\n\x10include_indirect\x18\x04 \x01(\x08\x12\x13\n\x0b\x61llow_cache\x18\x05 \x01(\x08\x12\x34\n\npagination\x18\x06 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x07 \x01(\x0b\x32\x1d.feast.registry.SortingParams\"\x8f\x01\n\x1eGetObjectRelationshipsResponse\x12\x35\n\rrelationships\x18\x01 \x03(\x0b\x32\x1e.feast.registry.EntityRelation\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"\xbe\x02\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\r\n\x05owner\x18\x05 \x01(\t\x12\x35\n\x11\x63reated_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12:\n\x16last_updated_timestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x04tags\x18\x08 \x03(\x0b\x32!.feast.registry.Feature.TagsEntry\x12\x0c\n\x04kind\x18\t \x01(\t\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xd3\x01\n\x13ListFeaturesRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x06 \x01(\x08\x12\x34\n\npagination\x18\x04 \x01(\x0b\x32 .feast.registry.PaginationParams\x12.\n\x07sorting\x18\x05 \x01(\x0b\x32\x1d.feast.registry.SortingParams\x12\x0c\n\x04kind\x18\x07 \x01(\t\"y\n\x14ListFeaturesResponse\x12)\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32\x17.feast.registry.Feature\x12\x36\n\npagination\x18\x02 \x01(\x0b\x32\".feast.registry.PaginationMetadata\"]\n\x11GetFeatureRequest\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_view\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x61llow_cache\x18\x04 \x01(\x08\x32\x8f%\n\x0eRegistryServer\x12K\n\x0b\x41pplyEntity\x12\".feast.registry.ApplyEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\tGetEntity\x12 .feast.registry.GetEntityRequest\x1a\x12.feast.core.Entity\"\x00\x12[\n\x0cListEntities\x12#.feast.registry.ListEntitiesRequest\x1a$.feast.registry.ListEntitiesResponse\"\x00\x12M\n\x0c\x44\x65leteEntity\x12#.feast.registry.DeleteEntityRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyDataSource\x12&.feast.registry.ApplyDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetDataSource\x12$.feast.registry.GetDataSourceRequest\x1a\x16.feast.core.DataSource\"\x00\x12\x64\n\x0fListDataSources\x12&.feast.registry.ListDataSourcesRequest\x1a\'.feast.registry.ListDataSourcesResponse\"\x00\x12U\n\x10\x44\x65leteDataSource\x12\'.feast.registry.DeleteDataSourceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x10\x41pplyFeatureView\x12\'.feast.registry.ApplyFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x44\x65leteFeatureView\x12(.feast.registry.DeleteFeatureViewRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x11GetAnyFeatureView\x12(.feast.registry.GetAnyFeatureViewRequest\x1a).feast.registry.GetAnyFeatureViewResponse\"\x00\x12p\n\x13ListAllFeatureViews\x12*.feast.registry.ListAllFeatureViewsRequest\x1a+.feast.registry.ListAllFeatureViewsResponse\"\x00\x12R\n\x0eGetFeatureView\x12%.feast.registry.GetFeatureViewRequest\x1a\x17.feast.core.FeatureView\"\x00\x12g\n\x10ListFeatureViews\x12\'.feast.registry.ListFeatureViewsRequest\x1a(.feast.registry.ListFeatureViewsResponse\"\x00\x12\x64\n\x14GetStreamFeatureView\x12+.feast.registry.GetStreamFeatureViewRequest\x1a\x1d.feast.core.StreamFeatureView\"\x00\x12y\n\x16ListStreamFeatureViews\x12-.feast.registry.ListStreamFeatureViewsRequest\x1a..feast.registry.ListStreamFeatureViewsResponse\"\x00\x12j\n\x16GetOnDemandFeatureView\x12-.feast.registry.GetOnDemandFeatureViewRequest\x1a\x1f.feast.core.OnDemandFeatureView\"\x00\x12\x7f\n\x18ListOnDemandFeatureViews\x12/.feast.registry.ListOnDemandFeatureViewsRequest\x1a\x30.feast.registry.ListOnDemandFeatureViewsResponse\"\x00\x12L\n\x0cGetLabelView\x12#.feast.registry.GetLabelViewRequest\x1a\x15.feast.core.LabelView\"\x00\x12\x61\n\x0eListLabelViews\x12%.feast.registry.ListLabelViewsRequest\x1a&.feast.registry.ListLabelViewsResponse\"\x00\x12[\n\x13\x41pplyFeatureService\x12*.feast.registry.ApplyFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12[\n\x11GetFeatureService\x12(.feast.registry.GetFeatureServiceRequest\x1a\x1a.feast.core.FeatureService\"\x00\x12p\n\x13ListFeatureServices\x12*.feast.registry.ListFeatureServicesRequest\x1a+.feast.registry.ListFeatureServicesResponse\"\x00\x12]\n\x14\x44\x65leteFeatureService\x12+.feast.registry.DeleteFeatureServiceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12W\n\x11\x41pplySavedDataset\x12(.feast.registry.ApplySavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12U\n\x0fGetSavedDataset\x12&.feast.registry.GetSavedDatasetRequest\x1a\x18.feast.core.SavedDataset\"\x00\x12j\n\x11ListSavedDatasets\x12(.feast.registry.ListSavedDatasetsRequest\x1a).feast.registry.ListSavedDatasetsResponse\"\x00\x12Y\n\x12\x44\x65leteSavedDataset\x12).feast.registry.DeleteSavedDatasetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x65\n\x18\x41pplyValidationReference\x12/.feast.registry.ApplyValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12j\n\x16GetValidationReference\x12-.feast.registry.GetValidationReferenceRequest\x1a\x1f.feast.core.ValidationReference\"\x00\x12\x7f\n\x18ListValidationReferences\x12/.feast.registry.ListValidationReferencesRequest\x1a\x30.feast.registry.ListValidationReferencesResponse\"\x00\x12g\n\x19\x44\x65leteValidationReference\x12\x30.feast.registry.DeleteValidationReferenceRequest\x1a\x16.google.protobuf.Empty\"\x00\x12S\n\x0f\x41pplyPermission\x12&.feast.registry.ApplyPermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12O\n\rGetPermission\x12$.feast.registry.GetPermissionRequest\x1a\x16.feast.core.Permission\"\x00\x12\x64\n\x0fListPermissions\x12&.feast.registry.ListPermissionsRequest\x1a\'.feast.registry.ListPermissionsResponse\"\x00\x12U\n\x10\x44\x65letePermission\x12\'.feast.registry.DeletePermissionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0c\x41pplyProject\x12#.feast.registry.ApplyProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\nGetProject\x12!.feast.registry.GetProjectRequest\x1a\x13.feast.core.Project\"\x00\x12[\n\x0cListProjects\x12#.feast.registry.ListProjectsRequest\x1a$.feast.registry.ListProjectsResponse\"\x00\x12O\n\rDeleteProject\x12$.feast.registry.DeleteProjectRequest\x1a\x16.google.protobuf.Empty\"\x00\x12]\n\x14\x41pplyMaterialization\x12+.feast.registry.ApplyMaterializationRequest\x1a\x16.google.protobuf.Empty\"\x00\x12p\n\x13ListProjectMetadata\x12*.feast.registry.ListProjectMetadataRequest\x1a+.feast.registry.ListProjectMetadataResponse\"\x00\x12K\n\x0bUpdateInfra\x12\".feast.registry.UpdateInfraRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x08GetInfra\x12\x1f.feast.registry.GetInfraRequest\x1a\x11.feast.core.Infra\"\x00\x12:\n\x06\x43ommit\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\x07Refresh\x12\x1e.feast.registry.RefreshRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\x05Proto\x12\x16.google.protobuf.Empty\x1a\x14.feast.core.Registry\"\x00\x12m\n\x12GetRegistryLineage\x12).feast.registry.GetRegistryLineageRequest\x1a*.feast.registry.GetRegistryLineageResponse\"\x00\x12y\n\x16GetObjectRelationships\x12-.feast.registry.GetObjectRelationshipsRequest\x1a..feast.registry.GetObjectRelationshipsResponse\"\x00\x12[\n\x0cListFeatures\x12#.feast.registry.ListFeaturesRequest\x1a$.feast.registry.ListFeaturesResponse\"\x00\x12J\n\nGetFeature\x12!.feast.registry.GetFeatureRequest\x1a\x17.feast.registry.Feature\"\x00\x42\x35Z3github.com/feast-dev/feast/go/protos/feast/registryb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -48,6 +49,8 @@ _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._options = None _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_options = b'8\001' + _globals['_LISTLABELVIEWSREQUEST_TAGSENTRY']._options = None + _globals['_LISTLABELVIEWSREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._options = None _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._options = None @@ -60,170 +63,178 @@ _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_FEATURE_TAGSENTRY']._options = None _globals['_FEATURE_TAGSENTRY']._serialized_options = b'8\001' - _globals['_PAGINATIONPARAMS']._serialized_start=487 - _globals['_PAGINATIONPARAMS']._serialized_end=534 - _globals['_SORTINGPARAMS']._serialized_start=536 - _globals['_SORTINGPARAMS']._serialized_end=588 - _globals['_PAGINATIONMETADATA']._serialized_start=591 - _globals['_PAGINATIONMETADATA']._serialized_end=722 - _globals['_REFRESHREQUEST']._serialized_start=724 - _globals['_REFRESHREQUEST']._serialized_end=757 - _globals['_UPDATEINFRAREQUEST']._serialized_start=759 - _globals['_UPDATEINFRAREQUEST']._serialized_end=846 - _globals['_GETINFRAREQUEST']._serialized_start=848 - _globals['_GETINFRAREQUEST']._serialized_end=903 - _globals['_LISTPROJECTMETADATAREQUEST']._serialized_start=905 - _globals['_LISTPROJECTMETADATAREQUEST']._serialized_end=971 - _globals['_LISTPROJECTMETADATARESPONSE']._serialized_start=973 - _globals['_LISTPROJECTMETADATARESPONSE']._serialized_end=1057 - _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_start=1060 - _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_end=1263 - _globals['_APPLYENTITYREQUEST']._serialized_start=1265 - _globals['_APPLYENTITYREQUEST']._serialized_end=1354 - _globals['_GETENTITYREQUEST']._serialized_start=1356 - _globals['_GETENTITYREQUEST']._serialized_end=1426 - _globals['_LISTENTITIESREQUEST']._serialized_start=1429 - _globals['_LISTENTITIESREQUEST']._serialized_end=1696 - _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTENTITIESRESPONSE']._serialized_start=1698 - _globals['_LISTENTITIESRESPONSE']._serialized_end=1814 - _globals['_DELETEENTITYREQUEST']._serialized_start=1816 - _globals['_DELETEENTITYREQUEST']._serialized_end=1884 - _globals['_APPLYDATASOURCEREQUEST']._serialized_start=1886 - _globals['_APPLYDATASOURCEREQUEST']._serialized_end=1988 - _globals['_GETDATASOURCEREQUEST']._serialized_start=1990 - _globals['_GETDATASOURCEREQUEST']._serialized_end=2064 - _globals['_LISTDATASOURCESREQUEST']._serialized_start=2067 - _globals['_LISTDATASOURCESREQUEST']._serialized_end=2340 - _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTDATASOURCESRESPONSE']._serialized_start=2342 - _globals['_LISTDATASOURCESRESPONSE']._serialized_end=2469 - _globals['_DELETEDATASOURCEREQUEST']._serialized_start=2471 - _globals['_DELETEDATASOURCEREQUEST']._serialized_end=2543 - _globals['_APPLYFEATUREVIEWREQUEST']._serialized_start=2546 - _globals['_APPLYFEATUREVIEWREQUEST']._serialized_end=2803 - _globals['_GETFEATUREVIEWREQUEST']._serialized_start=2805 - _globals['_GETFEATUREVIEWREQUEST']._serialized_end=2880 - _globals['_LISTFEATUREVIEWSREQUEST']._serialized_start=2883 - _globals['_LISTFEATUREVIEWSREQUEST']._serialized_end=3158 - _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_start=3161 - _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_end=3291 - _globals['_DELETEFEATUREVIEWREQUEST']._serialized_start=3293 - _globals['_DELETEFEATUREVIEWREQUEST']._serialized_end=3366 - _globals['_ANYFEATUREVIEW']._serialized_start=3369 - _globals['_ANYFEATUREVIEW']._serialized_end=3583 - _globals['_GETANYFEATUREVIEWREQUEST']._serialized_start=3585 - _globals['_GETANYFEATUREVIEWREQUEST']._serialized_end=3663 - _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_start=3665 - _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_end=3750 - _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_start=3753 - _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_end=4113 - _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_start=4116 - _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_end=4256 - _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_start=4258 - _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_end=4339 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_start=4342 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_end=4629 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_start=4632 - _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_end=4781 - _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_start=4783 - _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_end=4866 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_start=4869 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_end=5160 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_start=5163 - _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_end=5319 - _globals['_APPLYFEATURESERVICEREQUEST']._serialized_start=5321 - _globals['_APPLYFEATURESERVICEREQUEST']._serialized_end=5435 - _globals['_GETFEATURESERVICEREQUEST']._serialized_start=5437 - _globals['_GETFEATURESERVICEREQUEST']._serialized_end=5515 - _globals['_LISTFEATURESERVICESREQUEST']._serialized_start=5518 - _globals['_LISTFEATURESERVICESREQUEST']._serialized_end=5821 - _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTFEATURESERVICESRESPONSE']._serialized_start=5824 - _globals['_LISTFEATURESERVICESRESPONSE']._serialized_end=5963 - _globals['_DELETEFEATURESERVICEREQUEST']._serialized_start=5965 - _globals['_DELETEFEATURESERVICEREQUEST']._serialized_end=6041 - _globals['_APPLYSAVEDDATASETREQUEST']._serialized_start=6043 - _globals['_APPLYSAVEDDATASETREQUEST']._serialized_end=6151 - _globals['_GETSAVEDDATASETREQUEST']._serialized_start=6153 - _globals['_GETSAVEDDATASETREQUEST']._serialized_end=6229 - _globals['_LISTSAVEDDATASETSREQUEST']._serialized_start=6232 - _globals['_LISTSAVEDDATASETSREQUEST']._serialized_end=6509 - _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_start=6512 - _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_end=6645 - _globals['_DELETESAVEDDATASETREQUEST']._serialized_start=6647 - _globals['_DELETESAVEDDATASETREQUEST']._serialized_end=6721 - _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_start=6724 - _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_end=6853 - _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_start=6855 - _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_end=6938 - _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_start=6941 - _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_end=7232 - _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_start=7235 - _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_end=7389 - _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_start=7391 - _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_end=7472 - _globals['_APPLYPERMISSIONREQUEST']._serialized_start=7474 - _globals['_APPLYPERMISSIONREQUEST']._serialized_end=7575 - _globals['_GETPERMISSIONREQUEST']._serialized_start=7577 - _globals['_GETPERMISSIONREQUEST']._serialized_end=7651 - _globals['_LISTPERMISSIONSREQUEST']._serialized_start=7654 - _globals['_LISTPERMISSIONSREQUEST']._serialized_end=7927 - _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTPERMISSIONSRESPONSE']._serialized_start=7929 - _globals['_LISTPERMISSIONSRESPONSE']._serialized_end=8055 - _globals['_DELETEPERMISSIONREQUEST']._serialized_start=8057 - _globals['_DELETEPERMISSIONREQUEST']._serialized_end=8129 - _globals['_APPLYPROJECTREQUEST']._serialized_start=8131 - _globals['_APPLYPROJECTREQUEST']._serialized_end=8206 - _globals['_GETPROJECTREQUEST']._serialized_start=8208 - _globals['_GETPROJECTREQUEST']._serialized_end=8262 - _globals['_LISTPROJECTSREQUEST']._serialized_start=8265 - _globals['_LISTPROJECTSREQUEST']._serialized_end=8515 - _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_start=1653 - _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_end=1696 - _globals['_LISTPROJECTSRESPONSE']._serialized_start=8517 - _globals['_LISTPROJECTSRESPONSE']._serialized_end=8634 - _globals['_DELETEPROJECTREQUEST']._serialized_start=8636 - _globals['_DELETEPROJECTREQUEST']._serialized_end=8688 - _globals['_ENTITYREFERENCE']._serialized_start=8690 - _globals['_ENTITYREFERENCE']._serialized_end=8735 - _globals['_ENTITYRELATION']._serialized_start=8737 - _globals['_ENTITYRELATION']._serialized_end=8851 - _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_start=8854 - _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_end=9077 - _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_start=9080 - _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_end=9376 - _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_start=9379 - _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_end=9618 - _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_start=9621 - _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_end=9764 - _globals['_FEATURE']._serialized_start=9767 - _globals['_FEATURE']._serialized_end=10071 - _globals['_FEATURE_TAGSENTRY']._serialized_start=1653 - _globals['_FEATURE_TAGSENTRY']._serialized_end=1696 - _globals['_LISTFEATURESREQUEST']._serialized_start=10074 - _globals['_LISTFEATURESREQUEST']._serialized_end=10271 - _globals['_LISTFEATURESRESPONSE']._serialized_start=10273 - _globals['_LISTFEATURESRESPONSE']._serialized_end=10394 - _globals['_GETFEATUREREQUEST']._serialized_start=10396 - _globals['_GETFEATUREREQUEST']._serialized_end=10489 - _globals['_REGISTRYSERVER']._serialized_start=10492 - _globals['_REGISTRYSERVER']._serialized_end=15066 + _globals['_PAGINATIONPARAMS']._serialized_start=515 + _globals['_PAGINATIONPARAMS']._serialized_end=562 + _globals['_SORTINGPARAMS']._serialized_start=564 + _globals['_SORTINGPARAMS']._serialized_end=616 + _globals['_PAGINATIONMETADATA']._serialized_start=619 + _globals['_PAGINATIONMETADATA']._serialized_end=750 + _globals['_REFRESHREQUEST']._serialized_start=752 + _globals['_REFRESHREQUEST']._serialized_end=785 + _globals['_UPDATEINFRAREQUEST']._serialized_start=787 + _globals['_UPDATEINFRAREQUEST']._serialized_end=874 + _globals['_GETINFRAREQUEST']._serialized_start=876 + _globals['_GETINFRAREQUEST']._serialized_end=931 + _globals['_LISTPROJECTMETADATAREQUEST']._serialized_start=933 + _globals['_LISTPROJECTMETADATAREQUEST']._serialized_end=999 + _globals['_LISTPROJECTMETADATARESPONSE']._serialized_start=1001 + _globals['_LISTPROJECTMETADATARESPONSE']._serialized_end=1085 + _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_start=1088 + _globals['_APPLYMATERIALIZATIONREQUEST']._serialized_end=1291 + _globals['_APPLYENTITYREQUEST']._serialized_start=1293 + _globals['_APPLYENTITYREQUEST']._serialized_end=1382 + _globals['_GETENTITYREQUEST']._serialized_start=1384 + _globals['_GETENTITYREQUEST']._serialized_end=1454 + _globals['_LISTENTITIESREQUEST']._serialized_start=1457 + _globals['_LISTENTITIESREQUEST']._serialized_end=1724 + _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTENTITIESREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTENTITIESRESPONSE']._serialized_start=1726 + _globals['_LISTENTITIESRESPONSE']._serialized_end=1842 + _globals['_DELETEENTITYREQUEST']._serialized_start=1844 + _globals['_DELETEENTITYREQUEST']._serialized_end=1912 + _globals['_APPLYDATASOURCEREQUEST']._serialized_start=1914 + _globals['_APPLYDATASOURCEREQUEST']._serialized_end=2016 + _globals['_GETDATASOURCEREQUEST']._serialized_start=2018 + _globals['_GETDATASOURCEREQUEST']._serialized_end=2092 + _globals['_LISTDATASOURCESREQUEST']._serialized_start=2095 + _globals['_LISTDATASOURCESREQUEST']._serialized_end=2368 + _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTDATASOURCESREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTDATASOURCESRESPONSE']._serialized_start=2370 + _globals['_LISTDATASOURCESRESPONSE']._serialized_end=2497 + _globals['_DELETEDATASOURCEREQUEST']._serialized_start=2499 + _globals['_DELETEDATASOURCEREQUEST']._serialized_end=2571 + _globals['_APPLYFEATUREVIEWREQUEST']._serialized_start=2574 + _globals['_APPLYFEATUREVIEWREQUEST']._serialized_end=2876 + _globals['_GETFEATUREVIEWREQUEST']._serialized_start=2878 + _globals['_GETFEATUREVIEWREQUEST']._serialized_end=2953 + _globals['_LISTFEATUREVIEWSREQUEST']._serialized_start=2956 + _globals['_LISTFEATUREVIEWSREQUEST']._serialized_end=3231 + _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_start=3234 + _globals['_LISTFEATUREVIEWSRESPONSE']._serialized_end=3364 + _globals['_DELETEFEATUREVIEWREQUEST']._serialized_start=3366 + _globals['_DELETEFEATUREVIEWREQUEST']._serialized_end=3439 + _globals['_ANYFEATUREVIEW']._serialized_start=3442 + _globals['_ANYFEATUREVIEW']._serialized_end=3701 + _globals['_GETANYFEATUREVIEWREQUEST']._serialized_start=3703 + _globals['_GETANYFEATUREVIEWREQUEST']._serialized_end=3781 + _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_start=3783 + _globals['_GETANYFEATUREVIEWRESPONSE']._serialized_end=3868 + _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_start=3871 + _globals['_LISTALLFEATUREVIEWSREQUEST']._serialized_end=4231 + _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTALLFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_start=4234 + _globals['_LISTALLFEATUREVIEWSRESPONSE']._serialized_end=4374 + _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_start=4376 + _globals['_GETSTREAMFEATUREVIEWREQUEST']._serialized_end=4457 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_start=4460 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST']._serialized_end=4747 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTSTREAMFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_start=4750 + _globals['_LISTSTREAMFEATUREVIEWSRESPONSE']._serialized_end=4899 + _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_start=4901 + _globals['_GETONDEMANDFEATUREVIEWREQUEST']._serialized_end=4984 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_start=4987 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST']._serialized_end=5278 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTONDEMANDFEATUREVIEWSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_start=5281 + _globals['_LISTONDEMANDFEATUREVIEWSRESPONSE']._serialized_end=5437 + _globals['_GETLABELVIEWREQUEST']._serialized_start=5439 + _globals['_GETLABELVIEWREQUEST']._serialized_end=5512 + _globals['_LISTLABELVIEWSREQUEST']._serialized_start=5515 + _globals['_LISTLABELVIEWSREQUEST']._serialized_end=5786 + _globals['_LISTLABELVIEWSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTLABELVIEWSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTLABELVIEWSRESPONSE']._serialized_start=5788 + _globals['_LISTLABELVIEWSRESPONSE']._serialized_end=5912 + _globals['_APPLYFEATURESERVICEREQUEST']._serialized_start=5914 + _globals['_APPLYFEATURESERVICEREQUEST']._serialized_end=6028 + _globals['_GETFEATURESERVICEREQUEST']._serialized_start=6030 + _globals['_GETFEATURESERVICEREQUEST']._serialized_end=6108 + _globals['_LISTFEATURESERVICESREQUEST']._serialized_start=6111 + _globals['_LISTFEATURESERVICESREQUEST']._serialized_end=6414 + _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTFEATURESERVICESREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTFEATURESERVICESRESPONSE']._serialized_start=6417 + _globals['_LISTFEATURESERVICESRESPONSE']._serialized_end=6556 + _globals['_DELETEFEATURESERVICEREQUEST']._serialized_start=6558 + _globals['_DELETEFEATURESERVICEREQUEST']._serialized_end=6634 + _globals['_APPLYSAVEDDATASETREQUEST']._serialized_start=6636 + _globals['_APPLYSAVEDDATASETREQUEST']._serialized_end=6744 + _globals['_GETSAVEDDATASETREQUEST']._serialized_start=6746 + _globals['_GETSAVEDDATASETREQUEST']._serialized_end=6822 + _globals['_LISTSAVEDDATASETSREQUEST']._serialized_start=6825 + _globals['_LISTSAVEDDATASETSREQUEST']._serialized_end=7102 + _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTSAVEDDATASETSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_start=7105 + _globals['_LISTSAVEDDATASETSRESPONSE']._serialized_end=7238 + _globals['_DELETESAVEDDATASETREQUEST']._serialized_start=7240 + _globals['_DELETESAVEDDATASETREQUEST']._serialized_end=7314 + _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_start=7317 + _globals['_APPLYVALIDATIONREFERENCEREQUEST']._serialized_end=7446 + _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_start=7448 + _globals['_GETVALIDATIONREFERENCEREQUEST']._serialized_end=7531 + _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_start=7534 + _globals['_LISTVALIDATIONREFERENCESREQUEST']._serialized_end=7825 + _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTVALIDATIONREFERENCESREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_start=7828 + _globals['_LISTVALIDATIONREFERENCESRESPONSE']._serialized_end=7982 + _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_start=7984 + _globals['_DELETEVALIDATIONREFERENCEREQUEST']._serialized_end=8065 + _globals['_APPLYPERMISSIONREQUEST']._serialized_start=8067 + _globals['_APPLYPERMISSIONREQUEST']._serialized_end=8168 + _globals['_GETPERMISSIONREQUEST']._serialized_start=8170 + _globals['_GETPERMISSIONREQUEST']._serialized_end=8244 + _globals['_LISTPERMISSIONSREQUEST']._serialized_start=8247 + _globals['_LISTPERMISSIONSREQUEST']._serialized_end=8520 + _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTPERMISSIONSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTPERMISSIONSRESPONSE']._serialized_start=8522 + _globals['_LISTPERMISSIONSRESPONSE']._serialized_end=8648 + _globals['_DELETEPERMISSIONREQUEST']._serialized_start=8650 + _globals['_DELETEPERMISSIONREQUEST']._serialized_end=8722 + _globals['_APPLYPROJECTREQUEST']._serialized_start=8724 + _globals['_APPLYPROJECTREQUEST']._serialized_end=8799 + _globals['_GETPROJECTREQUEST']._serialized_start=8801 + _globals['_GETPROJECTREQUEST']._serialized_end=8855 + _globals['_LISTPROJECTSREQUEST']._serialized_start=8858 + _globals['_LISTPROJECTSREQUEST']._serialized_end=9108 + _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_start=1681 + _globals['_LISTPROJECTSREQUEST_TAGSENTRY']._serialized_end=1724 + _globals['_LISTPROJECTSRESPONSE']._serialized_start=9110 + _globals['_LISTPROJECTSRESPONSE']._serialized_end=9227 + _globals['_DELETEPROJECTREQUEST']._serialized_start=9229 + _globals['_DELETEPROJECTREQUEST']._serialized_end=9281 + _globals['_ENTITYREFERENCE']._serialized_start=9283 + _globals['_ENTITYREFERENCE']._serialized_end=9328 + _globals['_ENTITYRELATION']._serialized_start=9330 + _globals['_ENTITYRELATION']._serialized_end=9444 + _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_start=9447 + _globals['_GETREGISTRYLINEAGEREQUEST']._serialized_end=9670 + _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_start=9673 + _globals['_GETREGISTRYLINEAGERESPONSE']._serialized_end=9969 + _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_start=9972 + _globals['_GETOBJECTRELATIONSHIPSREQUEST']._serialized_end=10211 + _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_start=10214 + _globals['_GETOBJECTRELATIONSHIPSRESPONSE']._serialized_end=10357 + _globals['_FEATURE']._serialized_start=10360 + _globals['_FEATURE']._serialized_end=10678 + _globals['_FEATURE_TAGSENTRY']._serialized_start=1681 + _globals['_FEATURE_TAGSENTRY']._serialized_end=1724 + _globals['_LISTFEATURESREQUEST']._serialized_start=10681 + _globals['_LISTFEATURESREQUEST']._serialized_end=10892 + _globals['_LISTFEATURESRESPONSE']._serialized_start=10894 + _globals['_LISTFEATURESRESPONSE']._serialized_end=11015 + _globals['_GETFEATUREREQUEST']._serialized_start=11017 + _globals['_GETFEATUREREQUEST']._serialized_end=11110 + _globals['_REGISTRYSERVER']._serialized_start=11113 + _globals['_REGISTRYSERVER']._serialized_end=15864 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi index a1f1b99365d..fb4153b73da 100644 --- a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi +++ b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2.pyi @@ -9,6 +9,7 @@ import feast.core.Entity_pb2 import feast.core.FeatureService_pb2 import feast.core.FeatureView_pb2 import feast.core.InfraObject_pb2 +import feast.core.LabelView_pb2 import feast.core.OnDemandFeatureView_pb2 import feast.core.Permission_pb2 import feast.core.Project_pb2 @@ -477,6 +478,7 @@ class ApplyFeatureViewRequest(google.protobuf.message.Message): FEATURE_VIEW_FIELD_NUMBER: builtins.int ON_DEMAND_FEATURE_VIEW_FIELD_NUMBER: builtins.int STREAM_FEATURE_VIEW_FIELD_NUMBER: builtins.int + LABEL_VIEW_FIELD_NUMBER: builtins.int PROJECT_FIELD_NUMBER: builtins.int COMMIT_FIELD_NUMBER: builtins.int @property @@ -485,6 +487,8 @@ class ApplyFeatureViewRequest(google.protobuf.message.Message): def on_demand_feature_view(self) -> feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView: ... @property def stream_feature_view(self) -> feast.core.StreamFeatureView_pb2.StreamFeatureView: ... + @property + def label_view(self) -> feast.core.LabelView_pb2.LabelView: ... project: builtins.str commit: builtins.bool def __init__( @@ -493,12 +497,13 @@ class ApplyFeatureViewRequest(google.protobuf.message.Message): feature_view: feast.core.FeatureView_pb2.FeatureView | None = ..., on_demand_feature_view: feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView | None = ..., stream_feature_view: feast.core.StreamFeatureView_pb2.StreamFeatureView | None = ..., + label_view: feast.core.LabelView_pb2.LabelView | None = ..., project: builtins.str = ..., commit: builtins.bool = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["base_feature_view", b"base_feature_view", "feature_view", b"feature_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["base_feature_view", b"base_feature_view", "commit", b"commit", "feature_view", b"feature_view", "on_demand_feature_view", b"on_demand_feature_view", "project", b"project", "stream_feature_view", b"stream_feature_view"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["base_feature_view", b"base_feature_view"]) -> typing_extensions.Literal["feature_view", "on_demand_feature_view", "stream_feature_view"] | None: ... + def HasField(self, field_name: typing_extensions.Literal["base_feature_view", b"base_feature_view", "feature_view", b"feature_view", "label_view", b"label_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["base_feature_view", b"base_feature_view", "commit", b"commit", "feature_view", b"feature_view", "label_view", b"label_view", "on_demand_feature_view", b"on_demand_feature_view", "project", b"project", "stream_feature_view", b"stream_feature_view"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["base_feature_view", b"base_feature_view"]) -> typing_extensions.Literal["feature_view", "on_demand_feature_view", "stream_feature_view", "label_view"] | None: ... global___ApplyFeatureViewRequest = ApplyFeatureViewRequest @@ -613,22 +618,26 @@ class AnyFeatureView(google.protobuf.message.Message): FEATURE_VIEW_FIELD_NUMBER: builtins.int ON_DEMAND_FEATURE_VIEW_FIELD_NUMBER: builtins.int STREAM_FEATURE_VIEW_FIELD_NUMBER: builtins.int + LABEL_VIEW_FIELD_NUMBER: builtins.int @property def feature_view(self) -> feast.core.FeatureView_pb2.FeatureView: ... @property def on_demand_feature_view(self) -> feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView: ... @property def stream_feature_view(self) -> feast.core.StreamFeatureView_pb2.StreamFeatureView: ... + @property + def label_view(self) -> feast.core.LabelView_pb2.LabelView: ... def __init__( self, *, feature_view: feast.core.FeatureView_pb2.FeatureView | None = ..., on_demand_feature_view: feast.core.OnDemandFeatureView_pb2.OnDemandFeatureView | None = ..., stream_feature_view: feast.core.StreamFeatureView_pb2.StreamFeatureView | None = ..., + label_view: feast.core.LabelView_pb2.LabelView | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["any_feature_view", b"any_feature_view", "feature_view", b"feature_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["any_feature_view", b"any_feature_view", "feature_view", b"feature_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["any_feature_view", b"any_feature_view"]) -> typing_extensions.Literal["feature_view", "on_demand_feature_view", "stream_feature_view"] | None: ... + def HasField(self, field_name: typing_extensions.Literal["any_feature_view", b"any_feature_view", "feature_view", b"feature_view", "label_view", b"label_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["any_feature_view", b"any_feature_view", "feature_view", b"feature_view", "label_view", b"label_view", "on_demand_feature_view", b"on_demand_feature_view", "stream_feature_view", b"stream_feature_view"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["any_feature_view", b"any_feature_view"]) -> typing_extensions.Literal["feature_view", "on_demand_feature_view", "stream_feature_view", "label_view"] | None: ... global___AnyFeatureView = AnyFeatureView @@ -919,6 +928,93 @@ class ListOnDemandFeatureViewsResponse(google.protobuf.message.Message): global___ListOnDemandFeatureViewsResponse = ListOnDemandFeatureViewsResponse +class GetLabelViewRequest(google.protobuf.message.Message): + """LabelViews""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + PROJECT_FIELD_NUMBER: builtins.int + ALLOW_CACHE_FIELD_NUMBER: builtins.int + name: builtins.str + project: builtins.str + allow_cache: builtins.bool + def __init__( + self, + *, + name: builtins.str = ..., + project: builtins.str = ..., + allow_cache: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "name", b"name", "project", b"project"]) -> None: ... + +global___GetLabelViewRequest = GetLabelViewRequest + +class ListLabelViewsRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class TagsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + + PROJECT_FIELD_NUMBER: builtins.int + ALLOW_CACHE_FIELD_NUMBER: builtins.int + TAGS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + SORTING_FIELD_NUMBER: builtins.int + project: builtins.str + allow_cache: builtins.bool + @property + def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + @property + def pagination(self) -> global___PaginationParams: ... + @property + def sorting(self) -> global___SortingParams: ... + def __init__( + self, + *, + project: builtins.str = ..., + allow_cache: builtins.bool = ..., + tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + pagination: global___PaginationParams | None = ..., + sorting: global___SortingParams | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "pagination", b"pagination", "project", b"project", "sorting", b"sorting", "tags", b"tags"]) -> None: ... + +global___ListLabelViewsRequest = ListLabelViewsRequest + +class ListLabelViewsResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LABEL_VIEWS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + @property + def label_views(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.LabelView_pb2.LabelView]: ... + @property + def pagination(self) -> global___PaginationMetadata: ... + def __init__( + self, + *, + label_views: collections.abc.Iterable[feast.core.LabelView_pb2.LabelView] | None = ..., + pagination: global___PaginationMetadata | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["label_views", b"label_views", "pagination", b"pagination"]) -> None: ... + +global___ListLabelViewsResponse = ListLabelViewsResponse + class ApplyFeatureServiceRequest(google.protobuf.message.Message): """FeatureServices""" @@ -1738,6 +1834,7 @@ class Feature(google.protobuf.message.Message): CREATED_TIMESTAMP_FIELD_NUMBER: builtins.int LAST_UPDATED_TIMESTAMP_FIELD_NUMBER: builtins.int TAGS_FIELD_NUMBER: builtins.int + KIND_FIELD_NUMBER: builtins.int name: builtins.str feature_view: builtins.str type: builtins.str @@ -1749,6 +1846,8 @@ class Feature(google.protobuf.message.Message): def last_updated_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: ... @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... + kind: builtins.str + """Semantic kind: "feature" (input/predictor) or "label" (target/annotation).""" def __init__( self, *, @@ -1760,9 +1859,10 @@ class Feature(google.protobuf.message.Message): created_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., last_updated_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + kind: builtins.str = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "last_updated_timestamp", b"last_updated_timestamp"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "description", b"description", "feature_view", b"feature_view", "last_updated_timestamp", b"last_updated_timestamp", "name", b"name", "owner", b"owner", "tags", b"tags", "type", b"type"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["created_timestamp", b"created_timestamp", "description", b"description", "feature_view", b"feature_view", "kind", b"kind", "last_updated_timestamp", b"last_updated_timestamp", "name", b"name", "owner", b"owner", "tags", b"tags", "type", b"type"]) -> None: ... global___Feature = Feature @@ -1775,6 +1875,7 @@ class ListFeaturesRequest(google.protobuf.message.Message): ALLOW_CACHE_FIELD_NUMBER: builtins.int PAGINATION_FIELD_NUMBER: builtins.int SORTING_FIELD_NUMBER: builtins.int + KIND_FIELD_NUMBER: builtins.int project: builtins.str feature_view: builtins.str name: builtins.str @@ -1783,6 +1884,8 @@ class ListFeaturesRequest(google.protobuf.message.Message): def pagination(self) -> global___PaginationParams: ... @property def sorting(self) -> global___SortingParams: ... + kind: builtins.str + """Filter by kind: "feature" or "label". Empty means no filter.""" def __init__( self, *, @@ -1792,9 +1895,10 @@ class ListFeaturesRequest(google.protobuf.message.Message): allow_cache: builtins.bool = ..., pagination: global___PaginationParams | None = ..., sorting: global___SortingParams | None = ..., + kind: builtins.str = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["pagination", b"pagination", "sorting", b"sorting"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "feature_view", b"feature_view", "name", b"name", "pagination", b"pagination", "project", b"project", "sorting", b"sorting"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_cache", b"allow_cache", "feature_view", b"feature_view", "kind", b"kind", "name", b"name", "pagination", b"pagination", "project", b"project", "sorting", b"sorting"]) -> None: ... global___ListFeaturesRequest = ListFeaturesRequest diff --git a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2_grpc.py b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2_grpc.py index 84de666b6b1..fe66751e1d1 100644 --- a/sdk/python/feast/protos/feast/registry/RegistryServer_pb2_grpc.py +++ b/sdk/python/feast/protos/feast/registry/RegistryServer_pb2_grpc.py @@ -7,6 +7,7 @@ from feast.protos.feast.core import FeatureService_pb2 as feast_dot_core_dot_FeatureService__pb2 from feast.protos.feast.core import FeatureView_pb2 as feast_dot_core_dot_FeatureView__pb2 from feast.protos.feast.core import InfraObject_pb2 as feast_dot_core_dot_InfraObject__pb2 +from feast.protos.feast.core import LabelView_pb2 as feast_dot_core_dot_LabelView__pb2 from feast.protos.feast.core import OnDemandFeatureView_pb2 as feast_dot_core_dot_OnDemandFeatureView__pb2 from feast.protos.feast.core import Permission_pb2 as feast_dot_core_dot_Permission__pb2 from feast.protos.feast.core import Project_pb2 as feast_dot_core_dot_Project__pb2 @@ -117,6 +118,16 @@ def __init__(self, channel): request_serializer=feast_dot_registry_dot_RegistryServer__pb2.ListOnDemandFeatureViewsRequest.SerializeToString, response_deserializer=feast_dot_registry_dot_RegistryServer__pb2.ListOnDemandFeatureViewsResponse.FromString, ) + self.GetLabelView = channel.unary_unary( + '/feast.registry.RegistryServer/GetLabelView', + request_serializer=feast_dot_registry_dot_RegistryServer__pb2.GetLabelViewRequest.SerializeToString, + response_deserializer=feast_dot_core_dot_LabelView__pb2.LabelView.FromString, + ) + self.ListLabelViews = channel.unary_unary( + '/feast.registry.RegistryServer/ListLabelViews', + request_serializer=feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsRequest.SerializeToString, + response_deserializer=feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsResponse.FromString, + ) self.ApplyFeatureService = channel.unary_unary( '/feast.registry.RegistryServer/ApplyFeatureService', request_serializer=feast_dot_registry_dot_RegistryServer__pb2.ApplyFeatureServiceRequest.SerializeToString, @@ -391,6 +402,19 @@ def ListOnDemandFeatureViews(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def GetLabelView(self, request, context): + """LabelView RPCs + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListLabelViews(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def ApplyFeatureService(self, request, context): """FeatureService RPCs """ @@ -677,6 +701,16 @@ def add_RegistryServerServicer_to_server(servicer, server): request_deserializer=feast_dot_registry_dot_RegistryServer__pb2.ListOnDemandFeatureViewsRequest.FromString, response_serializer=feast_dot_registry_dot_RegistryServer__pb2.ListOnDemandFeatureViewsResponse.SerializeToString, ), + 'GetLabelView': grpc.unary_unary_rpc_method_handler( + servicer.GetLabelView, + request_deserializer=feast_dot_registry_dot_RegistryServer__pb2.GetLabelViewRequest.FromString, + response_serializer=feast_dot_core_dot_LabelView__pb2.LabelView.SerializeToString, + ), + 'ListLabelViews': grpc.unary_unary_rpc_method_handler( + servicer.ListLabelViews, + request_deserializer=feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsRequest.FromString, + response_serializer=feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsResponse.SerializeToString, + ), 'ApplyFeatureService': grpc.unary_unary_rpc_method_handler( servicer.ApplyFeatureService, request_deserializer=feast_dot_registry_dot_RegistryServer__pb2.ApplyFeatureServiceRequest.FromString, @@ -1148,6 +1182,40 @@ def ListOnDemandFeatureViews(request, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + @staticmethod + def GetLabelView(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/feast.registry.RegistryServer/GetLabelView', + feast_dot_registry_dot_RegistryServer__pb2.GetLabelViewRequest.SerializeToString, + feast_dot_core_dot_LabelView__pb2.LabelView.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListLabelViews(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/feast.registry.RegistryServer/ListLabelViews', + feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsRequest.SerializeToString, + feast_dot_registry_dot_RegistryServer__pb2.ListLabelViewsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + @staticmethod def ApplyFeatureService(request, target, diff --git a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.py b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.py index dcf91563185..586938289ae 100644 --- a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.py +++ b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.py @@ -13,9 +13,10 @@ from feast.protos.feast.serving import ServingService_pb2 as feast_dot_serving_dot_ServingService__pb2 +from feast.protos.feast.types import Value_pb2 as feast_dot_types_dot_Value__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x66\x65\x61st/serving/GrpcServer.proto\x1a\"feast/serving/ServingService.proto\"\xb3\x01\n\x0bPushRequest\x12,\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32\x1a.PushRequest.FeaturesEntry\x12\x1b\n\x13stream_feature_view\x18\x02 \x01(\t\x12\x1c\n\x14\x61llow_registry_cache\x18\x03 \x01(\x08\x12\n\n\x02to\x18\x04 \x01(\t\x1a/\n\rFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x1e\n\x0cPushResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\xc1\x01\n\x19WriteToOnlineStoreRequest\x12:\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32(.WriteToOnlineStoreRequest.FeaturesEntry\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x02 \x01(\t\x12\x1c\n\x14\x61llow_registry_cache\x18\x03 \x01(\x08\x1a/\n\rFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\",\n\x1aWriteToOnlineStoreResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\x32\xf1\x01\n\x11GrpcFeatureServer\x12%\n\x04Push\x12\x0c.PushRequest\x1a\r.PushResponse\"\x00\x12M\n\x12WriteToOnlineStore\x12\x1a.WriteToOnlineStoreRequest\x1a\x1b.WriteToOnlineStoreResponse\x12\x66\n\x11GetOnlineFeatures\x12\'.feast.serving.GetOnlineFeaturesRequest\x1a(.feast.serving.GetOnlineFeaturesResponseB]\n\x13\x66\x65\x61st.proto.servingB\x12GrpcServerAPIProtoZ2github.com/feast-dev/feast/go/protos/feast/servingb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x66\x65\x61st/serving/GrpcServer.proto\x1a\"feast/serving/ServingService.proto\x1a\x17\x66\x65\x61st/types/Value.proto\"\xb6\x02\n\x0bPushRequest\x12,\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32\x1a.PushRequest.FeaturesEntry\x12\x1b\n\x13stream_feature_view\x18\x02 \x01(\t\x12\x1c\n\x14\x61llow_registry_cache\x18\x03 \x01(\x08\x12\n\n\x02to\x18\x04 \x01(\t\x12\x37\n\x0etyped_features\x18\x05 \x03(\x0b\x32\x1f.PushRequest.TypedFeaturesEntry\x1a/\n\rFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aH\n\x12TypedFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\"\x1e\n\x0cPushResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\xd2\x02\n\x19WriteToOnlineStoreRequest\x12:\n\x08\x66\x65\x61tures\x18\x01 \x03(\x0b\x32(.WriteToOnlineStoreRequest.FeaturesEntry\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x02 \x01(\t\x12\x1c\n\x14\x61llow_registry_cache\x18\x03 \x01(\x08\x12\x45\n\x0etyped_features\x18\x04 \x03(\x0b\x32-.WriteToOnlineStoreRequest.TypedFeaturesEntry\x1a/\n\rFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aH\n\x12TypedFeaturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\",\n\x1aWriteToOnlineStoreResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\x32\xf1\x01\n\x11GrpcFeatureServer\x12%\n\x04Push\x12\x0c.PushRequest\x1a\r.PushResponse\"\x00\x12M\n\x12WriteToOnlineStore\x12\x1a.WriteToOnlineStoreRequest\x1a\x1b.WriteToOnlineStoreResponse\x12\x66\n\x11GetOnlineFeatures\x12\'.feast.serving.GetOnlineFeaturesRequest\x1a(.feast.serving.GetOnlineFeaturesResponseB]\n\x13\x66\x65\x61st.proto.servingB\x12GrpcServerAPIProtoZ2github.com/feast-dev/feast/go/protos/feast/servingb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -25,20 +26,28 @@ _globals['DESCRIPTOR']._serialized_options = b'\n\023feast.proto.servingB\022GrpcServerAPIProtoZ2github.com/feast-dev/feast/go/protos/feast/serving' _globals['_PUSHREQUEST_FEATURESENTRY']._options = None _globals['_PUSHREQUEST_FEATURESENTRY']._serialized_options = b'8\001' + _globals['_PUSHREQUEST_TYPEDFEATURESENTRY']._options = None + _globals['_PUSHREQUEST_TYPEDFEATURESENTRY']._serialized_options = b'8\001' _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._options = None _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._serialized_options = b'8\001' - _globals['_PUSHREQUEST']._serialized_start=71 - _globals['_PUSHREQUEST']._serialized_end=250 - _globals['_PUSHREQUEST_FEATURESENTRY']._serialized_start=203 - _globals['_PUSHREQUEST_FEATURESENTRY']._serialized_end=250 - _globals['_PUSHRESPONSE']._serialized_start=252 - _globals['_PUSHRESPONSE']._serialized_end=282 - _globals['_WRITETOONLINESTOREREQUEST']._serialized_start=285 - _globals['_WRITETOONLINESTOREREQUEST']._serialized_end=478 - _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._serialized_start=203 - _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._serialized_end=250 - _globals['_WRITETOONLINESTORERESPONSE']._serialized_start=480 - _globals['_WRITETOONLINESTORERESPONSE']._serialized_end=524 - _globals['_GRPCFEATURESERVER']._serialized_start=527 - _globals['_GRPCFEATURESERVER']._serialized_end=768 + _globals['_WRITETOONLINESTOREREQUEST_TYPEDFEATURESENTRY']._options = None + _globals['_WRITETOONLINESTOREREQUEST_TYPEDFEATURESENTRY']._serialized_options = b'8\001' + _globals['_PUSHREQUEST']._serialized_start=96 + _globals['_PUSHREQUEST']._serialized_end=406 + _globals['_PUSHREQUEST_FEATURESENTRY']._serialized_start=285 + _globals['_PUSHREQUEST_FEATURESENTRY']._serialized_end=332 + _globals['_PUSHREQUEST_TYPEDFEATURESENTRY']._serialized_start=334 + _globals['_PUSHREQUEST_TYPEDFEATURESENTRY']._serialized_end=406 + _globals['_PUSHRESPONSE']._serialized_start=408 + _globals['_PUSHRESPONSE']._serialized_end=438 + _globals['_WRITETOONLINESTOREREQUEST']._serialized_start=441 + _globals['_WRITETOONLINESTOREREQUEST']._serialized_end=779 + _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._serialized_start=285 + _globals['_WRITETOONLINESTOREREQUEST_FEATURESENTRY']._serialized_end=332 + _globals['_WRITETOONLINESTOREREQUEST_TYPEDFEATURESENTRY']._serialized_start=334 + _globals['_WRITETOONLINESTOREREQUEST_TYPEDFEATURESENTRY']._serialized_end=406 + _globals['_WRITETOONLINESTORERESPONSE']._serialized_start=781 + _globals['_WRITETOONLINESTORERESPONSE']._serialized_end=825 + _globals['_GRPCFEATURESERVER']._serialized_start=828 + _globals['_GRPCFEATURESERVER']._serialized_end=1069 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi index 54964f46e58..a83cd87a16e 100644 --- a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi +++ b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi @@ -4,6 +4,7 @@ isort:skip_file """ import builtins import collections.abc +import feast.types.Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -34,15 +35,35 @@ class PushRequest(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + class TypedFeaturesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> feast.types.Value_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: feast.types.Value_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + FEATURES_FIELD_NUMBER: builtins.int STREAM_FEATURE_VIEW_FIELD_NUMBER: builtins.int ALLOW_REGISTRY_CACHE_FIELD_NUMBER: builtins.int TO_FIELD_NUMBER: builtins.int + TYPED_FEATURES_FIELD_NUMBER: builtins.int @property def features(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... stream_feature_view: builtins.str allow_registry_cache: builtins.bool to: builtins.str + @property + def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.Value]: ... def __init__( self, *, @@ -50,8 +71,9 @@ class PushRequest(google.protobuf.message.Message): stream_feature_view: builtins.str = ..., allow_registry_cache: builtins.bool = ..., to: builtins.str = ..., + typed_features: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.Value] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "features", b"features", "stream_feature_view", b"stream_feature_view", "to", b"to"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "features", b"features", "stream_feature_view", b"stream_feature_view", "to", b"to", "typed_features", b"typed_features"]) -> None: ... global___PushRequest = PushRequest @@ -87,21 +109,42 @@ class WriteToOnlineStoreRequest(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + class TypedFeaturesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> feast.types.Value_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: feast.types.Value_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + FEATURES_FIELD_NUMBER: builtins.int FEATURE_VIEW_NAME_FIELD_NUMBER: builtins.int ALLOW_REGISTRY_CACHE_FIELD_NUMBER: builtins.int + TYPED_FEATURES_FIELD_NUMBER: builtins.int @property def features(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ... feature_view_name: builtins.str allow_registry_cache: builtins.bool + @property + def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.Value]: ... def __init__( self, *, features: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., feature_view_name: builtins.str = ..., allow_registry_cache: builtins.bool = ..., + typed_features: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.Value] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "feature_view_name", b"feature_view_name", "features", b"features"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "feature_view_name", b"feature_view_name", "features", b"features", "typed_features", b"typed_features"]) -> None: ... global___WriteToOnlineStoreRequest = WriteToOnlineStoreRequest diff --git a/sdk/python/feast/protos/feast/serving/ServingService_pb2.py b/sdk/python/feast/protos/feast/serving/ServingService_pb2.py index fa866640577..82ade7eb988 100644 --- a/sdk/python/feast/protos/feast/serving/ServingService_pb2.py +++ b/sdk/python/feast/protos/feast/serving/ServingService_pb2.py @@ -16,7 +16,7 @@ from feast.protos.feast.types import Value_pb2 as feast_dot_types_dot_Value__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"feast/serving/ServingService.proto\x12\rfeast.serving\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17\x66\x65\x61st/types/Value.proto\"\x1c\n\x1aGetFeastServingInfoRequest\".\n\x1bGetFeastServingInfoResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"E\n\x12\x46\x65\x61tureReferenceV2\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_name\x18\x02 \x01(\t\"\xfd\x02\n\x1aGetOnlineFeaturesRequestV2\x12\x33\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32!.feast.serving.FeatureReferenceV2\x12H\n\x0b\x65ntity_rows\x18\x02 \x03(\x0b\x32\x33.feast.serving.GetOnlineFeaturesRequestV2.EntityRow\x12\x0f\n\x07project\x18\x05 \x01(\t\x1a\xce\x01\n\tEntityRow\x12-\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12O\n\x06\x66ields\x18\x02 \x03(\x0b\x32?.feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry\x1a\x41\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\"\x1a\n\x0b\x46\x65\x61tureList\x12\x0b\n\x03val\x18\x01 \x03(\t\"\xc8\x03\n\x18GetOnlineFeaturesRequest\x12\x19\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\tH\x00\x12.\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1a.feast.serving.FeatureListH\x00\x12G\n\x08\x65ntities\x18\x03 \x03(\x0b\x32\x35.feast.serving.GetOnlineFeaturesRequest.EntitiesEntry\x12\x1a\n\x12\x66ull_feature_names\x18\x04 \x01(\x08\x12T\n\x0frequest_context\x18\x05 \x03(\x0b\x32;.feast.serving.GetOnlineFeaturesRequest.RequestContextEntry\x1aK\n\rEntitiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.types.RepeatedValue:\x02\x38\x01\x1aQ\n\x13RequestContextEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.types.RepeatedValue:\x02\x38\x01\x42\x06\n\x04kind\"\xd2\x02\n\x19GetOnlineFeaturesResponse\x12\x42\n\x08metadata\x18\x01 \x01(\x0b\x32\x30.feast.serving.GetOnlineFeaturesResponseMetadata\x12G\n\x07results\x18\x02 \x03(\x0b\x32\x36.feast.serving.GetOnlineFeaturesResponse.FeatureVector\x12\x0e\n\x06status\x18\x03 \x01(\x08\x1a\x97\x01\n\rFeatureVector\x12\"\n\x06values\x18\x01 \x03(\x0b\x32\x12.feast.types.Value\x12,\n\x08statuses\x18\x02 \x03(\x0e\x32\x1a.feast.serving.FieldStatus\x12\x34\n\x10\x65vent_timestamps\x18\x03 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\"V\n!GetOnlineFeaturesResponseMetadata\x12\x31\n\rfeature_names\x18\x01 \x01(\x0b\x32\x1a.feast.serving.FeatureList*[\n\x0b\x46ieldStatus\x12\x0b\n\x07INVALID\x10\x00\x12\x0b\n\x07PRESENT\x10\x01\x12\x0e\n\nNULL_VALUE\x10\x02\x12\r\n\tNOT_FOUND\x10\x03\x12\x13\n\x0fOUTSIDE_MAX_AGE\x10\x04\x32\xe6\x01\n\x0eServingService\x12l\n\x13GetFeastServingInfo\x12).feast.serving.GetFeastServingInfoRequest\x1a*.feast.serving.GetFeastServingInfoResponse\x12\x66\n\x11GetOnlineFeatures\x12\'.feast.serving.GetOnlineFeaturesRequest\x1a(.feast.serving.GetOnlineFeaturesResponseBZ\n\x13\x66\x65\x61st.proto.servingB\x0fServingAPIProtoZ2github.com/feast-dev/feast/go/protos/feast/servingb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"feast/serving/ServingService.proto\x12\rfeast.serving\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17\x66\x65\x61st/types/Value.proto\"\x1c\n\x1aGetFeastServingInfoRequest\".\n\x1bGetFeastServingInfoResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"E\n\x12\x46\x65\x61tureReferenceV2\x12\x19\n\x11\x66\x65\x61ture_view_name\x18\x01 \x01(\t\x12\x14\n\x0c\x66\x65\x61ture_name\x18\x02 \x01(\t\"\xfd\x02\n\x1aGetOnlineFeaturesRequestV2\x12\x33\n\x08\x66\x65\x61tures\x18\x04 \x03(\x0b\x32!.feast.serving.FeatureReferenceV2\x12H\n\x0b\x65ntity_rows\x18\x02 \x03(\x0b\x32\x33.feast.serving.GetOnlineFeaturesRequestV2.EntityRow\x12\x0f\n\x07project\x18\x05 \x01(\t\x1a\xce\x01\n\tEntityRow\x12-\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12O\n\x06\x66ields\x18\x02 \x03(\x0b\x32?.feast.serving.GetOnlineFeaturesRequestV2.EntityRow.FieldsEntry\x1a\x41\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\"\x1a\n\x0b\x46\x65\x61tureList\x12\x0b\n\x03val\x18\x01 \x03(\t\"\xf7\x03\n\x18GetOnlineFeaturesRequest\x12\x19\n\x0f\x66\x65\x61ture_service\x18\x01 \x01(\tH\x00\x12.\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1a.feast.serving.FeatureListH\x00\x12G\n\x08\x65ntities\x18\x03 \x03(\x0b\x32\x35.feast.serving.GetOnlineFeaturesRequest.EntitiesEntry\x12\x1a\n\x12\x66ull_feature_names\x18\x04 \x01(\x08\x12T\n\x0frequest_context\x18\x05 \x03(\x0b\x32;.feast.serving.GetOnlineFeaturesRequest.RequestContextEntry\x12-\n%include_feature_view_version_metadata\x18\x06 \x01(\x08\x1aK\n\rEntitiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.types.RepeatedValue:\x02\x38\x01\x1aQ\n\x13RequestContextEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.feast.types.RepeatedValue:\x02\x38\x01\x42\x06\n\x04kind\"\xd2\x02\n\x19GetOnlineFeaturesResponse\x12\x42\n\x08metadata\x18\x01 \x01(\x0b\x32\x30.feast.serving.GetOnlineFeaturesResponseMetadata\x12G\n\x07results\x18\x02 \x03(\x0b\x32\x36.feast.serving.GetOnlineFeaturesResponse.FeatureVector\x12\x0e\n\x06status\x18\x03 \x01(\x08\x1a\x97\x01\n\rFeatureVector\x12\"\n\x06values\x18\x01 \x03(\x0b\x32\x12.feast.types.Value\x12,\n\x08statuses\x18\x02 \x03(\x0e\x32\x1a.feast.serving.FieldStatus\x12\x34\n\x10\x65vent_timestamps\x18\x03 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\"4\n\x13\x46\x65\x61tureViewMetadata\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x05\"\x99\x01\n!GetOnlineFeaturesResponseMetadata\x12\x31\n\rfeature_names\x18\x01 \x01(\x0b\x32\x1a.feast.serving.FeatureList\x12\x41\n\x15\x66\x65\x61ture_view_metadata\x18\x02 \x03(\x0b\x32\".feast.serving.FeatureViewMetadata*[\n\x0b\x46ieldStatus\x12\x0b\n\x07INVALID\x10\x00\x12\x0b\n\x07PRESENT\x10\x01\x12\x0e\n\nNULL_VALUE\x10\x02\x12\r\n\tNOT_FOUND\x10\x03\x12\x13\n\x0fOUTSIDE_MAX_AGE\x10\x04\x32\xe6\x01\n\x0eServingService\x12l\n\x13GetFeastServingInfo\x12).feast.serving.GetFeastServingInfoRequest\x1a*.feast.serving.GetFeastServingInfoResponse\x12\x66\n\x11GetOnlineFeatures\x12\'.feast.serving.GetOnlineFeaturesRequest\x1a(.feast.serving.GetOnlineFeaturesResponseBZ\n\x13\x66\x65\x61st.proto.servingB\x0fServingAPIProtoZ2github.com/feast-dev/feast/go/protos/feast/servingb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -30,8 +30,8 @@ _globals['_GETONLINEFEATURESREQUEST_ENTITIESENTRY']._serialized_options = b'8\001' _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._options = None _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._serialized_options = b'8\001' - _globals['_FIELDSTATUS']._serialized_start=1560 - _globals['_FIELDSTATUS']._serialized_end=1651 + _globals['_FIELDSTATUS']._serialized_start=1729 + _globals['_FIELDSTATUS']._serialized_end=1820 _globals['_GETFEASTSERVINGINFOREQUEST']._serialized_start=111 _globals['_GETFEASTSERVINGINFOREQUEST']._serialized_end=139 _globals['_GETFEASTSERVINGINFORESPONSE']._serialized_start=141 @@ -47,17 +47,19 @@ _globals['_FEATURELIST']._serialized_start=644 _globals['_FEATURELIST']._serialized_end=670 _globals['_GETONLINEFEATURESREQUEST']._serialized_start=673 - _globals['_GETONLINEFEATURESREQUEST']._serialized_end=1129 - _globals['_GETONLINEFEATURESREQUEST_ENTITIESENTRY']._serialized_start=963 - _globals['_GETONLINEFEATURESREQUEST_ENTITIESENTRY']._serialized_end=1038 - _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._serialized_start=1040 - _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._serialized_end=1121 - _globals['_GETONLINEFEATURESRESPONSE']._serialized_start=1132 - _globals['_GETONLINEFEATURESRESPONSE']._serialized_end=1470 - _globals['_GETONLINEFEATURESRESPONSE_FEATUREVECTOR']._serialized_start=1319 - _globals['_GETONLINEFEATURESRESPONSE_FEATUREVECTOR']._serialized_end=1470 - _globals['_GETONLINEFEATURESRESPONSEMETADATA']._serialized_start=1472 - _globals['_GETONLINEFEATURESRESPONSEMETADATA']._serialized_end=1558 - _globals['_SERVINGSERVICE']._serialized_start=1654 - _globals['_SERVINGSERVICE']._serialized_end=1884 + _globals['_GETONLINEFEATURESREQUEST']._serialized_end=1176 + _globals['_GETONLINEFEATURESREQUEST_ENTITIESENTRY']._serialized_start=1010 + _globals['_GETONLINEFEATURESREQUEST_ENTITIESENTRY']._serialized_end=1085 + _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._serialized_start=1087 + _globals['_GETONLINEFEATURESREQUEST_REQUESTCONTEXTENTRY']._serialized_end=1168 + _globals['_GETONLINEFEATURESRESPONSE']._serialized_start=1179 + _globals['_GETONLINEFEATURESRESPONSE']._serialized_end=1517 + _globals['_GETONLINEFEATURESRESPONSE_FEATUREVECTOR']._serialized_start=1366 + _globals['_GETONLINEFEATURESRESPONSE_FEATUREVECTOR']._serialized_end=1517 + _globals['_FEATUREVIEWMETADATA']._serialized_start=1519 + _globals['_FEATUREVIEWMETADATA']._serialized_end=1571 + _globals['_GETONLINEFEATURESRESPONSEMETADATA']._serialized_start=1574 + _globals['_GETONLINEFEATURESRESPONSEMETADATA']._serialized_end=1727 + _globals['_SERVINGSERVICE']._serialized_start=1823 + _globals['_SERVINGSERVICE']._serialized_end=2053 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi b/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi index 3c5e57ae45a..1804ce0428e 100644 --- a/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi +++ b/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi @@ -253,6 +253,7 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): ENTITIES_FIELD_NUMBER: builtins.int FULL_FEATURE_NAMES_FIELD_NUMBER: builtins.int REQUEST_CONTEXT_FIELD_NUMBER: builtins.int + INCLUDE_FEATURE_VIEW_VERSION_METADATA_FIELD_NUMBER: builtins.int feature_service: builtins.str @property def features(self) -> global___FeatureList: ... @@ -268,6 +269,8 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): (was moved to dedicated parameter to avoid unnecessary separation logic on serving side) A map of variable name -> list of values """ + include_feature_view_version_metadata: builtins.bool + """Whether to include feature view version metadata in the response""" def __init__( self, *, @@ -276,9 +279,10 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): entities: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.RepeatedValue] | None = ..., full_feature_names: builtins.bool = ..., request_context: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.RepeatedValue] | None = ..., + include_feature_view_version_metadata: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["feature_service", b"feature_service", "features", b"features", "kind", b"kind"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["entities", b"entities", "feature_service", b"feature_service", "features", b"features", "full_feature_names", b"full_feature_names", "kind", b"kind", "request_context", b"request_context"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["entities", b"entities", "feature_service", b"feature_service", "features", b"features", "full_feature_names", b"full_feature_names", "include_feature_view_version_metadata", b"include_feature_view_version_metadata", "kind", b"kind", "request_context", b"request_context"]) -> None: ... def WhichOneof(self, oneof_group: typing_extensions.Literal["kind", b"kind"]) -> typing_extensions.Literal["feature_service", "features"] | None: ... global___GetOnlineFeaturesRequest = GetOnlineFeaturesRequest @@ -330,18 +334,43 @@ class GetOnlineFeaturesResponse(google.protobuf.message.Message): global___GetOnlineFeaturesResponse = GetOnlineFeaturesResponse +class FeatureViewMetadata(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + name: builtins.str + """Feature view name (e.g., "driver_stats")""" + version: builtins.int + """Version number (e.g., 2)""" + def __init__( + self, + *, + name: builtins.str = ..., + version: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["name", b"name", "version", b"version"]) -> None: ... + +global___FeatureViewMetadata = FeatureViewMetadata + class GetOnlineFeaturesResponseMetadata(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FEATURE_NAMES_FIELD_NUMBER: builtins.int + FEATURE_VIEW_METADATA_FIELD_NUMBER: builtins.int + @property + def feature_names(self) -> global___FeatureList: + """Clean feature names without @v2 syntax""" @property - def feature_names(self) -> global___FeatureList: ... + def feature_view_metadata(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FeatureViewMetadata]: + """Only populated when requested""" def __init__( self, *, feature_names: global___FeatureList | None = ..., + feature_view_metadata: collections.abc.Iterable[global___FeatureViewMetadata] | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["feature_names", b"feature_names"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["feature_names", b"feature_names"]) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["feature_names", b"feature_names", "feature_view_metadata", b"feature_view_metadata"]) -> None: ... global___GetOnlineFeaturesResponseMetadata = GetOnlineFeaturesResponseMetadata diff --git a/sdk/python/feast/protos/feast/types/Value_pb2.py b/sdk/python/feast/protos/feast/types/Value_pb2.py index 5edd8c5bde9..96d93ceef56 100644 --- a/sdk/python/feast/protos/feast/types/Value_pb2.py +++ b/sdk/python/feast/protos/feast/types/Value_pb2.py @@ -14,7 +14,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66\x65\x61st/types/Value.proto\x12\x0b\x66\x65\x61st.types\"\xe6\x03\n\tValueType\"\xd8\x03\n\x04\x45num\x12\x0b\n\x07INVALID\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\n\n\x06STRING\x10\x02\x12\t\n\x05INT32\x10\x03\x12\t\n\x05INT64\x10\x04\x12\n\n\x06\x44OUBLE\x10\x05\x12\t\n\x05\x46LOAT\x10\x06\x12\x08\n\x04\x42OOL\x10\x07\x12\x12\n\x0eUNIX_TIMESTAMP\x10\x08\x12\x0e\n\nBYTES_LIST\x10\x0b\x12\x0f\n\x0bSTRING_LIST\x10\x0c\x12\x0e\n\nINT32_LIST\x10\r\x12\x0e\n\nINT64_LIST\x10\x0e\x12\x0f\n\x0b\x44OUBLE_LIST\x10\x0f\x12\x0e\n\nFLOAT_LIST\x10\x10\x12\r\n\tBOOL_LIST\x10\x11\x12\x17\n\x13UNIX_TIMESTAMP_LIST\x10\x12\x12\x08\n\x04NULL\x10\x13\x12\x07\n\x03MAP\x10\x14\x12\x0c\n\x08MAP_LIST\x10\x15\x12\r\n\tBYTES_SET\x10\x16\x12\x0e\n\nSTRING_SET\x10\x17\x12\r\n\tINT32_SET\x10\x18\x12\r\n\tINT64_SET\x10\x19\x12\x0e\n\nDOUBLE_SET\x10\x1a\x12\r\n\tFLOAT_SET\x10\x1b\x12\x0c\n\x08\x42OOL_SET\x10\x1c\x12\x16\n\x12UNIX_TIMESTAMP_SET\x10\x1d\x12\x08\n\x04JSON\x10 \x12\r\n\tJSON_LIST\x10!\x12\n\n\x06STRUCT\x10\"\x12\x0f\n\x0bSTRUCT_LIST\x10#\"\xff\t\n\x05Value\x12\x13\n\tbytes_val\x18\x01 \x01(\x0cH\x00\x12\x14\n\nstring_val\x18\x02 \x01(\tH\x00\x12\x13\n\tint32_val\x18\x03 \x01(\x05H\x00\x12\x13\n\tint64_val\x18\x04 \x01(\x03H\x00\x12\x14\n\ndouble_val\x18\x05 \x01(\x01H\x00\x12\x13\n\tfloat_val\x18\x06 \x01(\x02H\x00\x12\x12\n\x08\x62ool_val\x18\x07 \x01(\x08H\x00\x12\x1c\n\x12unix_timestamp_val\x18\x08 \x01(\x03H\x00\x12\x30\n\x0e\x62ytes_list_val\x18\x0b \x01(\x0b\x32\x16.feast.types.BytesListH\x00\x12\x32\n\x0fstring_list_val\x18\x0c \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12\x30\n\x0eint32_list_val\x18\r \x01(\x0b\x32\x16.feast.types.Int32ListH\x00\x12\x30\n\x0eint64_list_val\x18\x0e \x01(\x0b\x32\x16.feast.types.Int64ListH\x00\x12\x32\n\x0f\x64ouble_list_val\x18\x0f \x01(\x0b\x32\x17.feast.types.DoubleListH\x00\x12\x30\n\x0e\x66loat_list_val\x18\x10 \x01(\x0b\x32\x16.feast.types.FloatListH\x00\x12.\n\rbool_list_val\x18\x11 \x01(\x0b\x32\x15.feast.types.BoolListH\x00\x12\x39\n\x17unix_timestamp_list_val\x18\x12 \x01(\x0b\x32\x16.feast.types.Int64ListH\x00\x12%\n\x08null_val\x18\x13 \x01(\x0e\x32\x11.feast.types.NullH\x00\x12#\n\x07map_val\x18\x14 \x01(\x0b\x32\x10.feast.types.MapH\x00\x12,\n\x0cmap_list_val\x18\x15 \x01(\x0b\x32\x14.feast.types.MapListH\x00\x12.\n\rbytes_set_val\x18\x16 \x01(\x0b\x32\x15.feast.types.BytesSetH\x00\x12\x30\n\x0estring_set_val\x18\x17 \x01(\x0b\x32\x16.feast.types.StringSetH\x00\x12.\n\rint32_set_val\x18\x18 \x01(\x0b\x32\x15.feast.types.Int32SetH\x00\x12.\n\rint64_set_val\x18\x19 \x01(\x0b\x32\x15.feast.types.Int64SetH\x00\x12\x30\n\x0e\x64ouble_set_val\x18\x1a \x01(\x0b\x32\x16.feast.types.DoubleSetH\x00\x12.\n\rfloat_set_val\x18\x1b \x01(\x0b\x32\x15.feast.types.FloatSetH\x00\x12,\n\x0c\x62ool_set_val\x18\x1c \x01(\x0b\x32\x14.feast.types.BoolSetH\x00\x12\x37\n\x16unix_timestamp_set_val\x18\x1d \x01(\x0b\x32\x15.feast.types.Int64SetH\x00\x12\x12\n\x08json_val\x18 \x01(\tH\x00\x12\x30\n\rjson_list_val\x18! \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12&\n\nstruct_val\x18\" \x01(\x0b\x32\x10.feast.types.MapH\x00\x12/\n\x0fstruct_list_val\x18# \x01(\x0b\x32\x14.feast.types.MapListH\x00\x42\x05\n\x03val\"\x18\n\tBytesList\x12\x0b\n\x03val\x18\x01 \x03(\x0c\"\x19\n\nStringList\x12\x0b\n\x03val\x18\x01 \x03(\t\"\x18\n\tInt32List\x12\x0b\n\x03val\x18\x01 \x03(\x05\"\x18\n\tInt64List\x12\x0b\n\x03val\x18\x01 \x03(\x03\"\x19\n\nDoubleList\x12\x0b\n\x03val\x18\x01 \x03(\x01\"\x18\n\tFloatList\x12\x0b\n\x03val\x18\x01 \x03(\x02\"\x17\n\x08\x42oolList\x12\x0b\n\x03val\x18\x01 \x03(\x08\"\x17\n\x08\x42ytesSet\x12\x0b\n\x03val\x18\x01 \x03(\x0c\"\x18\n\tStringSet\x12\x0b\n\x03val\x18\x01 \x03(\t\"\x17\n\x08Int32Set\x12\x0b\n\x03val\x18\x01 \x03(\x05\"\x17\n\x08Int64Set\x12\x0b\n\x03val\x18\x01 \x03(\x03\"\x18\n\tDoubleSet\x12\x0b\n\x03val\x18\x01 \x03(\x01\"\x17\n\x08\x46loatSet\x12\x0b\n\x03val\x18\x01 \x03(\x02\"\x16\n\x07\x42oolSet\x12\x0b\n\x03val\x18\x01 \x03(\x08\"m\n\x03Map\x12&\n\x03val\x18\x01 \x03(\x0b\x32\x19.feast.types.Map.ValEntry\x1a>\n\x08ValEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\"(\n\x07MapList\x12\x1d\n\x03val\x18\x01 \x03(\x0b\x32\x10.feast.types.Map\"0\n\rRepeatedValue\x12\x1f\n\x03val\x18\x01 \x03(\x0b\x32\x12.feast.types.Value*\x10\n\x04Null\x12\x08\n\x04NULL\x10\x00\x42Q\n\x11\x66\x65\x61st.proto.typesB\nValueProtoZ0github.com/feast-dev/feast/go/protos/feast/typesb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66\x65\x61st/types/Value.proto\x12\x0b\x66\x65\x61st.types\"\xb7\x05\n\tValueType\"\xa9\x05\n\x04\x45num\x12\x0b\n\x07INVALID\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\n\n\x06STRING\x10\x02\x12\t\n\x05INT32\x10\x03\x12\t\n\x05INT64\x10\x04\x12\n\n\x06\x44OUBLE\x10\x05\x12\t\n\x05\x46LOAT\x10\x06\x12\x08\n\x04\x42OOL\x10\x07\x12\x12\n\x0eUNIX_TIMESTAMP\x10\x08\x12\x0e\n\nBYTES_LIST\x10\x0b\x12\x0f\n\x0bSTRING_LIST\x10\x0c\x12\x0e\n\nINT32_LIST\x10\r\x12\x0e\n\nINT64_LIST\x10\x0e\x12\x0f\n\x0b\x44OUBLE_LIST\x10\x0f\x12\x0e\n\nFLOAT_LIST\x10\x10\x12\r\n\tBOOL_LIST\x10\x11\x12\x17\n\x13UNIX_TIMESTAMP_LIST\x10\x12\x12\x08\n\x04NULL\x10\x13\x12\x07\n\x03MAP\x10\x14\x12\x0c\n\x08MAP_LIST\x10\x15\x12\r\n\tBYTES_SET\x10\x16\x12\x0e\n\nSTRING_SET\x10\x17\x12\r\n\tINT32_SET\x10\x18\x12\r\n\tINT64_SET\x10\x19\x12\x0e\n\nDOUBLE_SET\x10\x1a\x12\r\n\tFLOAT_SET\x10\x1b\x12\x0c\n\x08\x42OOL_SET\x10\x1c\x12\x16\n\x12UNIX_TIMESTAMP_SET\x10\x1d\x12\x08\n\x04JSON\x10 \x12\r\n\tJSON_LIST\x10!\x12\n\n\x06STRUCT\x10\"\x12\x0f\n\x0bSTRUCT_LIST\x10#\x12\x08\n\x04UUID\x10$\x12\r\n\tTIME_UUID\x10%\x12\r\n\tUUID_LIST\x10&\x12\x12\n\x0eTIME_UUID_LIST\x10\'\x12\x0c\n\x08UUID_SET\x10(\x12\x11\n\rTIME_UUID_SET\x10)\x12\x0e\n\nVALUE_LIST\x10*\x12\r\n\tVALUE_SET\x10+\x12\x0b\n\x07\x44\x45\x43IMAL\x10,\x12\x10\n\x0c\x44\x45\x43IMAL_LIST\x10-\x12\x0f\n\x0b\x44\x45\x43IMAL_SET\x10.\x12\x0e\n\nSCALAR_MAP\x10/\x12\x13\n\x0fZONED_TIMESTAMP\x10\x30\"\xc6\x0e\n\x05Value\x12\x13\n\tbytes_val\x18\x01 \x01(\x0cH\x00\x12\x14\n\nstring_val\x18\x02 \x01(\tH\x00\x12\x13\n\tint32_val\x18\x03 \x01(\x05H\x00\x12\x13\n\tint64_val\x18\x04 \x01(\x03H\x00\x12\x14\n\ndouble_val\x18\x05 \x01(\x01H\x00\x12\x13\n\tfloat_val\x18\x06 \x01(\x02H\x00\x12\x12\n\x08\x62ool_val\x18\x07 \x01(\x08H\x00\x12\x1c\n\x12unix_timestamp_val\x18\x08 \x01(\x03H\x00\x12\x30\n\x0e\x62ytes_list_val\x18\x0b \x01(\x0b\x32\x16.feast.types.BytesListH\x00\x12\x32\n\x0fstring_list_val\x18\x0c \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12\x30\n\x0eint32_list_val\x18\r \x01(\x0b\x32\x16.feast.types.Int32ListH\x00\x12\x30\n\x0eint64_list_val\x18\x0e \x01(\x0b\x32\x16.feast.types.Int64ListH\x00\x12\x32\n\x0f\x64ouble_list_val\x18\x0f \x01(\x0b\x32\x17.feast.types.DoubleListH\x00\x12\x30\n\x0e\x66loat_list_val\x18\x10 \x01(\x0b\x32\x16.feast.types.FloatListH\x00\x12.\n\rbool_list_val\x18\x11 \x01(\x0b\x32\x15.feast.types.BoolListH\x00\x12\x39\n\x17unix_timestamp_list_val\x18\x12 \x01(\x0b\x32\x16.feast.types.Int64ListH\x00\x12%\n\x08null_val\x18\x13 \x01(\x0e\x32\x11.feast.types.NullH\x00\x12#\n\x07map_val\x18\x14 \x01(\x0b\x32\x10.feast.types.MapH\x00\x12,\n\x0cmap_list_val\x18\x15 \x01(\x0b\x32\x14.feast.types.MapListH\x00\x12.\n\rbytes_set_val\x18\x16 \x01(\x0b\x32\x15.feast.types.BytesSetH\x00\x12\x30\n\x0estring_set_val\x18\x17 \x01(\x0b\x32\x16.feast.types.StringSetH\x00\x12.\n\rint32_set_val\x18\x18 \x01(\x0b\x32\x15.feast.types.Int32SetH\x00\x12.\n\rint64_set_val\x18\x19 \x01(\x0b\x32\x15.feast.types.Int64SetH\x00\x12\x30\n\x0e\x64ouble_set_val\x18\x1a \x01(\x0b\x32\x16.feast.types.DoubleSetH\x00\x12.\n\rfloat_set_val\x18\x1b \x01(\x0b\x32\x15.feast.types.FloatSetH\x00\x12,\n\x0c\x62ool_set_val\x18\x1c \x01(\x0b\x32\x14.feast.types.BoolSetH\x00\x12\x37\n\x16unix_timestamp_set_val\x18\x1d \x01(\x0b\x32\x15.feast.types.Int64SetH\x00\x12\x12\n\x08json_val\x18 \x01(\tH\x00\x12\x30\n\rjson_list_val\x18! \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12&\n\nstruct_val\x18\" \x01(\x0b\x32\x10.feast.types.MapH\x00\x12/\n\x0fstruct_list_val\x18# \x01(\x0b\x32\x14.feast.types.MapListH\x00\x12\x12\n\x08uuid_val\x18$ \x01(\tH\x00\x12\x17\n\rtime_uuid_val\x18% \x01(\tH\x00\x12\x30\n\ruuid_list_val\x18& \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12\x35\n\x12time_uuid_list_val\x18\' \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12.\n\x0cuuid_set_val\x18( \x01(\x0b\x32\x16.feast.types.StringSetH\x00\x12\x33\n\x11time_uuid_set_val\x18) \x01(\x0b\x32\x16.feast.types.StringSetH\x00\x12.\n\x08list_val\x18* \x01(\x0b\x32\x1a.feast.types.RepeatedValueH\x00\x12-\n\x07set_val\x18+ \x01(\x0b\x32\x1a.feast.types.RepeatedValueH\x00\x12\x15\n\x0b\x64\x65\x63imal_val\x18, \x01(\tH\x00\x12\x33\n\x10\x64\x65\x63imal_list_val\x18- \x01(\x0b\x32\x17.feast.types.StringListH\x00\x12\x31\n\x0f\x64\x65\x63imal_set_val\x18. \x01(\x0b\x32\x16.feast.types.StringSetH\x00\x12\x30\n\x0escalar_map_val\x18/ \x01(\x0b\x32\x16.feast.types.ScalarMapH\x00\x12:\n\x13zoned_timestamp_val\x18\x30 \x01(\x0b\x32\x1b.feast.types.ZonedTimestampH\x00\x42\x05\n\x03val\"6\n\x0eZonedTimestamp\x12\x16\n\x0eunix_timestamp\x18\x01 \x01(\x03\x12\x0c\n\x04zone\x18\x02 \x01(\t\"\x18\n\tBytesList\x12\x0b\n\x03val\x18\x01 \x03(\x0c\"\x19\n\nStringList\x12\x0b\n\x03val\x18\x01 \x03(\t\"\x18\n\tInt32List\x12\x0b\n\x03val\x18\x01 \x03(\x05\"\x18\n\tInt64List\x12\x0b\n\x03val\x18\x01 \x03(\x03\"\x19\n\nDoubleList\x12\x0b\n\x03val\x18\x01 \x03(\x01\"\x18\n\tFloatList\x12\x0b\n\x03val\x18\x01 \x03(\x02\"\x17\n\x08\x42oolList\x12\x0b\n\x03val\x18\x01 \x03(\x08\"\x17\n\x08\x42ytesSet\x12\x0b\n\x03val\x18\x01 \x03(\x0c\"\x18\n\tStringSet\x12\x0b\n\x03val\x18\x01 \x03(\t\"\x17\n\x08Int32Set\x12\x0b\n\x03val\x18\x01 \x03(\x05\"\x17\n\x08Int64Set\x12\x0b\n\x03val\x18\x01 \x03(\x03\"\x18\n\tDoubleSet\x12\x0b\n\x03val\x18\x01 \x03(\x01\"\x17\n\x08\x46loatSet\x12\x0b\n\x03val\x18\x01 \x03(\x02\"\x16\n\x07\x42oolSet\x12\x0b\n\x03val\x18\x01 \x03(\x08\"m\n\x03Map\x12&\n\x03val\x18\x01 \x03(\x0b\x32\x19.feast.types.Map.ValEntry\x1a>\n\x08ValEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value:\x02\x38\x01\"(\n\x07MapList\x12\x1d\n\x03val\x18\x01 \x03(\x0b\x32\x10.feast.types.Map\"0\n\rRepeatedValue\x12\x1f\n\x03val\x18\x01 \x03(\x0b\x32\x12.feast.types.Value\"\xef\x01\n\x06MapKey\x12\x13\n\tint32_key\x18\x01 \x01(\x05H\x00\x12\x13\n\tint64_key\x18\x02 \x01(\x03H\x00\x12\x13\n\tfloat_key\x18\x03 \x01(\x02H\x00\x12\x14\n\ndouble_key\x18\x04 \x01(\x01H\x00\x12\x12\n\x08\x62ool_key\x18\x05 \x01(\x08H\x00\x12\x1c\n\x12unix_timestamp_key\x18\x06 \x01(\x03H\x00\x12\x13\n\tbytes_key\x18\x07 \x01(\x0cH\x00\x12\x12\n\x08uuid_key\x18\x08 \x01(\tH\x00\x12\x17\n\rtime_uuid_key\x18\t \x01(\tH\x00\x12\x15\n\x0b\x64\x65\x63imal_key\x18\n \x01(\tH\x00\x42\x05\n\x03key\"U\n\x0eScalarMapEntry\x12 \n\x03key\x18\x01 \x01(\x0b\x32\x13.feast.types.MapKey\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.feast.types.Value\"5\n\tScalarMap\x12(\n\x03val\x18\x01 \x03(\x0b\x32\x1b.feast.types.ScalarMapEntry*\x10\n\x04Null\x12\x08\n\x04NULL\x10\x00\x42Q\n\x11\x66\x65\x61st.proto.typesB\nValueProtoZ0github.com/feast-dev/feast/go/protos/feast/typesb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -24,48 +24,56 @@ _globals['DESCRIPTOR']._serialized_options = b'\n\021feast.proto.typesB\nValueProtoZ0github.com/feast-dev/feast/go/protos/feast/types' _globals['_MAP_VALENTRY']._options = None _globals['_MAP_VALENTRY']._serialized_options = b'8\001' - _globals['_NULL']._serialized_start=2373 - _globals['_NULL']._serialized_end=2389 + _globals['_NULL']._serialized_start=3605 + _globals['_NULL']._serialized_end=3621 _globals['_VALUETYPE']._serialized_start=41 - _globals['_VALUETYPE']._serialized_end=527 + _globals['_VALUETYPE']._serialized_end=736 _globals['_VALUETYPE_ENUM']._serialized_start=55 - _globals['_VALUETYPE_ENUM']._serialized_end=527 - _globals['_VALUE']._serialized_start=530 - _globals['_VALUE']._serialized_end=1809 - _globals['_BYTESLIST']._serialized_start=1811 - _globals['_BYTESLIST']._serialized_end=1835 - _globals['_STRINGLIST']._serialized_start=1837 - _globals['_STRINGLIST']._serialized_end=1862 - _globals['_INT32LIST']._serialized_start=1864 - _globals['_INT32LIST']._serialized_end=1888 - _globals['_INT64LIST']._serialized_start=1890 - _globals['_INT64LIST']._serialized_end=1914 - _globals['_DOUBLELIST']._serialized_start=1916 - _globals['_DOUBLELIST']._serialized_end=1941 - _globals['_FLOATLIST']._serialized_start=1943 - _globals['_FLOATLIST']._serialized_end=1967 - _globals['_BOOLLIST']._serialized_start=1969 - _globals['_BOOLLIST']._serialized_end=1992 - _globals['_BYTESSET']._serialized_start=1994 - _globals['_BYTESSET']._serialized_end=2017 - _globals['_STRINGSET']._serialized_start=2019 - _globals['_STRINGSET']._serialized_end=2043 - _globals['_INT32SET']._serialized_start=2045 - _globals['_INT32SET']._serialized_end=2068 - _globals['_INT64SET']._serialized_start=2070 - _globals['_INT64SET']._serialized_end=2093 - _globals['_DOUBLESET']._serialized_start=2095 - _globals['_DOUBLESET']._serialized_end=2119 - _globals['_FLOATSET']._serialized_start=2121 - _globals['_FLOATSET']._serialized_end=2144 - _globals['_BOOLSET']._serialized_start=2146 - _globals['_BOOLSET']._serialized_end=2168 - _globals['_MAP']._serialized_start=2170 - _globals['_MAP']._serialized_end=2279 - _globals['_MAP_VALENTRY']._serialized_start=2217 - _globals['_MAP_VALENTRY']._serialized_end=2279 - _globals['_MAPLIST']._serialized_start=2281 - _globals['_MAPLIST']._serialized_end=2321 - _globals['_REPEATEDVALUE']._serialized_start=2323 - _globals['_REPEATEDVALUE']._serialized_end=2371 + _globals['_VALUETYPE_ENUM']._serialized_end=736 + _globals['_VALUE']._serialized_start=739 + _globals['_VALUE']._serialized_end=2601 + _globals['_ZONEDTIMESTAMP']._serialized_start=2603 + _globals['_ZONEDTIMESTAMP']._serialized_end=2657 + _globals['_BYTESLIST']._serialized_start=2659 + _globals['_BYTESLIST']._serialized_end=2683 + _globals['_STRINGLIST']._serialized_start=2685 + _globals['_STRINGLIST']._serialized_end=2710 + _globals['_INT32LIST']._serialized_start=2712 + _globals['_INT32LIST']._serialized_end=2736 + _globals['_INT64LIST']._serialized_start=2738 + _globals['_INT64LIST']._serialized_end=2762 + _globals['_DOUBLELIST']._serialized_start=2764 + _globals['_DOUBLELIST']._serialized_end=2789 + _globals['_FLOATLIST']._serialized_start=2791 + _globals['_FLOATLIST']._serialized_end=2815 + _globals['_BOOLLIST']._serialized_start=2817 + _globals['_BOOLLIST']._serialized_end=2840 + _globals['_BYTESSET']._serialized_start=2842 + _globals['_BYTESSET']._serialized_end=2865 + _globals['_STRINGSET']._serialized_start=2867 + _globals['_STRINGSET']._serialized_end=2891 + _globals['_INT32SET']._serialized_start=2893 + _globals['_INT32SET']._serialized_end=2916 + _globals['_INT64SET']._serialized_start=2918 + _globals['_INT64SET']._serialized_end=2941 + _globals['_DOUBLESET']._serialized_start=2943 + _globals['_DOUBLESET']._serialized_end=2967 + _globals['_FLOATSET']._serialized_start=2969 + _globals['_FLOATSET']._serialized_end=2992 + _globals['_BOOLSET']._serialized_start=2994 + _globals['_BOOLSET']._serialized_end=3016 + _globals['_MAP']._serialized_start=3018 + _globals['_MAP']._serialized_end=3127 + _globals['_MAP_VALENTRY']._serialized_start=3065 + _globals['_MAP_VALENTRY']._serialized_end=3127 + _globals['_MAPLIST']._serialized_start=3129 + _globals['_MAPLIST']._serialized_end=3169 + _globals['_REPEATEDVALUE']._serialized_start=3171 + _globals['_REPEATEDVALUE']._serialized_end=3219 + _globals['_MAPKEY']._serialized_start=3222 + _globals['_MAPKEY']._serialized_end=3461 + _globals['_SCALARMAPENTRY']._serialized_start=3463 + _globals['_SCALARMAPENTRY']._serialized_end=3548 + _globals['_SCALARMAP']._serialized_start=3550 + _globals['_SCALARMAP']._serialized_end=3603 # @@protoc_insertion_point(module_scope) diff --git a/sdk/python/feast/protos/feast/types/Value_pb2.pyi b/sdk/python/feast/protos/feast/types/Value_pb2.pyi index 64079291f4d..97595d63c97 100644 --- a/sdk/python/feast/protos/feast/types/Value_pb2.pyi +++ b/sdk/python/feast/protos/feast/types/Value_pb2.pyi @@ -86,6 +86,19 @@ class ValueType(google.protobuf.message.Message): JSON_LIST: ValueType._Enum.ValueType # 33 STRUCT: ValueType._Enum.ValueType # 34 STRUCT_LIST: ValueType._Enum.ValueType # 35 + UUID: ValueType._Enum.ValueType # 36 + TIME_UUID: ValueType._Enum.ValueType # 37 + UUID_LIST: ValueType._Enum.ValueType # 38 + TIME_UUID_LIST: ValueType._Enum.ValueType # 39 + UUID_SET: ValueType._Enum.ValueType # 40 + TIME_UUID_SET: ValueType._Enum.ValueType # 41 + VALUE_LIST: ValueType._Enum.ValueType # 42 + VALUE_SET: ValueType._Enum.ValueType # 43 + DECIMAL: ValueType._Enum.ValueType # 44 + DECIMAL_LIST: ValueType._Enum.ValueType # 45 + DECIMAL_SET: ValueType._Enum.ValueType # 46 + SCALAR_MAP: ValueType._Enum.ValueType # 47 + ZONED_TIMESTAMP: ValueType._Enum.ValueType # 48 class Enum(_Enum, metaclass=_EnumEnumTypeWrapper): ... INVALID: ValueType.Enum.ValueType # 0 @@ -120,6 +133,19 @@ class ValueType(google.protobuf.message.Message): JSON_LIST: ValueType.Enum.ValueType # 33 STRUCT: ValueType.Enum.ValueType # 34 STRUCT_LIST: ValueType.Enum.ValueType # 35 + UUID: ValueType.Enum.ValueType # 36 + TIME_UUID: ValueType.Enum.ValueType # 37 + UUID_LIST: ValueType.Enum.ValueType # 38 + TIME_UUID_LIST: ValueType.Enum.ValueType # 39 + UUID_SET: ValueType.Enum.ValueType # 40 + TIME_UUID_SET: ValueType.Enum.ValueType # 41 + VALUE_LIST: ValueType.Enum.ValueType # 42 + VALUE_SET: ValueType.Enum.ValueType # 43 + DECIMAL: ValueType.Enum.ValueType # 44 + DECIMAL_LIST: ValueType.Enum.ValueType # 45 + DECIMAL_SET: ValueType.Enum.ValueType # 46 + SCALAR_MAP: ValueType.Enum.ValueType # 47 + ZONED_TIMESTAMP: ValueType.Enum.ValueType # 48 def __init__( self, @@ -161,6 +187,19 @@ class Value(google.protobuf.message.Message): JSON_LIST_VAL_FIELD_NUMBER: builtins.int STRUCT_VAL_FIELD_NUMBER: builtins.int STRUCT_LIST_VAL_FIELD_NUMBER: builtins.int + UUID_VAL_FIELD_NUMBER: builtins.int + TIME_UUID_VAL_FIELD_NUMBER: builtins.int + UUID_LIST_VAL_FIELD_NUMBER: builtins.int + TIME_UUID_LIST_VAL_FIELD_NUMBER: builtins.int + UUID_SET_VAL_FIELD_NUMBER: builtins.int + TIME_UUID_SET_VAL_FIELD_NUMBER: builtins.int + LIST_VAL_FIELD_NUMBER: builtins.int + SET_VAL_FIELD_NUMBER: builtins.int + DECIMAL_VAL_FIELD_NUMBER: builtins.int + DECIMAL_LIST_VAL_FIELD_NUMBER: builtins.int + DECIMAL_SET_VAL_FIELD_NUMBER: builtins.int + SCALAR_MAP_VAL_FIELD_NUMBER: builtins.int + ZONED_TIMESTAMP_VAL_FIELD_NUMBER: builtins.int bytes_val: builtins.bytes string_val: builtins.str int32_val: builtins.int @@ -213,6 +252,29 @@ class Value(google.protobuf.message.Message): def struct_val(self) -> global___Map: ... @property def struct_list_val(self) -> global___MapList: ... + uuid_val: builtins.str + time_uuid_val: builtins.str + @property + def uuid_list_val(self) -> global___StringList: ... + @property + def time_uuid_list_val(self) -> global___StringList: ... + @property + def uuid_set_val(self) -> global___StringSet: ... + @property + def time_uuid_set_val(self) -> global___StringSet: ... + @property + def list_val(self) -> global___RepeatedValue: ... + @property + def set_val(self) -> global___RepeatedValue: ... + decimal_val: builtins.str + @property + def decimal_list_val(self) -> global___StringList: ... + @property + def decimal_set_val(self) -> global___StringSet: ... + @property + def scalar_map_val(self) -> global___ScalarMap: ... + @property + def zoned_timestamp_val(self) -> global___ZonedTimestamp: ... def __init__( self, *, @@ -247,13 +309,52 @@ class Value(google.protobuf.message.Message): json_list_val: global___StringList | None = ..., struct_val: global___Map | None = ..., struct_list_val: global___MapList | None = ..., + uuid_val: builtins.str = ..., + time_uuid_val: builtins.str = ..., + uuid_list_val: global___StringList | None = ..., + time_uuid_list_val: global___StringList | None = ..., + uuid_set_val: global___StringSet | None = ..., + time_uuid_set_val: global___StringSet | None = ..., + list_val: global___RepeatedValue | None = ..., + set_val: global___RepeatedValue | None = ..., + decimal_val: builtins.str = ..., + decimal_list_val: global___StringList | None = ..., + decimal_set_val: global___StringSet | None = ..., + scalar_map_val: global___ScalarMap | None = ..., + zoned_timestamp_val: global___ZonedTimestamp | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_set_val", b"bool_set_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_set_val", b"bytes_set_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_set_val", b"double_set_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_set_val", b"float_set_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_set_val", b"int32_set_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_set_val", b"int64_set_val", "int64_val", b"int64_val", "json_list_val", b"json_list_val", "json_val", b"json_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_set_val", b"string_set_val", "string_val", b"string_val", "struct_list_val", b"struct_list_val", "struct_val", b"struct_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_set_val", b"unix_timestamp_set_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_set_val", b"bool_set_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_set_val", b"bytes_set_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_set_val", b"double_set_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_set_val", b"float_set_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_set_val", b"int32_set_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_set_val", b"int64_set_val", "int64_val", b"int64_val", "json_list_val", b"json_list_val", "json_val", b"json_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_set_val", b"string_set_val", "string_val", b"string_val", "struct_list_val", b"struct_list_val", "struct_val", b"struct_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_set_val", b"unix_timestamp_set_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["val", b"val"]) -> typing_extensions.Literal["bytes_val", "string_val", "int32_val", "int64_val", "double_val", "float_val", "bool_val", "unix_timestamp_val", "bytes_list_val", "string_list_val", "int32_list_val", "int64_list_val", "double_list_val", "float_list_val", "bool_list_val", "unix_timestamp_list_val", "null_val", "map_val", "map_list_val", "bytes_set_val", "string_set_val", "int32_set_val", "int64_set_val", "double_set_val", "float_set_val", "bool_set_val", "unix_timestamp_set_val", "json_val", "json_list_val", "struct_val", "struct_list_val"] | None: ... + def HasField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_set_val", b"bool_set_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_set_val", b"bytes_set_val", "bytes_val", b"bytes_val", "decimal_list_val", b"decimal_list_val", "decimal_set_val", b"decimal_set_val", "decimal_val", b"decimal_val", "double_list_val", b"double_list_val", "double_set_val", b"double_set_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_set_val", b"float_set_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_set_val", b"int32_set_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_set_val", b"int64_set_val", "int64_val", b"int64_val", "json_list_val", b"json_list_val", "json_val", b"json_val", "list_val", b"list_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "scalar_map_val", b"scalar_map_val", "set_val", b"set_val", "string_list_val", b"string_list_val", "string_set_val", b"string_set_val", "string_val", b"string_val", "struct_list_val", b"struct_list_val", "struct_val", b"struct_val", "time_uuid_list_val", b"time_uuid_list_val", "time_uuid_set_val", b"time_uuid_set_val", "time_uuid_val", b"time_uuid_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_set_val", b"unix_timestamp_set_val", "unix_timestamp_val", b"unix_timestamp_val", "uuid_list_val", b"uuid_list_val", "uuid_set_val", b"uuid_set_val", "uuid_val", b"uuid_val", "zoned_timestamp_val", b"zoned_timestamp_val", "val", b"val"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_set_val", b"bool_set_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_set_val", b"bytes_set_val", "bytes_val", b"bytes_val", "decimal_list_val", b"decimal_list_val", "decimal_set_val", b"decimal_set_val", "decimal_val", b"decimal_val", "double_list_val", b"double_list_val", "double_set_val", b"double_set_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_set_val", b"float_set_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_set_val", b"int32_set_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_set_val", b"int64_set_val", "int64_val", b"int64_val", "json_list_val", b"json_list_val", "json_val", b"json_val", "list_val", b"list_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "scalar_map_val", b"scalar_map_val", "set_val", b"set_val", "string_list_val", b"string_list_val", "string_set_val", b"string_set_val", "string_val", b"string_val", "struct_list_val", b"struct_list_val", "struct_val", b"struct_val", "time_uuid_list_val", b"time_uuid_list_val", "time_uuid_set_val", b"time_uuid_set_val", "time_uuid_val", b"time_uuid_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_set_val", b"unix_timestamp_set_val", "unix_timestamp_val", b"unix_timestamp_val", "uuid_list_val", b"uuid_list_val", "uuid_set_val", b"uuid_set_val", "uuid_val", b"uuid_val", "zoned_timestamp_val", b"zoned_timestamp_val", "val", b"val"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["val", b"val"]) -> typing_extensions.Literal["bytes_val", "string_val", "int32_val", "int64_val", "double_val", "float_val", "bool_val", "unix_timestamp_val", "bytes_list_val", "string_list_val", "int32_list_val", "int64_list_val", "double_list_val", "float_list_val", "bool_list_val", "unix_timestamp_list_val", "null_val", "map_val", "map_list_val", "bytes_set_val", "string_set_val", "int32_set_val", "int64_set_val", "double_set_val", "float_set_val", "bool_set_val", "unix_timestamp_set_val", "json_val", "json_list_val", "struct_val", "struct_list_val", "uuid_val", "time_uuid_val", "uuid_list_val", "time_uuid_list_val", "uuid_set_val", "time_uuid_set_val", "list_val", "set_val", "decimal_val", "decimal_list_val", "decimal_set_val", "scalar_map_val", "zoned_timestamp_val"] | None: ... global___Value = Value +class ZonedTimestamp(google.protobuf.message.Message): + """A timezone-aware datetime: the UTC instant plus its originating zone, so a + zoned datetime round-trips losslessly (unlike UNIX_TIMESTAMP, which is decoded + as UTC and discards the original zone). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UNIX_TIMESTAMP_FIELD_NUMBER: builtins.int + ZONE_FIELD_NUMBER: builtins.int + unix_timestamp: builtins.int + """Epoch seconds (UTC instant), same convention as unix_timestamp_val.""" + zone: builtins.str + """IANA zone name (e.g. "America/Los_Angeles") or a fixed-offset string + (e.g. "-07:00", "UTC"). Empty string is treated as UTC on read. + """ + def __init__( + self, + *, + unix_timestamp: builtins.int = ..., + zone: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["unix_timestamp", b"unix_timestamp", "zone", b"zone"]) -> None: ... + +global___ZonedTimestamp = ZonedTimestamp + class BytesList(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -529,3 +630,87 @@ class RepeatedValue(google.protobuf.message.Message): def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... global___RepeatedValue = RepeatedValue + +class MapKey(google.protobuf.message.Message): + """Map key for maps with non-string keys. + Excludes string (handled by Map) and all collection types (not valid as keys). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INT32_KEY_FIELD_NUMBER: builtins.int + INT64_KEY_FIELD_NUMBER: builtins.int + FLOAT_KEY_FIELD_NUMBER: builtins.int + DOUBLE_KEY_FIELD_NUMBER: builtins.int + BOOL_KEY_FIELD_NUMBER: builtins.int + UNIX_TIMESTAMP_KEY_FIELD_NUMBER: builtins.int + BYTES_KEY_FIELD_NUMBER: builtins.int + UUID_KEY_FIELD_NUMBER: builtins.int + TIME_UUID_KEY_FIELD_NUMBER: builtins.int + DECIMAL_KEY_FIELD_NUMBER: builtins.int + int32_key: builtins.int + int64_key: builtins.int + float_key: builtins.float + double_key: builtins.float + bool_key: builtins.bool + unix_timestamp_key: builtins.int + bytes_key: builtins.bytes + uuid_key: builtins.str + time_uuid_key: builtins.str + decimal_key: builtins.str + def __init__( + self, + *, + int32_key: builtins.int = ..., + int64_key: builtins.int = ..., + float_key: builtins.float = ..., + double_key: builtins.float = ..., + bool_key: builtins.bool = ..., + unix_timestamp_key: builtins.int = ..., + bytes_key: builtins.bytes = ..., + uuid_key: builtins.str = ..., + time_uuid_key: builtins.str = ..., + decimal_key: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["bool_key", b"bool_key", "bytes_key", b"bytes_key", "decimal_key", b"decimal_key", "double_key", b"double_key", "float_key", b"float_key", "int32_key", b"int32_key", "int64_key", b"int64_key", "key", b"key", "time_uuid_key", b"time_uuid_key", "unix_timestamp_key", b"unix_timestamp_key", "uuid_key", b"uuid_key"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["bool_key", b"bool_key", "bytes_key", b"bytes_key", "decimal_key", b"decimal_key", "double_key", b"double_key", "float_key", b"float_key", "int32_key", b"int32_key", "int64_key", b"int64_key", "key", b"key", "time_uuid_key", b"time_uuid_key", "unix_timestamp_key", b"unix_timestamp_key", "uuid_key", b"uuid_key"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["key", b"key"]) -> typing_extensions.Literal["int32_key", "int64_key", "float_key", "double_key", "bool_key", "unix_timestamp_key", "bytes_key", "uuid_key", "time_uuid_key", "decimal_key"] | None: ... + +global___MapKey = MapKey + +class ScalarMapEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + @property + def key(self) -> global___MapKey: ... + @property + def value(self) -> global___Value: ... + def __init__( + self, + *, + key: global___MapKey | None = ..., + value: global___Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + +global___ScalarMapEntry = ScalarMapEntry + +class ScalarMap(google.protobuf.message.Message): + """Map with non-string keys. For string-keyed maps use Map.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScalarMapEntry]: ... + def __init__( + self, + *, + val: collections.abc.Iterable[global___ScalarMapEntry] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... + +global___ScalarMap = ScalarMap diff --git a/sdk/python/feast/registry_server.py b/sdk/python/feast/registry_server.py index f033c5201ec..2cddf42c824 100644 --- a/sdk/python/feast/registry_server.py +++ b/sdk/python/feast/registry_server.py @@ -1,7 +1,7 @@ import logging from concurrent import futures from datetime import datetime, timezone -from typing import Any, List, Optional, Union, cast +from typing import Any, Callable, List, Optional, cast import grpc from google.protobuf.empty_pb2 import Empty @@ -12,7 +12,7 @@ from feast.base_feature_view import BaseFeatureView from feast.data_source import DataSource from feast.entity import Entity -from feast.errors import FeastObjectNotFoundException, FeatureViewNotFoundException +from feast.errors import FeastObjectNotFoundException from feast.feast_object import FeastObject from feast.feature_view import FeatureView from feast.grpc_error_interceptor import ErrorInterceptor @@ -146,6 +146,8 @@ def sort_key(obj): def _build_any_feature_view_proto(feature_view: BaseFeatureView): + from feast.labeling.label_view import LabelView + if isinstance(feature_view, StreamFeatureView): arg_name = "stream_feature_view" feature_view_proto = feature_view.to_proto() @@ -155,6 +157,11 @@ def _build_any_feature_view_proto(feature_view: BaseFeatureView): elif isinstance(feature_view, OnDemandFeatureView): arg_name = "on_demand_feature_view" feature_view_proto = feature_view.to_proto() + elif isinstance(feature_view, LabelView): + arg_name = "label_view" + feature_view_proto = feature_view.to_proto() + else: + raise ValueError(f"Unexpected feature view type: {type(feature_view)}") return RegistryServer_pb2.AnyFeatureView( feature_view=feature_view_proto if arg_name == "feature_view" else None, @@ -164,6 +171,7 @@ def _build_any_feature_view_proto(feature_view: BaseFeatureView): on_demand_feature_view=feature_view_proto if arg_name == "on_demand_feature_view" else None, + label_view=feature_view_proto if arg_name == "label_view" else None, ) @@ -341,23 +349,60 @@ def GetAnyFeatureView( def ApplyFeatureView( self, request: RegistryServer_pb2.ApplyFeatureViewRequest, context ): + from feast.labeling.label_view import LabelView + feature_view_type = request.WhichOneof("base_feature_view") + feature_view_meta: BaseFeatureView + if feature_view_type == "feature_view": - feature_view = FeatureView.from_proto(request.feature_view) + feature_view_meta = FeatureView.from_proto( + request.feature_view, skip_udf=True + ) elif feature_view_type == "on_demand_feature_view": - feature_view = OnDemandFeatureView.from_proto( - request.on_demand_feature_view + feature_view_meta = OnDemandFeatureView.from_proto( + request.on_demand_feature_view, skip_udf=True ) elif feature_view_type == "stream_feature_view": - feature_view = StreamFeatureView.from_proto(request.stream_feature_view) + feature_view_meta = StreamFeatureView.from_proto( + request.stream_feature_view, skip_udf=True + ) + elif feature_view_type == "label_view": + feature_view_meta = LabelView.from_proto(request.label_view) + else: + raise ValueError(f"Unexpected feature view type: {feature_view_type}") + + getter: Callable + if isinstance(feature_view_meta, StreamFeatureView): + getter = self.proxied_registry.get_stream_feature_view + elif isinstance(feature_view_meta, FeatureView): + getter = self.proxied_registry.get_feature_view + elif isinstance(feature_view_meta, OnDemandFeatureView): + getter = self.proxied_registry.get_on_demand_feature_view + elif isinstance(feature_view_meta, LabelView): + getter = self.proxied_registry.get_label_view + else: + getter = self.proxied_registry.get_feature_view assert_permissions_to_update( - resource=feature_view, - # Will replace with the new get_any_feature_view method later - getter=self.proxied_registry.get_feature_view, + resource=cast(FeastObject, feature_view_meta), + getter=cast(Callable, getter), project=request.project, ) + feature_view: BaseFeatureView + if feature_view_type == "feature_view": + feature_view = FeatureView.from_proto(request.feature_view) + elif feature_view_type == "on_demand_feature_view": + feature_view = OnDemandFeatureView.from_proto( + request.on_demand_feature_view + ) + elif feature_view_type == "stream_feature_view": + feature_view = StreamFeatureView.from_proto(request.stream_feature_view) + elif feature_view_type == "label_view": + feature_view = LabelView.from_proto(request.label_view) + else: + raise ValueError(f"Unexpected feature view type: {feature_view_type}") + ( self.proxied_registry.apply_feature_view( feature_view=feature_view, @@ -379,6 +424,7 @@ def ListFeatureViews( project=request.project, allow_cache=request.allow_cache, tags=dict(request.tags), + skip_udf=True, ), ), actions=AuthzedAction.DESCRIBE, @@ -397,13 +443,20 @@ def ListFeatureViews( def ListAllFeatureViews( self, request: RegistryServer_pb2.ListAllFeatureViewsRequest, context ): + from feast.labeling.label_view import LabelView + all_feature_views = cast( list[FeastObject], - self.proxied_registry.list_all_feature_views( - project=request.project, - allow_cache=request.allow_cache, - tags=dict(request.tags), - ), + [ + fv + for fv in self.proxied_registry.list_all_feature_views( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + skip_udf=True, + ) + if not isinstance(fv, LabelView) + ], ) if ( @@ -531,19 +584,12 @@ def ListAllFeatureViews( def DeleteFeatureView( self, request: RegistryServer_pb2.DeleteFeatureViewRequest, context ): - feature_view: Union[StreamFeatureView, FeatureView] - - try: - feature_view = self.proxied_registry.get_stream_feature_view( - name=request.name, project=request.project, allow_cache=False - ) - except FeatureViewNotFoundException: - feature_view = self.proxied_registry.get_feature_view( - name=request.name, project=request.project, allow_cache=False - ) + feature_view = self.proxied_registry.get_any_feature_view( + name=request.name, project=request.project, allow_cache=False + ) assert_permissions( - resource=feature_view, + resource=cast(FeastObject, feature_view), actions=[AuthzedAction.DELETE], ) self.proxied_registry.delete_feature_view( @@ -575,6 +621,7 @@ def ListStreamFeatureViews( project=request.project, allow_cache=request.allow_cache, tags=dict(request.tags), + skip_udf=True, ), ), actions=AuthzedAction.DESCRIBE, @@ -616,6 +663,7 @@ def ListOnDemandFeatureViews( project=request.project, allow_cache=request.allow_cache, tags=dict(request.tags), + skip_udf=True, ), ), actions=AuthzedAction.DESCRIBE, @@ -633,6 +681,40 @@ def ListOnDemandFeatureViews( pagination=pagination_metadata, ) + def GetLabelView(self, request: RegistryServer_pb2.GetLabelViewRequest, context): + return assert_permissions( + resource=self.proxied_registry.get_label_view( + name=request.name, + project=request.project, + allow_cache=request.allow_cache, + ), + actions=[AuthzedAction.DESCRIBE], + ).to_proto() + + def ListLabelViews( + self, request: RegistryServer_pb2.ListLabelViewsRequest, context + ): + paginated_label_views, pagination_metadata = apply_pagination_and_sorting( + permitted_resources( + resources=cast( + list[FeastObject], + self.proxied_registry.list_label_views( + project=request.project, + allow_cache=request.allow_cache, + tags=dict(request.tags), + ), + ), + actions=AuthzedAction.DESCRIBE, + ), + pagination=request.pagination, + sorting=request.sorting, + ) + + return RegistryServer_pb2.ListLabelViewsResponse( + label_views=[label_view.to_proto() for label_view in paginated_label_views], + pagination=pagination_metadata, + ) + def ApplyFeatureService( self, request: RegistryServer_pb2.ApplyFeatureServiceRequest, context ): @@ -874,6 +956,13 @@ def DeleteValidationReference( def ListProjectMetadata( self, request: RegistryServer_pb2.ListProjectMetadataRequest, context ): + try: + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.DESCRIBE]) + except FeastObjectNotFoundException: + pass return RegistryServer_pb2.ListProjectMetadataResponse( project_metadata=[ project_metadata.to_proto() @@ -906,6 +995,10 @@ def ApplyMaterialization( return Empty() def UpdateInfra(self, request: RegistryServer_pb2.UpdateInfraRequest, context): + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.UPDATE]) self.proxied_registry.update_infra( infra=Infra.from_proto(request.infra), project=request.project, @@ -914,6 +1007,10 @@ def UpdateInfra(self, request: RegistryServer_pb2.UpdateInfraRequest, context): return Empty() def GetInfra(self, request: RegistryServer_pb2.GetInfraRequest, context): + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.DESCRIBE]) return self.proxied_registry.get_infra( project=request.project, allow_cache=request.allow_cache ).to_proto() @@ -1046,6 +1143,13 @@ def DeleteProject(self, request: RegistryServer_pb2.DeleteProjectRequest, contex def GetRegistryLineage( self, request: RegistryServer_pb2.GetRegistryLineageRequest, context ): + try: + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.DESCRIBE]) + except FeastObjectNotFoundException: + pass direct_relationships, indirect_relationships = ( self.proxied_registry.get_registry_lineage( project=request.project, @@ -1084,6 +1188,13 @@ def GetObjectRelationships( self, request: RegistryServer_pb2.GetObjectRelationshipsRequest, context ): """Get relationships for a specific object.""" + try: + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.DESCRIBE]) + except FeastObjectNotFoundException: + pass relationships = self.proxied_registry.get_object_relationships( project=request.project, object_type=request.object_type, @@ -1104,38 +1215,49 @@ def GetObjectRelationships( ) def Commit(self, request, context): + for project in self.proxied_registry.list_projects(allow_cache=True): + assert_permissions(resource=project, actions=[AuthzedAction.UPDATE]) self.proxied_registry.commit() return Empty() def Refresh(self, request, context): + project = self.proxied_registry.get_project( + name=request.project, allow_cache=True + ) + assert_permissions(resource=project, actions=[AuthzedAction.UPDATE]) self.proxied_registry.refresh(request.project) return Empty() - def Proto(self, request, context): - return self.proxied_registry.proto() - def ListFeatures(self, request: RegistryServer_pb2.ListFeaturesRequest, context): """ List all features in the registry, optionally filtered by project, feature_view, or name. """ + from feast.labeling.label_view import LabelView + allow_cache = request.allow_cache if hasattr(request, "allow_cache") else True feature_views = self.proxied_registry.list_all_feature_views( project=request.project, allow_cache=allow_cache, + skip_udf=True, ) permitted_fvs = permitted_resources( resources=cast(list[FeastObject], feature_views), actions=AuthzedAction.DESCRIBE, ) + requested_kind = ( + request.kind if hasattr(request, "kind") and request.kind else "" + ) features = [] for fv in permitted_fvs: fv_name = getattr(fv, "name", None) + kind = "label" if isinstance(fv, LabelView) else "feature" + if requested_kind and kind != requested_kind: + continue for feature in getattr(fv, "features", []): if request.feature_view and fv_name != request.feature_view: continue if request.name and feature.name != request.name: continue - # Get owner and timestamps from feature view owner = "" created_timestamp = None last_updated_timestamp = None @@ -1161,6 +1283,7 @@ def ListFeatures(self, request: RegistryServer_pb2.ListFeaturesRequest, context) created_timestamp=created_timestamp, last_updated_timestamp=last_updated_timestamp, tags=getattr(feature, "tags", {}), + kind=kind, ) ) paginated_features, pagination_metadata = apply_pagination_and_sorting( @@ -1176,6 +1299,8 @@ def GetFeature(self, request: RegistryServer_pb2.GetFeatureRequest, context): """ Get a single feature by project, feature_view, and name. """ + from feast.labeling.label_view import LabelView + allow_cache = getattr(request, "allow_cache", True) feature_views = self.proxied_registry.list_all_feature_views( project=request.project, @@ -1189,7 +1314,6 @@ def GetFeature(self, request: RegistryServer_pb2.GetFeatureRequest, context): fv_name = getattr(fv, "name", None) for feature in getattr(fv, "features", []): if fv_name == request.feature_view and feature.name == request.name: - # Get owner and timestamps from feature view owner = "" created_timestamp = None last_updated_timestamp = None @@ -1214,6 +1338,7 @@ def GetFeature(self, request: RegistryServer_pb2.GetFeatureRequest, context): created_timestamp=created_timestamp, last_updated_timestamp=last_updated_timestamp, tags=getattr(feature, "tags", {}), + kind="label" if isinstance(fv, LabelView) else "feature", ) raise FeastObjectNotFoundException( f"Feature {request.name} not found in feature view {request.feature_view} in project {request.project}" diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index 02a0f13c733..06529cea0f2 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -50,6 +50,7 @@ "k8s": "feast.infra.compute_engines.kubernetes.k8s_engine.KubernetesComputeEngine", "spark.engine": "feast.infra.compute_engines.spark.compute.SparkComputeEngine", "ray.engine": "feast.infra.compute_engines.ray.compute.RayComputeEngine", + "flink.engine": "feast.infra.compute_engines.flink.compute.FlinkComputeEngine", } LEGACY_ONLINE_STORE_CLASS_FOR_TYPE = { @@ -120,6 +121,24 @@ "oidc_client": "feast.permissions.auth_model.OidcClientAuthConfig", } +_OIDC_CLIENT_KEYS = frozenset( + {"client_secret", "token", "token_env_var", "username", "password"} +) + + +def _is_oidc_client_config(auth_dict: dict) -> bool: + """Decide whether an OIDC auth dict should be routed to OidcClientAuthConfig. + + True when the dict carries any client-credential key, or when it is a bare + ``{"type": "oidc"}`` dict with no server-side keys (auth_discovery_url / + client_id), which signals token-passthrough via FEAST_OIDC_TOKEN. + """ + if auth_dict.get("type") != AuthType.OIDC.value: + return False + has_client_keys = bool(_OIDC_CLIENT_KEYS & auth_dict.keys()) + has_server_keys = "auth_discovery_url" in auth_dict + return has_client_keys or not has_server_keys + class FeastBaseModel(BaseModel): """Feast Pydantic Configuration Class""" @@ -133,6 +152,13 @@ class FeastConfigBaseModel(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid") +class McpRegistryConfig(FeastBaseModel): + """MCP (Model Context Protocol) configuration for the registry REST server.""" + + enabled: StrictBool = False + """ bool: Enable MCP support on the REST registry server. """ + + class RegistryConfig(FeastBaseModel): """Metadata Store Configuration. Configuration that relates to reading from and writing to the Feast registry.""" @@ -167,6 +193,15 @@ class RegistryConfig(FeastBaseModel): Once this is set to True, it cannot be reverted back to False. Reverting back to False will only reset the project but not all the projects""" + enable_online_feature_view_versioning: StrictBool = False + """ bool: Enable versioned online store tables and version-qualified reads + (e.g., 'fv@v2:feature'). When True, each schema version gets its own + online store table and can be queried independently. Version history + tracking in the registry is always active regardless of this setting. """ + + mcp: Optional[McpRegistryConfig] = None + """ McpRegistryConfig: MCP (Model Context Protocol) configuration for the registry REST server. """ + @field_validator("path") def validate_path(cls, path: str, values: ValidationInfo) -> str: if values.data.get("registry_type") == "sql": @@ -190,6 +225,19 @@ class MaterializationConfig(BaseModel): """ bool: If true, feature retrieval jobs will only pull the latest feature values for each entity. If false, feature retrieval jobs will pull all feature values within the specified time range. """ + online_write_batch_size: Optional[int] = Field(default=None, gt=0) + """ int: Number of rows to write to online store per batch during materialization. + If None (default), all rows are written in a single batch for backward compatibility. + Set to a positive integer (e.g., 10000) to enable batched writes. + Supported compute engines: local, spark, ray. """ + + +class DataQualityMonitoringConfig(FeastConfigBaseModel): + """Data Quality Monitoring configuration.""" + + auto_baseline: StrictBool = True + """Whether baseline distribution is computed automatically on ``feast apply``.""" + class OpenLineageConfig(FeastBaseModel): """Configuration for OpenLineage integration. @@ -209,8 +257,8 @@ class OpenLineageConfig(FeastBaseModel): enabled: StrictBool = False """ bool: Whether OpenLineage integration is enabled. Defaults to False. """ - transport_type: StrictStr = "console" - """ str: Type of transport (http, console, file, kafka). Defaults to console. """ + transport_type: Optional[StrictStr] = None + """ str: Type of transport (http, console, file, kafka). Defaults to None (uses OpenLineage SDK defaults). """ transport_url: Optional[StrictStr] = None """ str: URL for HTTP transport. Required when transport_type is 'http'. """ @@ -313,7 +361,15 @@ class RepoConfig(FeastBaseModel): """ MaterializationConfig: Configuration options for feature materialization behavior. """ openlineage_config: Optional[OpenLineageConfig] = Field(None, alias="openlineage") - """ OpenLineageConfig: Configuration for OpenLineage data lineage integration (optional). """ + """ Configuration for OpenLineage data lineage integration (optional). """ + + mlflow_config: Optional[Any] = Field(None, alias="mlflow") + """ MlflowConfig: Configuration for MLflow experiment tracking integration (optional). """ + + data_quality_monitoring_config: Optional[DataQualityMonitoringConfig] = Field( + None, alias="data_quality_monitoring" + ) + """ DataQualityMonitoringConfig: Data Quality Monitoring configuration (optional). """ def __init__(self, **data: Any): super().__init__(**data) @@ -355,6 +411,11 @@ def __init__(self, **data: Any): if "openlineage" in data: self.openlineage_config = data["openlineage"] + # Initialize MLflow configuration + self._mlflow = None + if "mlflow" in data: + self.mlflow_config = data["mlflow"] + if self.entity_key_serialization_version < 3: warnings.warn( "The serialization version below 3 are deprecated. " @@ -374,10 +435,11 @@ def registry(self): # This may be a custom registry store, which does not need a 'registry_type' self._registry = RegistryConfig(**self.registry_config) elif isinstance(self.registry_config, str): - # User passed in just a path to file registry - self._registry = get_registry_config_from_type("file")( - path=self.registry_config - ) + # Let Registry.__init__ auto-detect the correct store class + # from the URI scheme (e.g. gs:// -> GCSRegistryStore). + # Previously this hardcoded "file" type, which broke gs:// and + # s3:// paths because FileRegistryStore uses pathlib.Path. + self._registry = RegistryConfig(path=self.registry_config) elif self.registry_config: self._registry = self.registry_config return self._registry @@ -401,26 +463,12 @@ def offline_store(self): def auth_config(self): if not self._auth: if isinstance(self.auth, Dict): - # treat this auth block as *client-side* OIDC when it matches - # 1) ROPG – username + password + client_secret - # 2) client-credentials – client_secret only - # 3) static token – token - is_oidc_client = self.auth.get("type") == AuthType.OIDC.value and ( - ( - "username" in self.auth - and "password" in self.auth - and "client_secret" in self.auth - ) # 1 - or ( - "client_secret" in self.auth - and "username" not in self.auth - and "password" not in self.auth - ) # 2 - or ("token" in self.auth) # 3 + config_type = ( + "oidc_client" + if _is_oidc_client_config(self.auth) + else self.auth.get("type") ) - self._auth = get_auth_config_from_type( - "oidc_client" if is_oidc_client else self.auth.get("type") - )(**self.auth) + self._auth = get_auth_config_from_type(config_type)(**self.auth) elif isinstance(self.auth, str): self._auth = get_auth_config_from_type(self.auth)() elif self.auth: @@ -468,6 +516,18 @@ def openlineage(self) -> Optional[OpenLineageConfig]: self._openlineage = self.openlineage_config return self._openlineage + @property + def mlflow(self): + """Get the MLflow configuration.""" + if not self._mlflow: + if isinstance(self.mlflow_config, Dict): + from feast.mlflow_integration.config import MlflowConfig + + self._mlflow = MlflowConfig(**self.mlflow_config) + elif self.mlflow_config: + self._mlflow = self.mlflow_config + return self._mlflow + @model_validator(mode="before") def _validate_auth_config(cls, values: Any) -> Any: from feast.permissions.auth_model import AuthConfig diff --git a/sdk/python/feast/repo_contents.py b/sdk/python/feast/repo_contents.py index d65f6ac7bb9..6dac9769317 100644 --- a/sdk/python/feast/repo_contents.py +++ b/sdk/python/feast/repo_contents.py @@ -17,6 +17,7 @@ from feast.entity import Entity from feast.feature_service import FeatureService from feast.feature_view import FeatureView +from feast.labeling.label_view import LabelView from feast.on_demand_feature_view import OnDemandFeatureView from feast.permissions.permission import Permission from feast.project import Project @@ -34,6 +35,7 @@ class RepoContents(NamedTuple): feature_views: List[FeatureView] on_demand_feature_views: List[OnDemandFeatureView] stream_feature_views: List[StreamFeatureView] + label_views: List[LabelView] entities: List[Entity] feature_services: List[FeatureService] permissions: List[Permission] @@ -49,6 +51,7 @@ def to_registry_proto(self) -> RegistryProto: registry_proto.on_demand_feature_views.extend( [fv.to_proto() for fv in self.on_demand_feature_views] ) + registry_proto.label_views.extend([lv.to_proto() for lv in self.label_views]) registry_proto.feature_services.extend( [fs.to_proto() for fs in self.feature_services] ) diff --git a/sdk/python/feast/repo_operations.py b/sdk/python/feast/repo_operations.py index 1a6de75b2e4..02747ac4b54 100644 --- a/sdk/python/feast/repo_operations.py +++ b/sdk/python/feast/repo_operations.py @@ -1,586 +1,657 @@ -import base64 -import importlib -import json -import logging -import os -import random -import re -import sys -import tempfile -from importlib.abc import Loader -from importlib.machinery import ModuleSpec -from pathlib import Path -from typing import List, Optional, Set, Union - -import click -from click.exceptions import BadParameter - -from feast import PushSource -from feast.batch_feature_view import BatchFeatureView -from feast.constants import FEATURE_STORE_YAML_ENV_NAME -from feast.data_source import DataSource, KafkaSource, KinesisSource -from feast.diff.registry_diff import extract_objects_for_keep_delete_update_add -from feast.entity import Entity -from feast.feature_service import FeatureService -from feast.feature_store import FeatureStore -from feast.feature_view import DUMMY_ENTITY, FeatureView -from feast.file_utils import replace_str_in_file -from feast.infra.registry.base_registry import BaseRegistry -from feast.infra.registry.registry import FEAST_OBJECT_TYPES, FeastObjectType, Registry -from feast.names import adjectives, animals -from feast.on_demand_feature_view import OnDemandFeatureView -from feast.permissions.permission import Permission -from feast.project import Project -from feast.repo_config import RepoConfig -from feast.repo_contents import RepoContents -from feast.stream_feature_view import StreamFeatureView - -logger = logging.getLogger(__name__) - - -def py_path_to_module(path: Path) -> str: - return ( - str(path.relative_to(os.getcwd()))[: -len(".py")] - .replace("./", "") - .replace("/", ".") - .replace("\\", ".") - ) - - -def read_feastignore(repo_root: Path) -> List[str]: - """Read .feastignore in the repo root directory (if exists) and return the list of user-defined ignore paths""" - feast_ignore = repo_root / ".feastignore" - if not feast_ignore.is_file(): - return [] - lines = feast_ignore.read_text().strip().split("\n") - ignore_paths = [] - for line in lines: - # Remove everything after the first occurance of "#" symbol (comments) - if line.find("#") >= 0: - line = line[: line.find("#")] - # Strip leading or ending whitespaces - line = line.strip() - # Add this processed line to ignore_paths if it's not empty - if len(line) > 0: - ignore_paths.append(line) - return ignore_paths - - -def get_ignore_files(repo_root: Path, ignore_paths: List[str]) -> Set[Path]: - """Get all ignore files that match any of the user-defined ignore paths""" - ignore_files = set() - for ignore_path in set(ignore_paths): - # ignore_path may contains matchers (* or **). Use glob() to match user-defined path to actual paths - for matched_path in repo_root.glob(ignore_path): - if matched_path.is_file(): - # If the matched path is a file, add that to ignore_files set - ignore_files.add(matched_path.resolve()) - else: - # Otherwise, list all Python files in that directory and add all of them to ignore_files set - ignore_files |= { - sub_path.resolve() - for sub_path in matched_path.glob("**/*.py") - if sub_path.is_file() - } - return ignore_files - - -def get_repo_files(repo_root: Path) -> List[Path]: - """Get the list of all repo files, ignoring undesired files & directories specified in .feastignore""" - # Read ignore paths from .feastignore and create a set of all files that match any of these paths - ignore_paths = read_feastignore(repo_root) + [ - ".git", - ".feastignore", - ".venv", - ".pytest_cache", - "__pycache__", - ".ipynb_checkpoints", - ] - ignore_files = get_ignore_files(repo_root, ignore_paths) - - # List all Python files in the root directory (recursively) - repo_files = { - p.resolve() - for p in repo_root.glob("**/*.py") - if p.is_file() and "__init__.py" != p.name - } - # Ignore all files that match any of the ignore paths in .feastignore - repo_files -= ignore_files - - # Sort repo_files to read them in the same order every time - return sorted(repo_files) - - -def parse_repo(repo_root: Path) -> RepoContents: - """ - Collects unique Feast object definitions from the given feature repo. - - Specifically, if an object foo has already been added, bar will still be added if - (bar == foo), but not if (bar is foo). This ensures that import statements will - not result in duplicates, but defining two equal objects will. - """ - res = RepoContents( - projects=[], - data_sources=[], - entities=[], - feature_views=[], - feature_services=[], - on_demand_feature_views=[], - stream_feature_views=[], - permissions=[], - ) - - for repo_file in get_repo_files(repo_root): - module_path = py_path_to_module(repo_file) - module = importlib.import_module(module_path) - - for attr_name in dir(module): - obj = getattr(module, attr_name) - - if isinstance(obj, DataSource) and not any( - (obj is ds) for ds in res.data_sources - ): - res.data_sources.append(obj) - - # Handle batch sources defined within stream sources. - if ( - isinstance(obj, PushSource) - or isinstance(obj, KafkaSource) - or isinstance(obj, KinesisSource) - ): - batch_source = obj.batch_source - - if batch_source and not any( - (batch_source is ds) for ds in res.data_sources - ): - res.data_sources.append(batch_source) - if ( - isinstance(obj, FeatureView) - and not any((obj is fv) for fv in res.feature_views) - and not isinstance(obj, StreamFeatureView) - and not isinstance(obj, BatchFeatureView) - ): - res.feature_views.append(obj) - - # Handle batch sources defined with feature views. - batch_source = obj.batch_source - if batch_source is not None and not any( - (batch_source is ds) for ds in res.data_sources - ): - res.data_sources.append(batch_source) - - # Handle stream sources defined with feature views. - if obj.stream_source: - stream_source = obj.stream_source - if not any((stream_source is ds) for ds in res.data_sources): - res.data_sources.append(stream_source) - elif isinstance(obj, StreamFeatureView) and not any( - (obj is sfv) for sfv in res.stream_feature_views - ): - res.stream_feature_views.append(obj) - - # Handle batch sources defined with feature views. - batch_source = obj.batch_source - if batch_source is not None and not any( - (batch_source is ds) for ds in res.data_sources - ): - res.data_sources.append(batch_source) - assert obj.stream_source - stream_source = obj.stream_source - if not any((stream_source is ds) for ds in res.data_sources): - res.data_sources.append(stream_source) - elif isinstance(obj, BatchFeatureView) and not any( - (obj is bfv) for bfv in res.feature_views - ): - res.feature_views.append(obj) - - # Handle batch sources defined with feature views. - batch_source = obj.batch_source - if batch_source is not None and not any( - (batch_source is ds) for ds in res.data_sources - ): - res.data_sources.append(batch_source) - elif isinstance(obj, Entity) and not any( - (obj is entity) for entity in res.entities - ): - res.entities.append(obj) - elif isinstance(obj, FeatureService) and not any( - (obj is fs) for fs in res.feature_services - ): - res.feature_services.append(obj) - elif isinstance(obj, OnDemandFeatureView) and not any( - (obj is odfv) for odfv in res.on_demand_feature_views - ): - res.on_demand_feature_views.append(obj) - elif isinstance(obj, Permission) and not any( - (obj is p) for p in res.permissions - ): - res.permissions.append(obj) - elif isinstance(obj, Project) and not any((obj is p) for p in res.projects): - res.projects.append(obj) - - res.entities.append(DUMMY_ENTITY) - return res - - -def plan( - repo_config: RepoConfig, - repo_path: Path, - skip_source_validation: bool, - skip_feature_view_validation: bool = False, -): - os.chdir(repo_path) - repo = _get_repo_contents(repo_path, repo_config.project, repo_config) - for project in repo.projects: - repo_config.project = project.name - store, registry = _get_store_and_registry(repo_config) - # TODO: When we support multiple projects in a single repo, we should filter repo contents by project - if not skip_source_validation: - provider = store._get_provider() - data_sources = [ - t.batch_source for t in repo.feature_views if t.batch_source is not None - ] - # Make sure the data source used by this feature view is supported by Feast - for data_source in data_sources: - provider.validate_data_source(store.config, data_source) - - registry_diff, infra_diff, _ = store.plan( - repo, skip_feature_view_validation=skip_feature_view_validation - ) - click.echo(registry_diff.to_string()) - click.echo(infra_diff.to_string()) - - -def _get_repo_contents( - repo_path, - project_name: Optional[str] = None, - repo_config: Optional[RepoConfig] = None, -): - sys.dont_write_bytecode = True - repo = parse_repo(repo_path) - - if len(repo.projects) < 1: - if project_name: - print( - f"No project found in the repository. Using project name {project_name} defined in feature_store.yaml" - ) - project_description = ( - repo_config.project_description if repo_config else None - ) - repo.projects.append( - Project(name=project_name, description=project_description or "") - ) - else: - print( - "No project found in the repository. Either define Project in repository or define a project in feature_store.yaml" - ) - sys.exit(1) - elif len(repo.projects) == 1: - if repo.projects[0].name != project_name: - print( - "Project object name should match with the project name defined in feature_store.yaml" - ) - sys.exit(1) - else: - print( - "Multiple projects found in the repository. Currently no support for multiple projects" - ) - sys.exit(1) - - return repo - - -def _get_store_and_registry(repo_config): - store = FeatureStore(config=repo_config) - registry = store.registry - return store, registry - - -def extract_objects_for_apply_delete(project, registry, repo): - # TODO(achals): This code path should be refactored to handle added & kept entities separately. - ( - _, - objs_to_delete, - objs_to_update, - objs_to_add, - ) = extract_objects_for_keep_delete_update_add(registry, project, repo) - - all_to_apply: List[ - Union[ - Entity, - FeatureView, - OnDemandFeatureView, - StreamFeatureView, - FeatureService, - ] - ] = [] - for object_type in FEAST_OBJECT_TYPES: - to_apply = set(objs_to_add[object_type]).union(objs_to_update[object_type]) - all_to_apply.extend(to_apply) - - all_to_delete: List[ - Union[ - Entity, - FeatureView, - OnDemandFeatureView, - StreamFeatureView, - FeatureService, - ] - ] = [] - for object_type in FEAST_OBJECT_TYPES: - all_to_delete.extend(objs_to_delete[object_type]) - - return ( - all_to_apply, - all_to_delete, - set(objs_to_add[FeastObjectType.FEATURE_VIEW]).union( - set(objs_to_update[FeastObjectType.FEATURE_VIEW]) - ), - objs_to_delete[FeastObjectType.FEATURE_VIEW], - ) - - -def apply_total_with_repo_instance( - store: FeatureStore, - project_name: str, - registry: BaseRegistry, - repo: RepoContents, - skip_source_validation: bool, - skip_feature_view_validation: bool = False, -): - if not skip_source_validation: - provider = store._get_provider() - data_sources = [ - t.batch_source for t in repo.feature_views if t.batch_source is not None - ] - # Make sure the data source used by this feature view is supported by Feast - for data_source in data_sources: - provider.validate_data_source(store.config, data_source) - - # For each object in the registry, determine whether it should be kept or deleted. - ( - all_to_apply, - all_to_delete, - views_to_keep, - views_to_delete, - ) = extract_objects_for_apply_delete(project_name, registry, repo) - - try: - if store._should_use_plan(): - # Planning phase - compute diffs first without progress bars - registry_diff, infra_diff, new_infra = store.plan( - repo, - skip_feature_view_validation=skip_feature_view_validation, - ) - click.echo(registry_diff.to_string()) - - # Only show progress bars if there are actual infrastructure changes - progress_ctx = None - if len(infra_diff.infra_object_diffs) > 0: - from feast.diff.apply_progress import ApplyProgressContext - - progress_ctx = ApplyProgressContext() - progress_ctx.start_overall_progress() - - # Apply phase - store._apply_diffs( - registry_diff, infra_diff, new_infra, progress_ctx=progress_ctx - ) - click.echo(infra_diff.to_string()) - else: - # Legacy apply path - no progress bars for legacy path - store.apply( - all_to_apply, - objects_to_delete=all_to_delete, - partial=False, - skip_feature_view_validation=skip_feature_view_validation, - ) - log_infra_changes(views_to_keep, views_to_delete) - finally: - # Cleanup is handled in the new _apply_diffs method - pass - - -def log_infra_changes( - views_to_keep: Set[FeatureView], views_to_delete: Set[FeatureView] -): - from colorama import Fore, Style - - for view in views_to_keep: - click.echo( - f"Deploying infrastructure for {Style.BRIGHT + Fore.GREEN}{view.name}{Style.RESET_ALL}" - ) - for view in views_to_delete: - click.echo( - f"Removing infrastructure for {Style.BRIGHT + Fore.RED}{view.name}{Style.RESET_ALL}" - ) - - -def create_feature_store( - ctx: click.Context, -) -> FeatureStore: - repo = ctx.obj["CHDIR"] - # If we received a base64 encoded version of feature_store.yaml, use that - config_base64 = os.getenv(FEATURE_STORE_YAML_ENV_NAME) - if config_base64: - print("Received base64 encoded feature_store.yaml") - config_bytes = base64.b64decode(config_base64) - # Create a new unique directory for writing feature_store.yaml - repo_path = Path(tempfile.mkdtemp()) - with open(repo_path / "feature_store.yaml", "wb") as f: - f.write(config_bytes) - return FeatureStore(repo_path=str(repo_path.resolve())) - else: - fs_yaml_file = ctx.obj["FS_YAML_FILE"] - cli_check_repo(repo, fs_yaml_file) - return FeatureStore(repo_path=str(repo), fs_yaml_file=fs_yaml_file) - - -def apply_total( - repo_config: RepoConfig, - repo_path: Path, - skip_source_validation: bool, - skip_feature_view_validation: bool = False, -): - os.chdir(repo_path) - repo = _get_repo_contents(repo_path, repo_config.project, repo_config) - for project in repo.projects: - repo_config.project = project.name - store, registry = _get_store_and_registry(repo_config) - if not is_valid_name(project.name): - print( - f"{project.name} is not valid. Project name should only have " - f"alphanumerical values, underscores, and hyphens but not start with an underscore or hyphen." - ) - sys.exit(1) - # TODO: When we support multiple projects in a single repo, we should filter repo contents by project. Currently there is no way to associate Feast objects to project. - print(f"Applying changes for project {project.name}") - apply_total_with_repo_instance( - store, - project.name, - registry, - repo, - skip_source_validation, - skip_feature_view_validation, - ) - - -def teardown(repo_config: RepoConfig, repo_path: Optional[str]): - # Cannot pass in both repo_path and repo_config to FeatureStore. - feature_store = FeatureStore(repo_path=repo_path, config=repo_config) - feature_store.teardown() - - -def registry_dump(repo_config: RepoConfig, repo_path: Path) -> str: - """For debugging only: output contents of the metadata registry""" - registry_config = repo_config.registry - project = repo_config.project - registry = Registry( - project, - registry_config=registry_config, - repo_path=repo_path, - auth_config=repo_config.auth_config, - ) - registry_dict = registry.to_dict(project=project) - return json.dumps(registry_dict, indent=2, sort_keys=True) - - -def cli_check_repo(repo_path: Path, fs_yaml_file: Path): - sys.path.append(str(repo_path)) - if not fs_yaml_file.exists(): - print( - f"Can't find feature repo configuration file at {fs_yaml_file}. " - "Make sure you're running feast from an initialized feast repository." - ) - sys.exit(1) - - -def init_repo(repo_name: str, template: str, repo_path: Optional[str] = None): - import os - from pathlib import Path - from shutil import copytree - - from colorama import Fore, Style - - # Validate project name - if not is_valid_name(repo_name): - raise BadParameter( - message="Name should be alphanumeric values, underscores, and hyphens but not start with an underscore or hyphen", - param_hint="PROJECT_DIRECTORY", - ) - - # Determine where to create the repository - if repo_path: - # User specified a custom path - target_path = Path(repo_path).resolve() - target_path.mkdir(parents=True, exist_ok=True) - display_path = repo_path - else: - # Default behavior: create subdirectory with project name - target_path = Path(os.path.join(Path.cwd(), repo_name)) - target_path.mkdir(exist_ok=True) - display_path = repo_name - - repo_config_path = target_path / "feature_store.yaml" - - if repo_config_path.exists(): - print( - f"The directory {Style.BRIGHT + Fore.GREEN}{display_path}{Style.RESET_ALL} contains an existing feature " - f"store repository that may cause a conflict" - ) - print() - sys.exit(1) - - # Copy template directory - template_path = str(Path(Path(__file__).parent / "templates" / template).absolute()) - if not os.path.exists(template_path): - raise IOError(f"Could not find template {template}") - copytree(template_path, str(target_path), dirs_exist_ok=True) - - # Rename gitignore files back to .gitignore - for gitignore_path in target_path.rglob("gitignore"): - gitignore_path.rename(gitignore_path.with_name(".gitignore")) - - # Seed the repository - bootstrap_path = target_path / "bootstrap.py" - if os.path.exists(bootstrap_path): - import importlib.util - - spec = importlib.util.spec_from_file_location("bootstrap", str(bootstrap_path)) - assert isinstance(spec, ModuleSpec) - bootstrap = importlib.util.module_from_spec(spec) - assert isinstance(spec.loader, Loader) - spec.loader.exec_module(bootstrap) - bootstrap.bootstrap() # type: ignore - os.remove(bootstrap_path) - - # Template the feature_store.yaml file - feature_store_yaml_path = target_path / "feature_repo" / "feature_store.yaml" - replace_str_in_file( - feature_store_yaml_path, "project: my_project", f"project: {repo_name}" - ) - - # Remove the __pycache__ folder if it exists - import shutil - - shutil.rmtree(target_path / "__pycache__", ignore_errors=True) - - import click - - click.echo() - click.echo( - f"Creating a new Feast repository in {Style.BRIGHT + Fore.GREEN}{target_path}{Style.RESET_ALL}." - ) - click.echo() - - -def is_valid_name(name: str) -> bool: - """A name should be alphanumeric values, underscores, and hyphens but not start with an underscore""" - return ( - not name.startswith(("_", "-")) and re.compile(r"[^\w-]+").search(name) is None - ) - - -def generate_project_name() -> str: - """Generates a unique project name""" - return f"{random.choice(adjectives)}_{random.choice(animals)}" +import base64 +import importlib +import json +import logging +import os +import random +import re +import sys +import tempfile +from importlib.abc import Loader +from importlib.machinery import ModuleSpec +from pathlib import Path +from typing import List, Optional, Set, Union + +import click +from click.exceptions import BadParameter + +from feast import PushSource +from feast.batch_feature_view import BatchFeatureView +from feast.constants import FEATURE_STORE_YAML_ENV_NAME +from feast.data_source import DataSource, KafkaSource, KinesisSource +from feast.diff.registry_diff import extract_objects_for_keep_delete_update_add +from feast.entity import Entity +from feast.feature_service import FeatureService +from feast.feature_store import FeatureStore +from feast.feature_view import DUMMY_ENTITY, FeatureView +from feast.file_utils import replace_str_in_file +from feast.infra.registry.base_registry import BaseRegistry +from feast.infra.registry.registry import FEAST_OBJECT_TYPES, FeastObjectType, Registry +from feast.labeling.label_view import LabelView +from feast.names import adjectives, animals +from feast.on_demand_feature_view import OnDemandFeatureView +from feast.permissions.permission import Permission +from feast.project import Project +from feast.repo_config import RepoConfig +from feast.repo_contents import RepoContents +from feast.stream_feature_view import StreamFeatureView + +logger = logging.getLogger(__name__) + + +def py_path_to_module(path: Path) -> str: + return ( + str(path.relative_to(os.getcwd()))[: -len(".py")] + .replace("./", "") + .replace("/", ".") + .replace("\\", ".") + ) + + +def read_feastignore(repo_root: Path) -> List[str]: + """Read .feastignore in the repo root directory (if exists) and return the list of user-defined ignore paths""" + feast_ignore = repo_root / ".feastignore" + if not feast_ignore.is_file(): + return [] + lines = feast_ignore.read_text().strip().split("\n") + ignore_paths = [] + for line in lines: + # Remove everything after the first occurance of "#" symbol (comments) + if line.find("#") >= 0: + line = line[: line.find("#")] + # Strip leading or ending whitespaces + line = line.strip() + # Add this processed line to ignore_paths if it's not empty + if len(line) > 0: + ignore_paths.append(line) + return ignore_paths + + +def get_ignore_files(repo_root: Path, ignore_paths: List[str]) -> Set[Path]: + """Get all ignore files that match any of the user-defined ignore paths""" + ignore_files = set() + for ignore_path in set(ignore_paths): + # ignore_path may contains matchers (* or **). Use glob() to match user-defined path to actual paths + for matched_path in repo_root.glob(ignore_path): + if matched_path.is_file(): + # If the matched path is a file, add that to ignore_files set + ignore_files.add(matched_path.resolve()) + else: + # Otherwise, list all Python files in that directory and add all of them to ignore_files set + ignore_files |= { + sub_path.resolve() + for sub_path in matched_path.glob("**/*.py") + if sub_path.is_file() + } + return ignore_files + + +def get_repo_files(repo_root: Path) -> List[Path]: + """Get the list of all repo files, ignoring undesired files & directories specified in .feastignore""" + # Read ignore paths from .feastignore and create a set of all files that match any of these paths + ignore_paths = read_feastignore(repo_root) + [ + ".git", + ".feastignore", + ".venv", + "**/.ipynb_checkpoints", + "**/.pytest_cache", + "**/__pycache__", + ] + ignore_files = get_ignore_files(repo_root, ignore_paths) + + # List all Python files in the root directory (recursively) + repo_files = { + p.resolve() + for p in repo_root.glob("**/*.py") + if p.is_file() and "__init__.py" != p.name + } + # Ignore all files that match any of the ignore paths in .feastignore + repo_files -= ignore_files + + # Sort repo_files to read them in the same order every time + return sorted(repo_files) + + +def parse_repo(repo_root: Path) -> RepoContents: + """ + Collects unique Feast object definitions from the given feature repo. + + Specifically, if an object foo has already been added, bar will still be added if + (bar == foo), but not if (bar is foo). This ensures that import statements will + not result in duplicates, but defining two equal objects will. + """ + res = RepoContents( + projects=[], + data_sources=[], + entities=[], + feature_views=[], + feature_services=[], + on_demand_feature_views=[], + stream_feature_views=[], + label_views=[], + permissions=[], + ) + + for repo_file in get_repo_files(repo_root): + module_path = py_path_to_module(repo_file) + module = importlib.import_module(module_path) + + for attr_name in dir(module): + obj = getattr(module, attr_name) + + if isinstance(obj, DataSource) and not any( + (obj is ds) for ds in res.data_sources + ): + res.data_sources.append(obj) + + # Handle batch sources defined within stream sources. + if ( + isinstance(obj, PushSource) + or isinstance(obj, KafkaSource) + or isinstance(obj, KinesisSource) + ): + batch_source = obj.batch_source + + if batch_source and not any( + (batch_source is ds) for ds in res.data_sources + ): + res.data_sources.append(batch_source) + if ( + isinstance(obj, FeatureView) + and not any((obj is fv) for fv in res.feature_views) + and not isinstance(obj, StreamFeatureView) + and not isinstance(obj, BatchFeatureView) + ): + res.feature_views.append(obj) + + # Handle batch sources defined with feature views. + batch_source = obj.batch_source + if batch_source is not None and not any( + (batch_source is ds) for ds in res.data_sources + ): + res.data_sources.append(batch_source) + + # Handle stream sources defined with feature views. + if obj.stream_source: + stream_source = obj.stream_source + if not any((stream_source is ds) for ds in res.data_sources): + res.data_sources.append(stream_source) + elif isinstance(obj, StreamFeatureView) and not any( + (obj is sfv) for sfv in res.stream_feature_views + ): + res.stream_feature_views.append(obj) + + # Handle batch sources defined with feature views. + batch_source = obj.batch_source + if batch_source is not None and not any( + (batch_source is ds) for ds in res.data_sources + ): + res.data_sources.append(batch_source) + assert obj.stream_source + stream_source = obj.stream_source + if not any((stream_source is ds) for ds in res.data_sources): + res.data_sources.append(stream_source) + elif isinstance(obj, BatchFeatureView) and not any( + (obj is bfv) for bfv in res.feature_views + ): + res.feature_views.append(obj) + + # Handle batch sources defined with feature views. + batch_source = obj.batch_source + if batch_source is not None and not any( + (batch_source is ds) for ds in res.data_sources + ): + res.data_sources.append(batch_source) + elif isinstance(obj, Entity) and not any( + (obj is entity) for entity in res.entities + ): + res.entities.append(obj) + elif isinstance(obj, FeatureService) and not any( + (obj is fs) for fs in res.feature_services + ): + res.feature_services.append(obj) + elif isinstance(obj, OnDemandFeatureView) and not any( + (obj is odfv) for odfv in res.on_demand_feature_views + ): + res.on_demand_feature_views.append(obj) + elif isinstance(obj, LabelView) and not any( + (obj is lv) for lv in res.label_views + ): + res.label_views.append(obj) + if obj.source is not None and not any( + (obj.source is ds) for ds in res.data_sources + ): + res.data_sources.append(obj.source) + if ( + isinstance(obj.source, PushSource) + and obj.source.batch_source + and not any( + (obj.source.batch_source is ds) for ds in res.data_sources + ) + ): + res.data_sources.append(obj.source.batch_source) + elif isinstance(obj, Permission) and not any( + (obj is p) for p in res.permissions + ): + res.permissions.append(obj) + elif isinstance(obj, Project) and not any((obj is p) for p in res.projects): + res.projects.append(obj) + + res.entities.append(DUMMY_ENTITY) + return res + + +def plan( + repo_config: RepoConfig, + repo_path: Path, + skip_source_validation: bool, + skip_feature_view_validation: bool = False, +): + os.chdir(repo_path) + repo = _get_repo_contents(repo_path, repo_config.project, repo_config) + for project in repo.projects: + repo_config.project = project.name + store, registry = _get_store_and_registry(repo_config) + # TODO: When we support multiple projects in a single repo, we should filter repo contents by project + if not skip_source_validation: + provider = store._get_provider() + data_sources = [ + t.batch_source for t in repo.feature_views if t.batch_source is not None + ] + # Make sure the data source used by this feature view is supported by Feast + for data_source in data_sources: + provider.validate_data_source(store.config, data_source) + + registry_diff, infra_diff, _ = store.plan( + repo, skip_feature_view_validation=skip_feature_view_validation + ) + click.echo(registry_diff.to_string()) + click.echo(infra_diff.to_string()) + + +def _get_repo_contents( + repo_path, + project_name: Optional[str] = None, + repo_config: Optional[RepoConfig] = None, +): + sys.dont_write_bytecode = True + repo = parse_repo(repo_path) + + if len(repo.projects) < 1: + if project_name: + print( + f"No project found in the repository. Using project name {project_name} defined in feature_store.yaml" + ) + project_description = ( + repo_config.project_description if repo_config else None + ) + repo.projects.append( + Project(name=project_name, description=project_description or "") + ) + else: + print( + "No project found in the repository. Either define Project in repository or define a project in feature_store.yaml" + ) + sys.exit(1) + elif len(repo.projects) == 1: + if repo.projects[0].name != project_name: + print( + "Project object name should match with the project name defined in feature_store.yaml" + ) + sys.exit(1) + else: + print( + "Multiple projects found in the repository. Currently no support for multiple projects" + ) + sys.exit(1) + + return repo + + +def _get_store_and_registry(repo_config): + store = FeatureStore(config=repo_config) + registry = store.registry + return store, registry + + +def extract_objects_for_apply_delete(project, registry, repo): + # TODO(achals): This code path should be refactored to handle added & kept entities separately. + ( + _, + objs_to_delete, + objs_to_update, + objs_to_add, + ) = extract_objects_for_keep_delete_update_add(registry, project, repo) + + all_to_apply: List[ + Union[ + Entity, + FeatureView, + OnDemandFeatureView, + StreamFeatureView, + FeatureService, + ] + ] = [] + for object_type in FEAST_OBJECT_TYPES: + to_apply = set(objs_to_add[object_type]).union(objs_to_update[object_type]) + all_to_apply.extend(to_apply) + + all_to_delete: List[ + Union[ + Entity, + FeatureView, + OnDemandFeatureView, + StreamFeatureView, + FeatureService, + ] + ] = [] + for object_type in FEAST_OBJECT_TYPES: + all_to_delete.extend(objs_to_delete[object_type]) + + return ( + all_to_apply, + all_to_delete, + set(objs_to_add[FeastObjectType.FEATURE_VIEW]).union( + set(objs_to_update[FeastObjectType.FEATURE_VIEW]) + ), + objs_to_delete[FeastObjectType.FEATURE_VIEW], + ) + + +def apply_total_with_repo_instance( + store: FeatureStore, + project_name: str, + registry: BaseRegistry, + repo: RepoContents, + skip_source_validation: bool, + skip_feature_view_validation: bool = False, + no_promote: bool = False, +): + if not skip_source_validation: + provider = store._get_provider() + data_sources = [ + t.batch_source for t in repo.feature_views if t.batch_source is not None + ] + # Make sure the data source used by this feature view is supported by Feast + for data_source in data_sources: + provider.validate_data_source(store.config, data_source) + + # For each object in the registry, determine whether it should be kept or deleted. + ( + all_to_apply, + all_to_delete, + views_to_keep, + views_to_delete, + ) = extract_objects_for_apply_delete(project_name, registry, repo) + + try: + if store._should_use_plan(): + # Planning phase - compute diffs first without progress bars + registry_diff, infra_diff, new_infra = store.plan( + repo, + skip_feature_view_validation=skip_feature_view_validation, + ) + click.echo(registry_diff.to_string()) + + # Only show progress bars if there are actual infrastructure changes + progress_ctx = None + if len(infra_diff.infra_object_diffs) > 0: + from feast.diff.apply_progress import ApplyProgressContext + + progress_ctx = ApplyProgressContext() + progress_ctx.start_overall_progress() + + # Apply phase + store._apply_diffs( + registry_diff, + infra_diff, + new_infra, + progress_ctx=progress_ctx, + no_promote=no_promote, + ) + click.echo(infra_diff.to_string()) + else: + # Legacy apply path - no progress bars for legacy path + store.apply( + all_to_apply, + objects_to_delete=all_to_delete, + partial=False, + skip_feature_view_validation=skip_feature_view_validation, + no_promote=no_promote, + ) + log_infra_changes(views_to_keep, views_to_delete) + finally: + # Cleanup is handled in the new _apply_diffs method + pass + + # Submit baseline jobs if needed + dqm = store.config.data_quality_monitoring_config + if dqm is not None and dqm.auto_baseline: + _submit_baseline_jobs(store, project_name, repo) + + +def _submit_baseline_jobs(store, project_name, repo): + try: + from feast.monitoring.monitoring_service import MonitoringService + + svc = MonitoringService(store) + feature_views = list(repo.feature_views) + if not feature_views: + return + + job_ids = svc.submit_baseline_for_new_features( + project=project_name, feature_views=feature_views + ) + if not job_ids: + return + + import threading + + def _run_baseline_jobs(): + for job_id in job_ids: + try: + svc.execute_job(job_id) + click.echo(f" ✓ Baseline computed (job: {job_id})") + except Exception: + logging.getLogger(__name__).debug( + "Baseline job %s execution failed (non-critical)", + job_id, + exc_info=True, + ) + + click.echo( + f" → Computing baseline metrics in background ({len(job_ids)} job(s))..." + ) + thread = threading.Thread(target=_run_baseline_jobs) + thread.start() + except Exception: + logging.getLogger(__name__).debug( + "Monitoring baseline submission skipped (non-critical)", exc_info=True + ) + + +def log_infra_changes( + views_to_keep: Set[FeatureView], views_to_delete: Set[FeatureView] +): + from colorama import Fore, Style + + for view in views_to_keep: + click.echo( + f"Deploying infrastructure for {Style.BRIGHT + Fore.GREEN}{view.name}{Style.RESET_ALL}" + ) + for view in views_to_delete: + click.echo( + f"Removing infrastructure for {Style.BRIGHT + Fore.RED}{view.name}{Style.RESET_ALL}" + ) + + +def create_feature_store( + ctx: click.Context, +) -> FeatureStore: + repo = ctx.obj["CHDIR"] + # If we received a base64 encoded version of feature_store.yaml, use that + config_base64 = os.getenv(FEATURE_STORE_YAML_ENV_NAME) + if config_base64: + print("Received base64 encoded feature_store.yaml") + config_bytes = base64.b64decode(config_base64) + # Create a new unique directory for writing feature_store.yaml + repo_path = Path(tempfile.mkdtemp()) + with open(repo_path / "feature_store.yaml", "wb") as f: + f.write(config_bytes) + return FeatureStore(repo_path=str(repo_path.resolve())) + else: + fs_yaml_file = ctx.obj["FS_YAML_FILE"] + cli_check_repo(repo, fs_yaml_file) + return FeatureStore(repo_path=str(repo), fs_yaml_file=fs_yaml_file) + + +def apply_total( + repo_config: RepoConfig, + repo_path: Path, + skip_source_validation: bool, + skip_feature_view_validation: bool = False, + no_promote: bool = False, +): + os.chdir(repo_path) + repo = _get_repo_contents(repo_path, repo_config.project, repo_config) + for project in repo.projects: + repo_config.project = project.name + store, registry = _get_store_and_registry(repo_config) + if not is_valid_name(project.name): + print( + f"{project.name} is not valid. Project name should only have " + f"alphanumerical values, underscores, and hyphens but not start with an underscore or hyphen." + ) + sys.exit(1) + # TODO: When we support multiple projects in a single repo, we should filter repo contents by project. Currently there is no way to associate Feast objects to project. + print(f"Applying changes for project {project.name}") + apply_total_with_repo_instance( + store, + project.name, + registry, + repo, + skip_source_validation, + skip_feature_view_validation, + no_promote=no_promote, + ) + + +def teardown(repo_config: RepoConfig, repo_path: Optional[str]): + # Cannot pass in both repo_path and repo_config to FeatureStore. + feature_store = FeatureStore(repo_path=repo_path, config=repo_config) + feature_store.teardown() + + +def registry_dump(repo_config: RepoConfig, repo_path: Path) -> str: + """For debugging only: output contents of the metadata registry""" + registry_config = repo_config.registry + project = repo_config.project + registry = Registry( + project, + registry_config=registry_config, + repo_path=repo_path, + auth_config=repo_config.auth_config, + ) + registry_dict = registry.to_dict(project=project) + return json.dumps(registry_dict, indent=2, sort_keys=True) + + +def cli_check_repo(repo_path: Path, fs_yaml_file: Path): + sys.path.append(str(repo_path)) + if not fs_yaml_file.exists(): + print( + f"Can't find feature repo configuration file at {fs_yaml_file}. " + "Make sure you're running feast from an initialized feast repository." + ) + sys.exit(1) + + +def init_repo(repo_name: str, template: str, repo_path: Optional[str] = None): + import os + from pathlib import Path + from shutil import copytree + + from colorama import Fore, Style + + # Validate project name + if not is_valid_name(repo_name): + raise BadParameter( + message="Name should be alphanumeric values, underscores, and hyphens but not start with an underscore or hyphen", + param_hint="PROJECT_DIRECTORY", + ) + + # Determine where to create the repository + if repo_path: + # User specified a custom path + target_path = Path(repo_path).resolve() + target_path.mkdir(parents=True, exist_ok=True) + display_path = repo_path + else: + # Default behavior: create subdirectory with project name + target_path = Path(os.path.join(Path.cwd(), repo_name)) + target_path.mkdir(exist_ok=True) + display_path = repo_name + + repo_config_path = target_path / "feature_store.yaml" + + if repo_config_path.exists(): + print( + f"The directory {Style.BRIGHT + Fore.GREEN}{display_path}{Style.RESET_ALL} contains an existing feature " + f"store repository that may cause a conflict" + ) + print() + sys.exit(1) + + # Copy template directory + template_path = str(Path(Path(__file__).parent / "templates" / template).absolute()) + if not os.path.exists(template_path): + raise IOError(f"Could not find template {template}") + copytree(template_path, str(target_path), dirs_exist_ok=True) + + # Rename gitignore files back to .gitignore + for gitignore_path in target_path.rglob("gitignore"): + gitignore_path.rename(gitignore_path.with_name(".gitignore")) + + # Seed the repository + bootstrap_path = target_path / "bootstrap.py" + if os.path.exists(bootstrap_path): + import importlib.util + + spec = importlib.util.spec_from_file_location("bootstrap", str(bootstrap_path)) + assert isinstance(spec, ModuleSpec) + bootstrap = importlib.util.module_from_spec(spec) + assert isinstance(spec.loader, Loader) + spec.loader.exec_module(bootstrap) + bootstrap.bootstrap() # type: ignore + os.remove(bootstrap_path) + + # Template the feature_store.yaml file + feature_store_yaml_path = target_path / "feature_repo" / "feature_store.yaml" + replace_str_in_file( + feature_store_yaml_path, "project: my_project", f"project: {repo_name}" + ) + + # Remove the __pycache__ folder if it exists + import shutil + + shutil.rmtree(target_path / "__pycache__", ignore_errors=True) + + import click + + click.echo() + click.echo( + f"Creating a new Feast repository in {Style.BRIGHT + Fore.GREEN}{target_path}{Style.RESET_ALL}." + ) + click.echo() + + +def is_valid_name(name: str) -> bool: + """A name should be alphanumeric values, underscores, and hyphens but not start with an underscore""" + return ( + not name.startswith(("_", "-")) and re.compile(r"[^\w-]+").search(name) is None + ) + + +def generate_project_name() -> str: + """Generates a unique project name""" + return f"{random.choice(adjectives)}_{random.choice(animals)}" diff --git a/sdk/python/feast/rest_error_handler.py b/sdk/python/feast/rest_error_handler.py index c8586c826e9..a4a4d685597 100644 --- a/sdk/python/feast/rest_error_handler.py +++ b/sdk/python/feast/rest_error_handler.py @@ -39,7 +39,6 @@ def rest_error_handling_decorator(func): def wrapper(config: RepoConfig, *args, **kwargs): assert isinstance(config, RepoConfig) - # Extract connection pool configuration from online_store if available pool_maxsize = None max_idle_seconds = None max_retries = None @@ -58,7 +57,6 @@ def wrapper(config: RepoConfig, *args, **kwargs): max_idle_seconds = conn_config["max_idle_seconds"] max_retries = conn_config["max_retries"] - # Get a cached session with connection pooling session = get_http_auth_requests_session( config.auth_config, pool_maxsize=pool_maxsize, @@ -66,39 +64,46 @@ def wrapper(config: RepoConfig, *args, **kwargs): max_retries=max_retries, ) - # Define a wrapper for session methods to add logging and error handling - def method_wrapper(method_name): - original_method = getattr(session, method_name) - - @wraps(original_method) - def wrapped_method(*args, **kwargs): - logger.debug( - f"Calling {method_name} with args: {args}, kwargs: {kwargs}" - ) - response = original_method(*args, **kwargs) - logger.debug( - f"{method_name} response status code: {response.status_code}" - ) - - try: - response.raise_for_status() - except requests.RequestException: - logger.debug(f"response.json() = {response.json()}") - mapped_error = FeastError.from_error_detail(response.json()) - logger.debug(f"mapped_error = {str(mapped_error)}") - if mapped_error is not None: - raise mapped_error - return response - - return wrapped_method - - # Enhance session methods with logging and error handling - session.get = method_wrapper("get") # type: ignore[method-assign] - session.post = method_wrapper("post") # type: ignore[method-assign] - session.put = method_wrapper("put") # type: ignore[method-assign] - session.delete = method_wrapper("delete") # type: ignore[method-assign] - - # Pass the enhanced session object to the decorated function + _wrap_session_methods(session) + return func(session, config, *args, **kwargs) return wrapper + + +_ATTR_WRAPPED = "_feast_methods_wrapped" + + +def _wrap_session_methods(session: requests.Session) -> None: + """ + Wrap session HTTP methods with logging and Feast error mapping. + + Wraps each method exactly once. Subsequent calls are no-ops, preventing + the unbounded nesting that leads to ``RecursionError`` when a cached + session is reused across many requests. + """ + if getattr(session, _ATTR_WRAPPED, False): + return + + for method_name in ("get", "post", "put", "delete"): + original_method = getattr(session, method_name) + + @wraps(original_method) + def wrapped_method(*args, _orig=original_method, _name=method_name, **kwargs): + logger.debug(f"Calling {_name} with args: {args}, kwargs: {kwargs}") + response = _orig(*args, **kwargs) + logger.debug(f"{_name} response status code: {response.status_code}") + + try: + response.raise_for_status() + except requests.RequestException: + logger.debug(f"response.json() = {response.json()}") + mapped_error = FeastError.from_error_detail(response.json()) + logger.debug(f"mapped_error = {str(mapped_error)}") + if mapped_error is not None: + raise mapped_error + return response + + setattr(session, method_name, wrapped_method) + + object.__setattr__(session, _ATTR_WRAPPED, True) diff --git a/sdk/python/feast/saved_dataset.py b/sdk/python/feast/saved_dataset.py index 4a3043a8731..9ed69861d4b 100644 --- a/sdk/python/feast/saved_dataset.py +++ b/sdk/python/feast/saved_dataset.py @@ -34,6 +34,7 @@ def __new__(cls, name, bases, dct): _DATA_SOURCE_TO_SAVED_DATASET_STORAGE = { "FileSource": "feast.infra.offline_stores.file_source.SavedDatasetFileStorage", + "SparkSource": "feast.infra.offline_stores.contrib.spark_offline_store.spark_source.SavedDatasetSparkStorage", } diff --git a/sdk/python/feast/stream_feature_view.py b/sdk/python/feast/stream_feature_view.py index b8f410f9a48..c2b4625214a 100644 --- a/sdk/python/feast/stream_feature_view.py +++ b/sdk/python/feast/stream_feature_view.py @@ -12,6 +12,7 @@ from feast import flags_helper, utils from feast.aggregation import Aggregation +from feast.base_feature_view import BaseFeatureView from feast.data_source import DataSource from feast.entity import Entity from feast.feature_view import FeatureView @@ -66,6 +67,8 @@ class StreamFeatureView(FeatureView): description: A human-readable description. tags: A dictionary of key-value pairs to store arbitrary metadata. owner: The owner of the stream feature view, typically the email of the primary maintainer. + org: The organizational unit that owns this stream feature view (e.g. "ads", "search"). + Defaults to empty string. udf: The user defined transformation function. This transformation function should have all of the corresponding imports imported within the function. udf_string: The string representation of the user defined transformation function. feature_transformation: The transformation to apply to the features. @@ -87,6 +90,7 @@ class StreamFeatureView(FeatureView): description: str tags: Dict[str, str] owner: str + org: str mode: Union[TransformationMode, str] materialization_intervals: List[Tuple[datetime, datetime]] udf: Optional[FunctionType] @@ -97,6 +101,8 @@ class StreamFeatureView(FeatureView): timestamp_field: str enable_tiling: bool tiling_hop_size: Optional[timedelta] + _raw_udf_proto: Optional[Any] = None + _raw_feature_transformation_proto: Optional[Any] = None def __init__( self, @@ -111,6 +117,7 @@ def __init__( offline: bool = False, description: str = "", owner: str = "", + org: str = "", schema: Optional[List[Field]] = None, aggregations: Optional[List[Aggregation]] = None, mode: Union[str, TransformationMode] = TransformationMode.PYTHON, @@ -122,6 +129,7 @@ def __init__( enable_tiling: bool = False, tiling_hop_size: Optional[timedelta] = None, enable_validation: bool = False, + version: str = "latest", ): if not flags_helper.is_test(): warnings.warn( @@ -181,11 +189,13 @@ def __init__( offline=offline, description=description, owner=owner, + org=org, schema=schema, source=source, # type: ignore[arg-type] mode=mode, sink_source=sink_source, enable_validation=enable_validation, + version=version, ) def get_feature_transformation(self) -> Optional[Transformation]: @@ -197,7 +207,8 @@ def get_feature_transformation(self) -> Optional[Transformation]: TransformationMode.PYTHON, TransformationMode.SPARK_SQL, TransformationMode.SPARK, - ) or self.mode in ("pandas", "python", "spark_sql", "spark"): + TransformationMode.FLINK, + ) or self.mode in ("pandas", "python", "spark_sql", "spark", "flink"): return Transformation( mode=self.mode, udf=self.udf, udf_string=self.udf_string or "" ) @@ -206,6 +217,35 @@ def get_feature_transformation(self) -> Optional[Transformation]: f"Unsupported transformation mode: {self.mode} for StreamFeatureView" ) + def _schema_or_udf_changed(self, other: "BaseFeatureView") -> bool: + """Check for StreamFeatureView schema/UDF changes.""" + if super()._schema_or_udf_changed(other): + return True + + if not isinstance(other, StreamFeatureView): + return True + + # UDF changes + if self.udf and other.udf: + self_code = getattr(self.udf, "__code__", None) + other_code = getattr(other.udf, "__code__", None) + if self_code and other_code: + if self_code.co_code != other_code.co_code: + return True + elif self.udf != other.udf: # One is None + return True + + if self.udf_string != other.udf_string: + return True + if self.aggregations != other.aggregations: + return True + if self.timestamp_field != other.timestamp_field: + return True + if self.mode != other.mode: + return True + + return False + def __eq__(self, other): if not isinstance(other, StreamFeatureView): raise TypeError("Comparisons should only involve StreamFeatureViews") @@ -240,7 +280,12 @@ def to_proto(self): stream_source_proto = serialize_data_source(self.stream_source) udf_proto, feature_transformation = None, None - if self.udf: + if getattr(self, "_raw_udf_proto", None) is not None: + udf_proto = self._raw_udf_proto + feature_transformation = getattr( + self, "_raw_feature_transformation_proto", None + ) + elif self.udf: udf_proto = UserDefinedFunctionProto( name=self.udf.__name__, body=dill.dumps(self.udf, recurse=True), @@ -272,6 +317,7 @@ def to_proto(self): description=self.description, tags=self.tags, owner=self.owner, + org=self.org, ttl=ttl_duration, online=self.online, batch_source=batch_source_proto, @@ -282,12 +328,14 @@ def to_proto(self): enable_tiling=self.enable_tiling, tiling_hop_size=tiling_hop_size_duration, enable_validation=self.enable_validation, + version=self.version, + disabled=not self.enabled, ) return StreamFeatureViewProto(spec=spec, meta=meta) @classmethod - def from_proto(cls, sfv_proto): + def from_proto(cls, sfv_proto, skip_udf: bool = False): batch_source = ( DataSource.from_proto(sfv_proto.spec.batch_source) if sfv_proto.spec.HasField("batch_source") @@ -300,7 +348,7 @@ def from_proto(cls, sfv_proto): ) udf = ( dill.loads(sfv_proto.spec.user_defined_function.body) - if sfv_proto.spec.HasField("user_defined_function") + if sfv_proto.spec.HasField("user_defined_function") and not skip_udf else None ) udf_string = ( @@ -318,6 +366,7 @@ def from_proto(cls, sfv_proto): description=sfv_proto.spec.description, tags=dict(sfv_proto.spec.tags), owner=sfv_proto.spec.owner, + org=sfv_proto.spec.org, online=sfv_proto.spec.online, schema=[ Field.from_proto(field_proto) for field_proto in sfv_proto.spec.features @@ -344,6 +393,7 @@ def from_proto(cls, sfv_proto): else None ), enable_validation=sfv_proto.spec.enable_validation, + version=sfv_proto.spec.version or "latest", ) if batch_source: @@ -352,6 +402,30 @@ def from_proto(cls, sfv_proto): if stream_source: stream_feature_view.stream_source = stream_source + # Restore current_version_number from meta. + spec_version = sfv_proto.spec.version + cvn = sfv_proto.meta.current_version_number + if cvn > 0: + stream_feature_view.current_version_number = cvn + elif cvn == 0 and spec_version and spec_version.lower() != "latest": + stream_feature_view.current_version_number = 0 + else: + stream_feature_view.current_version_number = None + + stream_feature_view.enabled = not sfv_proto.spec.disabled + + # Restore lifecycle state from meta (SFV uses FeatureViewMeta which has state). + from feast.feature_view import FeatureViewState + + stream_feature_view.state = FeatureViewState.from_proto(sfv_proto.meta.state) + + if skip_udf and sfv_proto.spec.HasField("user_defined_function"): + stream_feature_view._raw_udf_proto = sfv_proto.spec.user_defined_function + if skip_udf and sfv_proto.spec.HasField("feature_transformation"): + stream_feature_view._raw_feature_transformation_proto = ( + sfv_proto.spec.feature_transformation + ) + stream_feature_view.entities = list(sfv_proto.spec.entities) stream_feature_view.features = [ @@ -390,6 +464,7 @@ def __copy__(self): online=self.online, description=self.description, owner=self.owner, + org=self.org, aggregations=self.aggregations, mode=self.mode, timestamp_field=self.timestamp_field, @@ -398,7 +473,10 @@ def __copy__(self): udf_string=self.udf_string, feature_transformation=self.feature_transformation, enable_validation=self.enable_validation, + version=self.version, ) + fv.enabled = self.enabled + fv.state = self.state fv.entities = self.entities fv.features = copy.copy(self.features) fv.entity_columns = copy.copy(self.entity_columns) @@ -418,12 +496,14 @@ def stream_feature_view( online: Optional[bool] = True, description: Optional[str] = "", owner: Optional[str] = "", + org: Optional[str] = "", schema: Optional[List[Field]] = None, source: Optional[DataSource] = None, aggregations: Optional[List[Aggregation]] = None, mode: Optional[str] = "spark", timestamp_field: Optional[str] = "", enable_validation: bool = False, + version: str = "latest", ): """ Creates an StreamFeatureView object with the given user function as udf. @@ -452,10 +532,12 @@ def decorator(user_function): tags=tags, online=online, owner=owner, + org=org, aggregations=aggregations, mode=mode, timestamp_field=timestamp_field, enable_validation=enable_validation, + version=version, ) functools.update_wrapper(wrapper=stream_feature_view_obj, wrapped=user_function) return stream_feature_view_obj diff --git a/sdk/python/feast/templates/athena/feature_repo/test_workflow.py b/sdk/python/feast/templates/athena/feature_repo/test_workflow.py index 8d6479da80e..8bbdb07f161 100644 --- a/sdk/python/feast/templates/athena/feature_repo/test_workflow.py +++ b/sdk/python/feast/templates/athena/feature_repo/test_workflow.py @@ -50,6 +50,7 @@ def test_end_to_end(): ], online=True, source=driver_hourly_stats, + version="latest", ) # apply repository diff --git a/sdk/python/feast/templates/aws/feature_repo/feature_definitions.py b/sdk/python/feast/templates/aws/feature_repo/feature_definitions.py index dd5a9c925b7..8d4faf4c74c 100644 --- a/sdk/python/feast/templates/aws/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/aws/feature_repo/feature_definitions.py @@ -57,6 +57,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -119,6 +120,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/cassandra/feature_repo/feature_definitions.py b/sdk/python/feast/templates/cassandra/feature_repo/feature_definitions.py index 131f1bcaa61..21b2985409e 100644 --- a/sdk/python/feast/templates/cassandra/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/cassandra/feature_repo/feature_definitions.py @@ -52,6 +52,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -114,6 +115,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/couchbase/feature_repo/feature_definitions.py b/sdk/python/feast/templates/couchbase/feature_repo/feature_definitions.py index 363ba3c4664..802f251ca5a 100644 --- a/sdk/python/feast/templates/couchbase/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/couchbase/feature_repo/feature_definitions.py @@ -47,6 +47,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -109,6 +110,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/gcp/feature_repo/feature_definitions.py b/sdk/python/feast/templates/gcp/feature_repo/feature_definitions.py index 81e06c72018..5eda02ea5d2 100644 --- a/sdk/python/feast/templates/gcp/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/gcp/feature_repo/feature_definitions.py @@ -61,6 +61,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -123,6 +124,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/hazelcast/feature_repo/feature_definitions.py b/sdk/python/feast/templates/hazelcast/feature_repo/feature_definitions.py index 131f1bcaa61..21b2985409e 100644 --- a/sdk/python/feast/templates/hazelcast/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/hazelcast/feature_repo/feature_definitions.py @@ -52,6 +52,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -114,6 +115,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/hbase/feature_repo/feature_definitions.py b/sdk/python/feast/templates/hbase/feature_repo/feature_definitions.py index 131f1bcaa61..21b2985409e 100644 --- a/sdk/python/feast/templates/hbase/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/hbase/feature_repo/feature_definitions.py @@ -52,6 +52,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -114,6 +115,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/local/bootstrap.py b/sdk/python/feast/templates/local/bootstrap.py index bd180ade01e..1732bb1ef78 100644 --- a/sdk/python/feast/templates/local/bootstrap.py +++ b/sdk/python/feast/templates/local/bootstrap.py @@ -7,6 +7,9 @@ def bootstrap(): import pathlib from datetime import datetime, timedelta + import pyarrow as pa + import pyarrow.parquet as pq + from feast.driver_test_data import create_driver_hourly_stats_df repo_path = pathlib.Path(__file__).parent.absolute() / "feature_repo" @@ -23,6 +26,25 @@ def bootstrap(): driver_stats_path = data_path / "driver_stats.parquet" driver_df.to_parquet(path=str(driver_stats_path), allow_truncated_timestamps=True) + # Create an empty parquet file for the label view batch source + # Use explicit pyarrow schema to ensure proper column types even with zero rows + label_schema = pa.schema( + [ + ("driver_id", pa.int64()), + ("is_reliable", pa.int64()), + ("quality_score", pa.float32()), + ("reviewer_notes", pa.string()), + ("labeler", pa.string()), + ("event_timestamp", pa.timestamp("ns")), + ] + ) + label_table = pa.table( + {field.name: pa.array([], type=field.type) for field in label_schema}, + schema=label_schema, + ) + label_data_path = data_path / "driver_quality_labels.parquet" + pq.write_table(label_table, str(label_data_path)) + example_py_file = repo_path / "feature_definitions.py" replace_str_in_file(example_py_file, "%PROJECT_NAME%", str(project_name)) replace_str_in_file( @@ -31,6 +53,11 @@ def bootstrap(): replace_str_in_file( example_py_file, "%LOGGING_PATH%", str(data_path.relative_to(repo_path)) ) + replace_str_in_file( + example_py_file, + "%LABEL_DATA_PATH%", + str(label_data_path.relative_to(repo_path)), + ) if __name__ == "__main__": diff --git a/sdk/python/feast/templates/local/feature_repo/feature_definitions.py b/sdk/python/feast/templates/local/feature_repo/feature_definitions.py index 6fe94a5fa59..97babb9018a 100644 --- a/sdk/python/feast/templates/local/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/local/feature_repo/feature_definitions.py @@ -5,11 +5,13 @@ import pandas as pd from feast import ( + ConflictPolicy, Entity, FeatureService, FeatureView, Field, FileSource, + LabelView, Project, PushSource, RequestSource, @@ -72,6 +74,7 @@ # feature view tags={"team": "driver_performance"}, enable_validation=True, + version="latest", ) # Define a request data source which encodes features / information only @@ -140,6 +143,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) @@ -163,3 +167,41 @@ def transformed_conv_rate_fresh(inputs: pd.DataFrame) -> pd.DataFrame: name="driver_activity_v3", features=[driver_stats_fresh_fv, transformed_conv_rate_fresh], ) + +# --- Label Views --- +# Label views manage mutable human labels for training data, RLHF, and evaluation. +# They use PushSources so labels can be submitted from the UI or external tools. + +driver_quality_labels_source = PushSource( + name="driver_quality_labels_push", + batch_source=FileSource( + name="driver_quality_labels_batch", + path="%LABEL_DATA_PATH%", + timestamp_field="event_timestamp", + ), +) + +driver_quality_labels = LabelView( + name="driver_quality_labels", + entities=[driver], + schema=[ + Field(name="is_reliable", dtype=Int64), + Field(name="quality_score", dtype=Float32), + Field(name="reviewer_notes", dtype=String), + Field(name="labeler", dtype=String), + ], + source=driver_quality_labels_source, + labeler_field="labeler", + conflict_policy=ConflictPolicy.LAST_WRITE_WINS, + description="Human quality labels for drivers - used for model training and evaluation", + tags={ + "feast.io/labeling-method": "table", + "feast.io/field-role:is_reliable": "label", + "feast.io/field-role:quality_score": "label", + "feast.io/field-role:reviewer_notes": "metadata", + "feast.io/label-values:is_reliable": "1,0", + "feast.io/label-widget:is_reliable": "binary", + "feast.io/label-widget:quality_score": "number", + "feast.io/label-widget:reviewer_notes": "text", + }, +) diff --git a/sdk/python/feast/templates/milvus/feature_repo/feature_definitions.py b/sdk/python/feast/templates/milvus/feature_repo/feature_definitions.py index e2fd0a891cf..31f3af3c26d 100644 --- a/sdk/python/feast/templates/milvus/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/milvus/feature_repo/feature_definitions.py @@ -58,6 +58,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -123,6 +124,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/postgres/bootstrap.py b/sdk/python/feast/templates/postgres/bootstrap.py index 6ed13e4e39a..37daacb0df0 100644 --- a/sdk/python/feast/templates/postgres/bootstrap.py +++ b/sdk/python/feast/templates/postgres/bootstrap.py @@ -29,11 +29,25 @@ def bootstrap(): postgres_schema = click.prompt("Postgres schema", default="public") postgres_user = click.prompt("Postgres user") postgres_password = click.prompt("Postgres password", hide_input=True) + postgres_sslmode = click.prompt( + "Postgres sslmode (disable, allow, prefer, require, verify-ca, verify-full)", + default="require", + ) if click.confirm( 'Should I upload example data to Postgres (overwriting "feast_driver_hourly_stats" table)?', default=True, ): + config = PostgreSQLConfig( + host=postgres_host, + port=int(postgres_port), + database=postgres_database, + db_schema=postgres_schema, + user=postgres_user, + password=postgres_password, + sslmode=postgres_sslmode, + ) + db_connection = psycopg.connect( conninfo=( f"postgresql://{postgres_user}" @@ -42,6 +56,7 @@ def bootstrap(): f":{int(postgres_port)}" f"/{postgres_database}" ), + sslmode=postgres_sslmode, options=f"-c search_path={postgres_schema}", ) @@ -49,14 +64,7 @@ def bootstrap(): cur.execute('DROP TABLE IF EXISTS "feast_driver_hourly_stats"') df_to_postgres_table( - config=PostgreSQLConfig( - host=postgres_host, - port=int(postgres_port), - database=postgres_database, - db_schema=postgres_schema, - user=postgres_user, - password=postgres_password, - ), + config=config, df=driver_df, table_name="feast_driver_hourly_stats", ) @@ -67,6 +75,7 @@ def bootstrap(): replace_str_in_file(config_file, "DB_SCHEMA", postgres_schema) replace_str_in_file(config_file, "DB_USERNAME", postgres_user) replace_str_in_file(config_file, "DB_PASSWORD", postgres_password) + replace_str_in_file(config_file, "DB_SSLMODE", postgres_sslmode) if __name__ == "__main__": diff --git a/sdk/python/feast/templates/postgres/feature_repo/feature_definitions.py b/sdk/python/feast/templates/postgres/feature_repo/feature_definitions.py index 0d1783e1e5e..073f18e43f5 100644 --- a/sdk/python/feast/templates/postgres/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/postgres/feature_repo/feature_definitions.py @@ -44,6 +44,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -106,6 +107,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/postgres/feature_repo/feature_store.yaml b/sdk/python/feast/templates/postgres/feature_repo/feature_store.yaml index a2fc2f51b61..ed80a5ff3e9 100644 --- a/sdk/python/feast/templates/postgres/feature_repo/feature_store.yaml +++ b/sdk/python/feast/templates/postgres/feature_repo/feature_store.yaml @@ -2,7 +2,7 @@ project: my_project provider: local registry: registry_type: sql - path: postgresql://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_NAME + path: postgresql://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_NAME?sslmode=DB_SSLMODE cache_ttl_seconds: 60 sqlalchemy_config_kwargs: echo: false @@ -15,6 +15,7 @@ online_store: db_schema: DB_SCHEMA user: DB_USERNAME password: DB_PASSWORD + sslmode: DB_SSLMODE offline_store: type: postgres host: DB_HOST @@ -23,4 +24,5 @@ offline_store: db_schema: DB_SCHEMA user: DB_USERNAME password: DB_PASSWORD + sslmode: DB_SSLMODE entity_key_serialization_version: 3 diff --git a/sdk/python/feast/templates/pytorch_nlp/feature_repo/example_repo.py b/sdk/python/feast/templates/pytorch_nlp/feature_repo/example_repo.py index ee49bea2899..80d1b9aa7bd 100644 --- a/sdk/python/feast/templates/pytorch_nlp/feature_repo/example_repo.py +++ b/sdk/python/feast/templates/pytorch_nlp/feature_repo/example_repo.py @@ -96,6 +96,7 @@ online=True, source=sentiment_source, tags={"team": "nlp", "domain": "sentiment_analysis"}, + version="latest", ) # Feature view for user-level aggregations @@ -123,6 +124,7 @@ online=True, source=sentiment_source, tags={"team": "nlp", "domain": "user_behavior"}, + version="latest", ) # Request source for real-time inference diff --git a/sdk/python/feast/templates/ray/feature_repo/feature_definitions.py b/sdk/python/feast/templates/ray/feature_repo/feature_definitions.py index 0b2df66de34..741f38cf889 100644 --- a/sdk/python/feast/templates/ray/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/ray/feature_repo/feature_definitions.py @@ -8,7 +8,7 @@ from pathlib import Path from feast import Entity, FeatureService, FeatureView, Field, ValueType -from feast.infra.offline_stores.file_source import FileSource +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import RaySource from feast.on_demand_feature_view import on_demand_feature_view from feast.types import Float32, Float64, Int64 @@ -30,17 +30,21 @@ join_keys=["customer_id"], ) -# Data sources - Ray offline store works with FileSource -# These will be processed by Ray for efficient distributed data access -driver_hourly_stats = FileSource( +# Data sources — RaySource is the recommended data source for the Ray offline +# store. It tells Feast how to load a Ray Dataset from any Ray Data-supported +# format (Parquet, CSV, JSON, HuggingFace datasets, MongoDB, SQL, and more). +# Here we read local Parquet files that are generated by bootstrap.py. +driver_hourly_stats = RaySource( name="driver_hourly_stats", + reader_type="parquet", path=f"{CURRENT_DIR}/%PARQUET_PATH%", timestamp_field="event_timestamp", created_timestamp_column="created", ) -customer_daily_profile = FileSource( +customer_daily_profile = RaySource( name="customer_daily_profile", + reader_type="parquet", path=f"{CURRENT_DIR}/data/customer_daily_profile.parquet", timestamp_field="event_timestamp", created_timestamp_column="created", @@ -59,6 +63,7 @@ online=True, source=driver_hourly_stats, tags={"team": "driver_performance", "processing": "ray"}, + version="latest", ) customer_daily_profile_view = FeatureView( @@ -73,6 +78,7 @@ online=True, source=customer_daily_profile, tags={"team": "customer_analytics", "processing": "ray"}, + version="latest", ) diff --git a/sdk/python/feast/templates/ray/feature_repo/test_workflow.py b/sdk/python/feast/templates/ray/feature_repo/test_workflow.py index 8caa4cb6380..721a122d5e1 100644 --- a/sdk/python/feast/templates/ray/feature_repo/test_workflow.py +++ b/sdk/python/feast/templates/ray/feature_repo/test_workflow.py @@ -83,12 +83,28 @@ def run_demo(): ], ) - # Convert to DataFrame - Ray processes this efficiently - historical_df = historical_features.to_df() - print(f" ✓ Retrieved {len(historical_df)} historical feature rows") - print(f" ✓ Features: {list(historical_df.columns)}") - - # Show sample of the data + # to_ray_dataset() returns the result as a Ray Dataset — no data is + # collected on the driver when the Ray offline store is used. This is + # the preferred output format for Ray Train, Ray Serve, and other + # distributed ML workloads. + ray_ds = historical_features.to_ray_dataset() + print(f" ✓ Retrieved Ray Dataset with {ray_ds.count()} rows") + print(f" ✓ Schema: {ray_ds.schema()}") + + # For non-Ray downstream consumers (pandas, scikit-learn, …) chain + # to_df() on the same RetrievalJob instead: + historical_df = store.get_historical_features( + entity_df=entity_df, + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + "customer_daily_profile:current_balance", + "customer_daily_profile:avg_passenger_count", + "customer_daily_profile:lifetime_trip_count", + ], + ).to_df() + print(f" ✓ Same features as pandas DataFrame: {list(historical_df.columns)}") print("\n Sample historical features:") print(historical_df.head(3).to_string(index=False)) diff --git a/sdk/python/feast/templates/snowflake/feature_repo/driver_repo.py b/sdk/python/feast/templates/snowflake/feature_repo/driver_repo.py index dd05dac8455..7526d096ef5 100644 --- a/sdk/python/feast/templates/snowflake/feature_repo/driver_repo.py +++ b/sdk/python/feast/templates/snowflake/feature_repo/driver_repo.py @@ -64,6 +64,7 @@ # Tags are user defined key/value pairs that are attached to each # feature view tags={"team": "driver_performance"}, + version="latest", ) # Define a request data source which encodes features / information only @@ -126,6 +127,7 @@ def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: online=True, source=driver_stats_push_source, # Changed from above tags={"team": "driver_performance"}, + version="latest", ) diff --git a/sdk/python/feast/templates/spark/feature_repo/feature_definitions.py b/sdk/python/feast/templates/spark/feature_repo/feature_definitions.py index 8ad48f53fc4..e89d9b0fc1e 100644 --- a/sdk/python/feast/templates/spark/feature_repo/feature_definitions.py +++ b/sdk/python/feast/templates/spark/feature_repo/feature_definitions.py @@ -54,6 +54,7 @@ online=True, source=driver_hourly_stats, tags={}, + version="latest", ) customer_daily_profile_view = FeatureView( name="customer_daily_profile", @@ -67,6 +68,7 @@ online=True, source=customer_daily_profile, tags={}, + version="latest", ) driver_stats_fs = FeatureService( diff --git a/sdk/python/feast/transformation/factory.py b/sdk/python/feast/transformation/factory.py index 16d7a7570d5..a181b7dea69 100644 --- a/sdk/python/feast/transformation/factory.py +++ b/sdk/python/feast/transformation/factory.py @@ -7,6 +7,7 @@ "sql": "feast.transformation.sql_transformation.SQLTransformation", "spark_sql": "feast.transformation.spark_transformation.SparkTransformation", "spark": "feast.transformation.spark_transformation.SparkTransformation", + "flink": "feast.transformation.flink_transformation.FlinkTransformation", "ray": "feast.transformation.ray_transformation.RayTransformation", } diff --git a/sdk/python/feast/transformation/flink_transformation.py b/sdk/python/feast/transformation/flink_transformation.py new file mode 100644 index 00000000000..83b929c4c96 --- /dev/null +++ b/sdk/python/feast/transformation/flink_transformation.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from typing import Any, Callable, Optional, cast + +from feast.transformation.base import Transformation +from feast.transformation.mode import TransformationMode + + +class FlinkTransformation(Transformation): + """Transformation wrapper for Flink compute-engine UDFs. + + The UDF is expected to accept PyFlink Table objects and return a PyFlink + Table. + """ + + def __new__( + cls, + udf: Optional[Callable[..., Any]] = None, + udf_string: Optional[str] = None, + name: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + description: str = "", + owner: str = "", + *args, + **kwargs, + ) -> "FlinkTransformation": + if udf is None and udf_string is None: + return cast("FlinkTransformation", object.__new__(cls)) + if udf is None: + raise ValueError("udf parameter cannot be None") + if udf_string is None: + raise ValueError("udf_string parameter cannot be None") + return cast( + "FlinkTransformation", + super(FlinkTransformation, cls).__new__( + cls, + mode=TransformationMode.FLINK, + udf=udf, + name=name, + udf_string=udf_string, + tags=tags, + description=description, + owner=owner, + ), + ) + + def __init__( + self, + udf: Optional[Callable[..., Any]] = None, + udf_string: Optional[str] = None, + name: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + description: str = "", + owner: str = "", + *args, + **kwargs, + ) -> None: + if udf is None and udf_string is None: + return + if udf is None: + raise ValueError("udf parameter cannot be None") + if udf_string is None: + raise ValueError("udf_string parameter cannot be None") + super().__init__( + mode=TransformationMode.FLINK, + udf=udf, + name=name, + udf_string=udf_string, + tags=tags, + description=description, + owner=owner, + ) + + def transform(self, *inputs: Any) -> Any: + return self.udf(*inputs) + + def infer_features(self, *args, **kwargs) -> Any: + pass diff --git a/sdk/python/feast/transformation/mode.py b/sdk/python/feast/transformation/mode.py index 44d38d8e99c..bd6fdf22424 100644 --- a/sdk/python/feast/transformation/mode.py +++ b/sdk/python/feast/transformation/mode.py @@ -6,6 +6,7 @@ class TransformationMode(Enum): PANDAS = "pandas" SPARK_SQL = "spark_sql" SPARK = "spark" + FLINK = "flink" RAY = "ray" SQL = "sql" SUBSTRAIT = "substrait" diff --git a/sdk/python/feast/type_map.py b/sdk/python/feast/type_map.py index 5e77f532c9c..5eca6782d5a 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -15,8 +15,10 @@ import decimal import json import logging +import re +import uuid as uuid_module from collections import defaultdict -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone from typing import ( TYPE_CHECKING, Any, @@ -51,9 +53,14 @@ Int64List, Int64Set, Map, + MapKey, MapList, + RepeatedValue, + ScalarMap, + ScalarMapEntry, StringList, StringSet, + ZonedTimestamp, ) from feast.protos.feast.types.Value_pb2 import Value as ProtoValue from feast.value_type import ListType, SetType, ValueType @@ -67,7 +74,70 @@ logger = logging.getLogger(__name__) -def feast_value_type_to_python_type(field_value_proto: ProtoValue) -> Any: +def _zone_name(tzinfo: Optional[Any]) -> str: + """Return a storable zone string for a datetime's tzinfo. + + Prefers the IANA name (e.g. ``zoneinfo.ZoneInfo`` key) so DST is preserved; + falls back to a fixed-offset string (e.g. ``-07:00``). A naive datetime + (``tzinfo is None``) yields ``""``, which decodes back as UTC. + """ + if tzinfo is None: + return "" + key = getattr(tzinfo, "key", None) # zoneinfo.ZoneInfo + if key: + return key + name = str(tzinfo) + # zoneinfo prints as the key; pytz prints the name; offsets print as "UTC-07:00" + return name + + +def _zone_from_name(zone: str): + """Resolve a stored zone string back to a tzinfo. Empty → UTC.""" + if not zone: + return timezone.utc + try: + from zoneinfo import ZoneInfo + + return ZoneInfo(zone) + except Exception: + # Not an IANA name. It may be a fixed-offset string produced by + # ``_zone_name`` (e.g. "UTC", "UTC-07:00", "+05:30"); parse it so the + # original offset is preserved on round trips rather than silently + # shifting the wall-clock time to UTC. + offset = _fixed_offset_from_name(zone) + if offset is not None: + return offset + logger.warning("Could not resolve zone %r; decoding as UTC", zone) + return timezone.utc + + +def _fixed_offset_from_name(zone: str) -> Optional[timezone]: + """Parse a fixed-offset zone string into a ``timezone``. + + Accepts the forms ``_zone_name`` emits for offset-only tzinfos: a bare + ``UTC``/``GMT``, or an offset like ``UTC-07:00``, ``-07:00``, ``+05:30`` or + ``+0530``. Returns ``None`` if the string is not a recognizable offset. + """ + text = zone.strip() + if text in ("UTC", "GMT"): + return timezone.utc + match = re.fullmatch( + r"(?:UTC|GMT)?([+-])(\d{2}):?(\d{2})", + text, + ) + if not match: + return None + sign, hours, minutes = match.groups() + delta = timedelta(hours=int(hours), minutes=int(minutes)) + if sign == "-": + delta = -delta + return timezone(delta) + + +def feast_value_type_to_python_type( + field_value_proto: ProtoValue, + feature_type: Optional[ValueType] = None, +) -> Any: """ Converts field value Proto to Dict and returns each field's Feast Value Type value in their respective Python value. @@ -101,6 +171,10 @@ def feast_value_type_to_python_type(field_value_proto: ProtoValue) -> Any: result.append(v) return result + # Handle nested collection types (list_val, set_val) + if val_attr in ("list_val", "set_val"): + return _handle_nested_collection_value(val) + # Handle Struct types — stored using Map proto, returned as dicts if val_attr == "struct_val": return _handle_map_value(val) @@ -112,6 +186,15 @@ def feast_value_type_to_python_type(field_value_proto: ProtoValue) -> Any: return _handle_map_value(val) elif val_attr == "map_list_val": return _handle_map_list_value(val) + elif val_attr == "scalar_map_val": + return _handle_scalar_map_value(val) + + # Zoned timestamp: a (instant, zone) message → tz-aware datetime in its own zone. + if val_attr == "zoned_timestamp_val": + if val.unix_timestamp == NULL_TIMESTAMP_INT_VALUE: + return None + tz = _zone_from_name(val.zone) + return datetime.fromtimestamp(val.unix_timestamp, tz=tz) # If it's a _LIST or _SET type extract the values. if hasattr(val, "val"): @@ -148,6 +231,34 @@ def feast_value_type_to_python_type(field_value_proto: ProtoValue) -> Any: elif val_attr.endswith("_set_val") and val_attr != "unix_timestamp_set_val": val = set(val) + # Convert UUID values to uuid.UUID objects + if val_attr in ("uuid_val", "time_uuid_val"): + return uuid_module.UUID(val) if isinstance(val, str) else val + if val_attr in ("uuid_list_val", "time_uuid_list_val"): + return [uuid_module.UUID(v) if isinstance(v, str) else v for v in val] + if val_attr in ("uuid_set_val", "time_uuid_set_val"): + return {uuid_module.UUID(v) if isinstance(v, str) else v for v in val} + + # Convert DECIMAL values to decimal.Decimal objects + if val_attr == "decimal_val": + return decimal.Decimal(val) if isinstance(val, str) else val + if val_attr == "decimal_list_val": + return [decimal.Decimal(v) if isinstance(v, str) else v for v in val] + if val_attr == "decimal_set_val": + return {decimal.Decimal(v) if isinstance(v, str) else v for v in val} + + # Backward compatibility: handle UUIDs stored as string_val/string_list_val with feature_type hint + if feature_type in (ValueType.UUID, ValueType.TIME_UUID) and isinstance(val, str): + return uuid_module.UUID(val) + if feature_type in (ValueType.UUID_LIST, ValueType.TIME_UUID_LIST) and isinstance( + val, list + ): + return [uuid_module.UUID(v) if isinstance(v, str) else v for v in val] + if feature_type in (ValueType.UUID_SET, ValueType.TIME_UUID_SET) and isinstance( + val, set + ): + return {uuid_module.UUID(v) if isinstance(v, str) else v for v in val} + return val @@ -174,6 +285,55 @@ def _handle_map_list_value(map_list_message) -> List[Dict[str, Any]]: return result +def _handle_nested_collection_value(repeated_value) -> List[Any]: + """Handle nested collection proto (RepeatedValue containing Values). + + Each inner Value is itself a list/set proto. We recursively convert + each inner Value to a Python list/set via feast_value_type_to_python_type. + """ + result = [] + for inner_value in repeated_value.val: + result.append(feast_value_type_to_python_type(inner_value)) + return result + + +def _map_key_to_python_value(map_key: MapKey) -> Any: + """Convert a MapKey proto to its Python equivalent.""" + key_attr = map_key.WhichOneof("key") + if key_attr is None: + return None + val = getattr(map_key, key_attr) + if key_attr in ("int32_key", "int64_key"): + return int(val) + if key_attr in ("float_key", "double_key"): + return float(val) + if key_attr == "bool_key": + return bool(val) + if key_attr == "unix_timestamp_key": + return ( + datetime.fromtimestamp(val, tz=timezone.utc) + if val != NULL_TIMESTAMP_INT_VALUE + else None + ) + if key_attr == "bytes_key": + return bytes(val) + if key_attr in ("uuid_key", "time_uuid_key"): + return uuid_module.UUID(val) + if key_attr == "decimal_key": + return decimal.Decimal(val) + return val + + +def _handle_scalar_map_value(value_map_message: ScalarMap) -> Dict[Any, Any]: + """Handle ScalarMap proto message (repeated ScalarMapEntry) → Python dict.""" + result: Dict[Any, Any] = {} + for entry in value_map_message.val: + key = _map_key_to_python_value(entry.key) + value = feast_value_type_to_python_type(entry.value) + result[key] = value + return result + + def feast_value_type_to_pandas_type(value_type: ValueType) -> Any: value_type_to_pandas_type: Dict[ValueType, str] = { ValueType.FLOAT: "float", @@ -184,9 +344,12 @@ def feast_value_type_to_pandas_type(value_type: ValueType) -> Any: ValueType.BYTES: "bytes", ValueType.BOOL: "bool", ValueType.UNIX_TIMESTAMP: "datetime64[ns]", + ValueType.UUID: "str", + ValueType.TIME_UUID: "str", + ValueType.DECIMAL: "object", } if ( - value_type.name in ("MAP", "JSON", "STRUCT") + value_type.name in ("MAP", "JSON", "STRUCT", "VALUE_LIST", "VALUE_SET") or value_type.name.endswith("_LIST") or value_type.name.endswith("_SET") ): @@ -247,6 +410,8 @@ def python_type_to_feast_value_type( "datetime64[ns, utc]": ValueType.UNIX_TIMESTAMP, "date": ValueType.UNIX_TIMESTAMP, "category": ValueType.STRING, + "uuid": ValueType.UUID, + "decimal": ValueType.DECIMAL, } if type_name in type_map: @@ -279,8 +444,9 @@ def python_type_to_feast_value_type( if not recurse: raise ValueError( f"Value type for field {name} is {type(value)} but " - f"recursion is not allowed. Array types can only be one level " - f"deep." + f"recursion is not allowed. Nested collection types cannot be " + f"inferred automatically; use an explicit Field dtype instead " + f"(e.g., dtype=Array(Array(Int32)))." ) # This is the final type which we infer from the list @@ -344,6 +510,9 @@ def python_type_to_feast_value_type( # Check if it's a dictionary (Map type) if isinstance(value, dict): + # Non-string keys require ScalarMap; string keys (or empty dict) use Map + if value and not isinstance(next(iter(value)), str): + return ValueType.SCALAR_MAP return ValueType.MAP raise ValueError( @@ -405,6 +574,27 @@ def _convert_value_type_str_to_value_type(type_str: str) -> ValueType: "JSON_LIST": ValueType.JSON_LIST, "STRUCT": ValueType.STRUCT, "STRUCT_LIST": ValueType.STRUCT_LIST, + "BYTES_SET": ValueType.BYTES_SET, + "STRING_SET": ValueType.STRING_SET, + "INT32_SET": ValueType.INT32_SET, + "INT64_SET": ValueType.INT64_SET, + "DOUBLE_SET": ValueType.DOUBLE_SET, + "FLOAT_SET": ValueType.FLOAT_SET, + "BOOL_SET": ValueType.BOOL_SET, + "UNIX_TIMESTAMP_SET": ValueType.UNIX_TIMESTAMP_SET, + "UUID": ValueType.UUID, + "TIME_UUID": ValueType.TIME_UUID, + "UUID_LIST": ValueType.UUID_LIST, + "TIME_UUID_LIST": ValueType.TIME_UUID_LIST, + "UUID_SET": ValueType.UUID_SET, + "TIME_UUID_SET": ValueType.TIME_UUID_SET, + "VALUE_LIST": ValueType.VALUE_LIST, + "VALUE_SET": ValueType.VALUE_SET, + "DECIMAL": ValueType.DECIMAL, + "DECIMAL_LIST": ValueType.DECIMAL_LIST, + "DECIMAL_SET": ValueType.DECIMAL_SET, + "SCALAR_MAP": ValueType.SCALAR_MAP, + "ZONED_TIMESTAMP": ValueType.ZONED_TIMESTAMP, } return type_map.get(type_str, ValueType.STRING) @@ -436,6 +626,21 @@ def _type_err(item, dtype): ValueType.STRING_LIST: (StringList, "string_list_val", [np.str_, str]), ValueType.BOOL_LIST: (BoolList, "bool_list_val", [np.bool_, bool]), ValueType.BYTES_LIST: (BytesList, "bytes_list_val", [np.bytes_, bytes]), + ValueType.UUID_LIST: ( + StringList, + "uuid_list_val", + [np.str_, str, uuid_module.UUID], + ), + ValueType.TIME_UUID_LIST: ( + StringList, + "time_uuid_list_val", + [np.str_, str, uuid_module.UUID], + ), + ValueType.DECIMAL_LIST: ( + StringList, + "decimal_list_val", + [np.str_, str, decimal.Decimal], + ), } PYTHON_SET_VALUE_TYPE_TO_PROTO_VALUE: Dict[ @@ -461,6 +666,17 @@ def _type_err(item, dtype): ValueType.STRING_SET: (StringSet, "string_set_val", [np.str_, str]), ValueType.BOOL_SET: (BoolSet, "bool_set_val", [np.bool_, bool]), ValueType.BYTES_SET: (BytesSet, "bytes_set_val", [np.bytes_, bytes]), + ValueType.UUID_SET: (StringSet, "uuid_set_val", [np.str_, str, uuid_module.UUID]), + ValueType.TIME_UUID_SET: ( + StringSet, + "time_uuid_set_val", + [np.str_, str, uuid_module.UUID], + ), + ValueType.DECIMAL_SET: ( + StringSet, + "decimal_set_val", + [np.str_, str, decimal.Decimal], + ), } PYTHON_SCALAR_VALUE_TYPE_TO_PROTO_VALUE: Dict[ @@ -486,6 +702,9 @@ def _type_err(item, dtype): ValueType.BYTES: ("bytes_val", lambda x: x, {bytes}), ValueType.IMAGE_BYTES: ("bytes_val", lambda x: x, {bytes}), ValueType.BOOL: ("bool_val", lambda x: x, {bool, np.bool_, int, np.int_}), + ValueType.UUID: ("uuid_val", lambda x: str(x), {str, uuid_module.UUID}), + ValueType.TIME_UUID: ("time_uuid_val", lambda x: str(x), {str, uuid_module.UUID}), + ValueType.DECIMAL: ("decimal_val", lambda x: str(x), {decimal.Decimal, str}), } @@ -591,7 +810,7 @@ def _validate_collection_item_types( """ if sample is None: return - if all(type(item) in valid_types for item in sample): + if all(type(item) in valid_types for item in sample if item is not None): return # to_numpy() upcasts INT32/INT64 with NULL to Float64 automatically @@ -602,6 +821,8 @@ def _validate_collection_item_types( ValueType.INT64_SET, ] for item in sample: + if item is None: + continue # None elements in STRING_LIST are replaced with ""; for other types they are dropped if type(item) not in valid_types: if feast_value_type in int_collection_types: # Check if the float values are due to NULL upcast @@ -685,6 +906,32 @@ def convert_set_to_list(value: Any) -> Any: converted_values, set_field_name, set_proto_type ) + if feast_value_type in (ValueType.UUID_SET, ValueType.TIME_UUID_SET): + # uuid.UUID objects must be converted to str for StringSet proto. + return [ + ( + ProtoValue( + **{set_field_name: set_proto_type(val=[str(e) for e in value])} # type: ignore[arg-type, misc] + ) + if value is not None + else ProtoValue() + ) + for value in converted_values + ] + + if feast_value_type == ValueType.DECIMAL_SET: + # decimal.Decimal objects must be converted to str for StringSet proto. + return [ + ( + ProtoValue( + **{set_field_name: set_proto_type(val=[str(e) for e in value])} # type: ignore[arg-type, misc] + ) + if value is not None + else ProtoValue() + ) + for value in converted_values + ] + # Generic set conversion return [ ProtoValue(**{set_field_name: set_proto_type(val=value)}) # type: ignore[arg-type] @@ -694,6 +941,39 @@ def convert_set_to_list(value: Any) -> Any: ] +# Per-type default values substituted for None elements inside list columns. +# Protobuf repeated fields do not accept None, so we replace with a +# type-appropriate zero/empty value. +_LIST_NONE_DEFAULTS: Dict[ValueType, Any] = { + ValueType.STRING_LIST: "", + ValueType.BYTES_LIST: b"", + ValueType.INT32_LIST: 0, + ValueType.INT64_LIST: 0, + ValueType.FLOAT_LIST: 0.0, + ValueType.DOUBLE_LIST: 0.0, + ValueType.BOOL_LIST: False, + ValueType.UNIX_TIMESTAMP_LIST: NULL_TIMESTAMP_INT_VALUE, + ValueType.UUID_LIST: "", + ValueType.TIME_UUID_LIST: "", + ValueType.DECIMAL_LIST: "", +} + + +def _sanitize_list_value(value: Any, feast_value_type: ValueType) -> Any: + """Convert ndarray to list and replace None elements with a type-appropriate default. + + Arrow/Athena may deserialize array columns as numpy.ndarray with object dtype + instead of plain Python lists. Protobuf repeated fields do not accept ndarrays + or None elements, so we normalise here before building proto messages. + """ + if isinstance(value, np.ndarray): + value = value.tolist() + none_default = _LIST_NONE_DEFAULTS.get(feast_value_type) + if none_default is not None and isinstance(value, list): + value = [none_default if v is None else v for v in value] + return value + + def _convert_list_values_to_proto( feast_value_type: ValueType, values: List[Any], @@ -716,6 +996,13 @@ def _convert_list_values_to_proto( feast_value_type ] + values = [ + _sanitize_list_value(v, feast_value_type) if v is not None else v + for v in values + ] + if sample is not None: + sample = _sanitize_list_value(sample, feast_value_type) + # Bytes to array type conversion if isinstance(sample, (bytes, bytearray)): if feast_value_type == ValueType.BYTES_LIST: @@ -745,6 +1032,32 @@ def _convert_list_values_to_proto( if feast_value_type == ValueType.BOOL_LIST: return _convert_bool_collection_to_proto(values, field_name, proto_type) + if feast_value_type in (ValueType.UUID_LIST, ValueType.TIME_UUID_LIST): + # uuid.UUID objects must be converted to str for StringList proto. + return [ + ( + ProtoValue( + **{field_name: proto_type(val=[str(e) for e in value])} # type: ignore[arg-type, misc] + ) + if value is not None + else ProtoValue() + ) + for value in values + ] + + if feast_value_type == ValueType.DECIMAL_LIST: + # decimal.Decimal objects must be converted to str for StringList proto. + return [ + ( + ProtoValue( + **{field_name: proto_type(val=[str(e) for e in value])} # type: ignore[arg-type, misc] + ) + if value is not None + else ProtoValue() + ) + for value in values + ] + # Generic list conversion return [ ProtoValue(**{field_name: proto_type(val=value)}) # type: ignore[arg-type] @@ -754,6 +1067,16 @@ def _convert_list_values_to_proto( ] +def _is_array_like(value: Any) -> bool: + """Return True if *value* is array-like (numpy array or any sized, + non-string, non-bytes container). Array-like values in a scalar + feature column cannot be mapped to a protobuf scalar field and are + therefore always treated as null.""" + return isinstance(value, np.ndarray) or ( + hasattr(value, "__len__") and not isinstance(value, (str, bytes)) + ) + + def _convert_scalar_values_to_proto( feast_value_type: ValueType, values: List[Any], @@ -774,16 +1097,63 @@ def _convert_scalar_values_to_proto( return [ProtoValue()] * len(values) if feast_value_type == ValueType.UNIX_TIMESTAMP: - int_timestamps = _python_datetime_to_int_timestamp(values) - return [ProtoValue(unix_timestamp_val=ts) for ts in int_timestamps] # type: ignore + out: List[Any] = [None] * len(values) + clean_indices: List[int] = [] + clean_values: List[Any] = [] + for i, value in enumerate(values): + if _is_array_like(value) or value is None: + out[i] = ProtoValue() + else: + clean_indices.append(i) + clean_values.append(value) + if clean_values: + timestamps = _python_datetime_to_int_timestamp(clean_values) + for i, ts in zip(clean_indices, timestamps): + out[i] = ProtoValue(unix_timestamp_val=ts) # type: ignore + return out + + if feast_value_type == ValueType.ZONED_TIMESTAMP: + # Lossless zoned datetime: store the UTC instant plus the originating zone. + # Only datetime values are accepted; a naive datetime keeps zone="" (UTC). + out = [] + for value in values: + if _is_array_like(value) or value is None or pd.isnull(value): + out.append(ProtoValue()) + elif isinstance(value, datetime): + # A naive datetime is interpreted as UTC for the instant, but keeps + # zone="" (the "unzoned" sentinel, which decode maps back to UTC). + dt = ( + value + if value.tzinfo is not None + else value.replace(tzinfo=timezone.utc) + ) + out.append( + ProtoValue( + zoned_timestamp_val=ZonedTimestamp( + unix_timestamp=int(dt.timestamp()), + zone=_zone_name(value.tzinfo), + ) + ) # type: ignore + ) + else: + raise TypeError( + f"ZONED_TIMESTAMP expects datetime values, got {type(value)}" + ) + return out field_name, func, valid_scalar_types = PYTHON_SCALAR_VALUE_TYPE_TO_PROTO_VALUE[ feast_value_type ] - # Validate scalar types + # Validate scalar types. The caller guarantees that *sample* is not + # array-like (array-like values are filtered out when picking the sample + # for scalar columns in python_values_to_proto_values). if valid_scalar_types: - if (sample == 0 or sample == 0.0) and feast_value_type != ValueType.BOOL: + try: + is_zero = sample == 0 or sample == 0.0 + except (ValueError, TypeError): + is_zero = False + if is_zero and feast_value_type != ValueType.BOOL: # Numpy converts 0 to int, but column type may be float allowed_types = {np.int64, int, np.float64, float, decimal.Decimal} assert type(sample) in allowed_types, ( @@ -796,20 +1166,35 @@ def _convert_scalar_values_to_proto( # Handle BOOL specially due to np.bool_ conversion requirement if feast_value_type == ValueType.BOOL: - return [ - ProtoValue( - **{field_name: func(bool(value) if type(value) is np.bool_ else value)} - ) # type: ignore - if not pd.isnull(value) - else ProtoValue() - for value in values - ] + out = [] + for value in values: + if _is_array_like(value): + # Array-like value in a scalar BOOL column: treat as null. + out.append(ProtoValue()) + elif not pd.isnull(value): + out.append( + ProtoValue( + **{ + field_name: func( + bool(value) if type(value) is np.bool_ else value + ) + } + ) # type: ignore + ) + else: + out.append(ProtoValue()) + return out # Generic scalar conversion out = [] for value in values: if isinstance(value, ProtoValue): out.append(value) + elif _is_array_like(value): + # Array-like value in a scalar column: always treat as null. + # pd.isnull() is vectorised and would return an ndarray here, + # making `not pd.isnull(value)` raise ValueError. + out.append(ProtoValue()) elif not pd.isnull(value): out.append(ProtoValue(**{field_name: func(value)})) else: @@ -831,6 +1216,10 @@ def _python_value_to_proto_value( Returns: List of Feast Value Proto """ + # Handle nested collection types (VALUE_LIST, VALUE_SET) + if feast_value_type in (ValueType.VALUE_LIST, ValueType.VALUE_SET): + return _convert_nested_collection_to_proto(feast_value_type, values) + # Handle Map types if feast_value_type == ValueType.MAP: result = [] @@ -864,6 +1253,21 @@ def _python_value_to_proto_value( ) return result + if feast_value_type == ValueType.SCALAR_MAP: + result = [] + for value in values: + if value is None: + result.append(ProtoValue()) + else: + if not isinstance(value, dict): + raise TypeError( + f"Expected dict for SCALAR_MAP type, got {type(value).__name__}: {value!r}" + ) + result.append( + ProtoValue(scalar_map_val=_python_dict_to_scalar_map_proto(value)) + ) + return result + # Handle JSON type — serialize Python objects as JSON strings if feast_value_type == ValueType.JSON: result = [] @@ -948,16 +1352,65 @@ def _python_value_to_proto_value( if "set" in type_name_lower: return _python_set_to_proto_values(feast_value_type, values) - # Scalar types + # Scalar types — pick a sample that is not array-like so that the type + # validation in _convert_scalar_values_to_proto always receives a plain + # scalar (array-like values in a scalar column are treated as null). if ( feast_value_type in PYTHON_SCALAR_VALUE_TYPE_TO_PROTO_VALUE or feast_value_type == ValueType.UNIX_TIMESTAMP + or feast_value_type == ValueType.ZONED_TIMESTAMP ): - return _convert_scalar_values_to_proto(feast_value_type, values, sample) + scalar_sample = next( + (v for v in values if _non_empty_value(v) and not _is_array_like(v)), + None, + ) + return _convert_scalar_values_to_proto(feast_value_type, values, scalar_sample) raise Exception(f"Unsupported data type: {feast_value_type}") +def _convert_nested_collection_to_proto( + feast_value_type: ValueType, values: List[Any] +) -> List[ProtoValue]: + """Convert nested collection values (list-of-lists, list-of-sets, etc.) to proto.""" + val_attr = "list_val" if feast_value_type == ValueType.VALUE_LIST else "set_val" + + result = [] + for value in values: + if value is None: + result.append(ProtoValue()) + else: + inner_values = [] + for inner_collection in value: + if inner_collection is None: + inner_values.append(ProtoValue()) + else: + inner_list = list(inner_collection) + if len(inner_list) == 0: + # Empty inner collection: store as empty ProtoValue + inner_values.append(ProtoValue()) + elif any( + isinstance(item, (list, set, tuple, np.ndarray)) + for item in inner_list + ): + # Deeper nesting (3+ levels): recurse using VALUE_LIST + inner_proto = _convert_nested_collection_to_proto( + ValueType.VALUE_LIST, [inner_list] + ) + inner_values.append(inner_proto[0]) + else: + # Leaf level: wrap as a single list-typed Value + proto_vals = python_values_to_proto_values( + [inner_list], ValueType.UNKNOWN + ) + inner_values.append(proto_vals[0]) + repeated = RepeatedValue(val=inner_values) + proto = ProtoValue() + getattr(proto, val_attr).CopyFrom(repeated) + result.append(proto) + return result + + def _python_dict_to_map_proto(python_dict: Dict[str, Any]) -> Map: """Convert a Python dictionary to a Map proto message.""" map_proto = Map() @@ -999,6 +1452,48 @@ def _python_list_to_map_list_proto(python_list: List[Dict[str, Any]]) -> MapList return map_list_proto +def _python_value_to_map_key_proto(key: Any) -> MapKey: + """Convert a Python value to a MapKey proto for use in ScalarMap entries.""" + # bool must be checked before int since bool is a subclass of int + if isinstance(key, (bool, np.bool_)): + return MapKey(bool_key=bool(key)) + if isinstance(key, np.int32): + return MapKey(int32_key=int(key)) + if isinstance(key, (int, np.integer)): + return MapKey(int64_key=int(key)) + if isinstance(key, np.float32): + return MapKey(float_key=float(key)) + if isinstance(key, (float, np.floating)): + return MapKey(double_key=float(key)) + if isinstance(key, uuid_module.UUID): + return MapKey(uuid_key=str(key)) + if isinstance(key, decimal.Decimal): + return MapKey(decimal_key=str(key)) + if isinstance(key, bytes): + return MapKey(bytes_key=key) + if isinstance(key, (datetime, pd.Timestamp)): + ts = int(pd.Timestamp(key).timestamp()) + return MapKey(unix_timestamp_key=ts) + raise TypeError( + f"Unsupported key type for SCALAR_MAP: {type(key).__name__}. " + "Supported non-string key types: int, float, bool, uuid.UUID, " + "decimal.Decimal, bytes, datetime." + ) + + +def _python_dict_to_scalar_map_proto(python_dict: Dict[Any, Any]) -> ScalarMap: + """Convert a Python dictionary with non-string keys to a ScalarMap proto.""" + value_map_proto = ScalarMap() + for key, value in python_dict.items(): + map_key = _python_value_to_map_key_proto(key) + if value is None: + value_proto = ProtoValue() + else: + value_proto = python_values_to_proto_values([value], ValueType.UNKNOWN)[0] + value_map_proto.val.append(ScalarMapEntry(key=map_key, value=value_proto)) + return value_map_proto + + def python_values_to_proto_values( values: List[Any], feature_type: ValueType = ValueType.UNKNOWN ) -> List[ProtoValue]: @@ -1015,6 +1510,8 @@ def python_values_to_proto_values( value_type = python_type_to_feast_value_type("", sample) if value_type == ValueType.UNKNOWN: + if all(v is None for v in values): + return [ProtoValue() for _ in values] raise TypeError("Couldn't infer value type from empty value") proto_values = _python_value_to_proto_value(value_type, values) @@ -1050,6 +1547,8 @@ def python_values_to_proto_values( "json_list_val": ValueType.JSON_LIST, "struct_val": ValueType.STRUCT, "struct_list_val": ValueType.STRUCT_LIST, + "list_val": ValueType.VALUE_LIST, + "set_val": ValueType.VALUE_SET, "int32_set_val": ValueType.INT32_SET, "int64_set_val": ValueType.INT64_SET, "double_set_val": ValueType.DOUBLE_SET, @@ -1058,6 +1557,16 @@ def python_values_to_proto_values( "bytes_set_val": ValueType.BYTES_SET, "bool_set_val": ValueType.BOOL_SET, "unix_timestamp_set_val": ValueType.UNIX_TIMESTAMP_SET, + "uuid_set_val": ValueType.UUID_SET, + "time_uuid_set_val": ValueType.TIME_UUID_SET, + "uuid_val": ValueType.UUID, + "time_uuid_val": ValueType.TIME_UUID, + "uuid_list_val": ValueType.UUID_LIST, + "time_uuid_list_val": ValueType.TIME_UUID_LIST, + "decimal_val": ValueType.DECIMAL, + "decimal_list_val": ValueType.DECIMAL_LIST, + "decimal_set_val": ValueType.DECIMAL_SET, + "scalar_map_val": ValueType.SCALAR_MAP, } VALUE_TYPE_TO_PROTO_VALUE_MAP: Dict[ValueType, str] = { @@ -1085,7 +1594,11 @@ def pa_to_feast_value_type(pa_type_as_str: str) -> ValueType: is_list = False if pa_type_as_str.startswith("list", "") + inner_str = pa_type_as_str[len("list "FLOAT_LIST": f"feast_{project_name}_snowflake_array_float_to_list_double_proto", "BOOL_LIST": f"feast_{project_name}_snowflake_array_boolean_to_list_bool_proto", "UNIX_TIMESTAMP_LIST": f"feast_{project_name}_snowflake_array_timestamp_to_list_unix_timestamp_proto", + "UUID": f"feast_{project_name}_snowflake_varchar_to_string_proto", + "TIME_UUID": f"feast_{project_name}_snowflake_varchar_to_string_proto", + "UUID_LIST": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "TIME_UUID_LIST": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "UUID_SET": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "TIME_UUID_SET": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "DECIMAL": f"feast_{project_name}_snowflake_varchar_to_string_proto", + "DECIMAL_LIST": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", + "DECIMAL_SET": f"feast_{project_name}_snowflake_array_varchar_to_list_string_proto", } return name_map[value_name].upper() @@ -1550,8 +2072,8 @@ def pg_type_to_feast_value_type(type_str: str) -> ValueType: "timestamp with time zone[]": ValueType.UNIX_TIMESTAMP_LIST, "numeric[]": ValueType.DOUBLE_LIST, "numeric": ValueType.DOUBLE, - "uuid": ValueType.STRING, - "uuid[]": ValueType.STRING_LIST, + "uuid": ValueType.UUID, + "uuid[]": ValueType.UUID_LIST, "json": ValueType.MAP, "jsonb": ValueType.MAP, "json[]": ValueType.MAP_LIST, @@ -1597,7 +2119,20 @@ def feast_value_type_to_pa( ValueType.JSON_LIST: pyarrow.list_(pyarrow.large_string()), ValueType.STRUCT: pyarrow.struct([]), ValueType.STRUCT_LIST: pyarrow.list_(pyarrow.struct([])), + # Placeholder: inner type is unknown from ValueType alone. + # Callers needing accurate inner types should use from_feast_to_pyarrow_type() with a FeastType. + ValueType.VALUE_LIST: pyarrow.list_(pyarrow.list_(pyarrow.string())), + ValueType.VALUE_SET: pyarrow.list_(pyarrow.list_(pyarrow.string())), ValueType.NULL: pyarrow.null(), + ValueType.UUID: pyarrow.string(), + ValueType.TIME_UUID: pyarrow.string(), + ValueType.UUID_LIST: pyarrow.list_(pyarrow.string()), + ValueType.TIME_UUID_LIST: pyarrow.list_(pyarrow.string()), + ValueType.UUID_SET: pyarrow.list_(pyarrow.string()), + ValueType.TIME_UUID_SET: pyarrow.list_(pyarrow.string()), + ValueType.DECIMAL: pyarrow.string(), + ValueType.DECIMAL_LIST: pyarrow.list_(pyarrow.string()), + ValueType.DECIMAL_SET: pyarrow.list_(pyarrow.string()), } return type_map[feast_type] @@ -1750,7 +2285,7 @@ def cb_columnar_type_to_feast_value_type(type_str: str) -> ValueType: "object": ValueType.UNKNOWN, "array": ValueType.UNKNOWN, "multiset": ValueType.UNKNOWN, - "uuid": ValueType.STRING, + "uuid": ValueType.UUID, } value = ( type_map[type_str.lower()] @@ -1762,6 +2297,35 @@ def cb_columnar_type_to_feast_value_type(type_str: str) -> ValueType: return value +def mongodb_to_feast_value_type(type_str: str) -> ValueType: + """Map a Python type string (as inferred from pymongo documents) to a Feast ValueType. + + The type strings are produced by + ``feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb_source._infer_python_type_str``. + Unrecognised strings are mapped to ``ValueType.UNKNOWN``. + """ + type_map: Dict[str, ValueType] = { + "str": ValueType.STRING, + "string": ValueType.STRING, + "int": ValueType.INT64, + "int64": ValueType.INT64, + "float": ValueType.DOUBLE, + "float64": ValueType.DOUBLE, + "bool": ValueType.BOOL, + "bytes": ValueType.BYTES, + "datetime": ValueType.UNIX_TIMESTAMP, + "list": ValueType.UNKNOWN, + "dict": ValueType.UNKNOWN, + "list[str]": ValueType.STRING_LIST, + "list[int]": ValueType.INT64_LIST, + "list[float]": ValueType.DOUBLE_LIST, + "list[bool]": ValueType.BOOL_LIST, + "list[bytes]": ValueType.BYTES_LIST, + "list[datetime]": ValueType.UNIX_TIMESTAMP_LIST, + } + return type_map.get(type_str, ValueType.UNKNOWN) + + def convert_scalar_column( series: pd.Series, value_type: ValueType, target_pandas_type: str ) -> pd.Series: @@ -1776,6 +2340,8 @@ def convert_scalar_column( return series.astype("boolean") elif value_type == ValueType.STRING: return series.astype("string") + elif value_type in [ValueType.UUID, ValueType.TIME_UUID]: + return series.astype("string") elif value_type == ValueType.UNIX_TIMESTAMP: return pd.to_datetime(series, unit="s", errors="coerce") elif value_type in (ValueType.JSON, ValueType.STRUCT, ValueType.MAP): @@ -1795,6 +2361,18 @@ def convert_array_column(series: pd.Series, value_type: ValueType) -> pd.Series: ValueType.STRING_LIST: object, ValueType.BYTES_LIST: object, ValueType.UNIX_TIMESTAMP_LIST: "datetime64[s]", + ValueType.UUID_LIST: object, + ValueType.TIME_UUID_LIST: object, + ValueType.BYTES_SET: object, + ValueType.STRING_SET: object, + ValueType.INT32_SET: np.int32, + ValueType.INT64_SET: np.int64, + ValueType.FLOAT_SET: np.float32, + ValueType.DOUBLE_SET: np.float64, + ValueType.BOOL_SET: np.bool_, + ValueType.UNIX_TIMESTAMP_SET: "datetime64[s]", + ValueType.UUID_SET: object, + ValueType.TIME_UUID_SET: object, } target_dtype = base_type_map.get(value_type, object) diff --git a/sdk/python/feast/types.py b/sdk/python/feast/types.py index d94c356cd1a..ca913e06bb8 100644 --- a/sdk/python/feast/types.py +++ b/sdk/python/feast/types.py @@ -25,6 +25,9 @@ "BYTES": "BYTES", "PDF_BYTES": "PDF_BYTES", "IMAGE_BYTES": "IMAGE_BYTES", + "UUID": "UUID", + "TIME_UUID": "TIME_UUID", + "DECIMAL": "DECIMAL", "STRING": "STRING", "INT32": "INT32", "INT64": "INT64", @@ -34,6 +37,8 @@ "UNIX_TIMESTAMP": "UNIX_TIMESTAMP", "MAP": "MAP", "JSON": "JSON", + "SCALAR_MAP": "SCALAR_MAP", + "ZONED_TIMESTAMP": "ZONED_TIMESTAMP", } @@ -87,6 +92,11 @@ class PrimitiveFeastType(Enum): IMAGE_BYTES = 10 MAP = 11 JSON = 12 + UUID = 13 + TIME_UUID = 14 + DECIMAL = 15 + SCALAR_MAP = 16 + ZONED_TIMESTAMP = 17 def to_value_type(self) -> ValueType: """ @@ -121,6 +131,11 @@ def __hash__(self): UnixTimestamp = PrimitiveFeastType.UNIX_TIMESTAMP Map = PrimitiveFeastType.MAP Json = PrimitiveFeastType.JSON +Uuid = PrimitiveFeastType.UUID +TimeUuid = PrimitiveFeastType.TIME_UUID +Decimal = PrimitiveFeastType.DECIMAL +ScalarMap = PrimitiveFeastType.SCALAR_MAP +ZonedTimestamp = PrimitiveFeastType.ZONED_TIMESTAMP SUPPORTED_BASE_TYPES = [ Invalid, @@ -136,6 +151,10 @@ def __hash__(self): UnixTimestamp, Map, Json, + Uuid, + TimeUuid, + Decimal, + ZonedTimestamp, ] PRIMITIVE_FEAST_TYPES_TO_STRING = { @@ -152,6 +171,11 @@ def __hash__(self): "UNIX_TIMESTAMP": "UnixTimestamp", "MAP": "Map", "JSON": "Json", + "UUID": "Uuid", + "TIME_UUID": "TimeUuid", + "DECIMAL": "Decimal", + "SCALAR_MAP": "ScalarMap", + "ZONED_TIMESTAMP": "ZonedTimestamp", } @@ -166,22 +190,38 @@ class Array(ComplexFeastType): base_type: Union[PrimitiveFeastType, ComplexFeastType] def __init__(self, base_type: Union[PrimitiveFeastType, "ComplexFeastType"]): - # Allow Struct as a base type for Array(Struct(...)) - if not isinstance(base_type, Struct) and base_type not in SUPPORTED_BASE_TYPES: - raise ValueError( - f"Type {type(base_type)} is currently not supported as a base type for Array." - ) + # Allow Struct, Array, and Set as base types for nested collections + if not isinstance(base_type, (Struct, Array, Set)): + # Arrays do not support ZonedTimestamp: there is no ZONED_TIMESTAMP_LIST + # ValueType for it to map to. + supported_array_types = [ + t for t in SUPPORTED_BASE_TYPES if t not in (ZonedTimestamp,) + ] + if base_type not in supported_array_types: + raise ValueError( + f"Type {type(base_type)} is currently not supported as a base type for Array." + ) self.base_type = base_type def to_value_type(self) -> ValueType: if isinstance(self.base_type, Struct): return ValueType.STRUCT_LIST + if isinstance(self.base_type, (Array, Set)): + return ValueType.VALUE_LIST assert isinstance(self.base_type, PrimitiveFeastType) value_type_name = PRIMITIVE_FEAST_TYPES_TO_VALUE_TYPES[self.base_type.name] value_type_list_name = value_type_name + "_LIST" return ValueType[value_type_list_name] + def __eq__(self, other): + if isinstance(other, Array): + return self.base_type == other.base_type + return False + + def __hash__(self): + return hash(("Array", hash(self.base_type))) + def __str__(self): return f"Array({self.base_type})" @@ -197,21 +237,36 @@ class Set(ComplexFeastType): base_type: Union[PrimitiveFeastType, ComplexFeastType] def __init__(self, base_type: Union[PrimitiveFeastType, ComplexFeastType]): - # Sets do not support MAP as a base type - supported_set_types = [t for t in SUPPORTED_BASE_TYPES if t != Map] - if base_type not in supported_set_types: - raise ValueError( - f"Type {type(base_type)} is currently not supported as a base type for Set." - ) + # Allow Array and Set as base types for nested collections + if not isinstance(base_type, (Array, Set)): + # Sets do not support MAP as a base type, nor ZonedTimestamp (there is no + # ZONED_TIMESTAMP_SET ValueType for it to map to). + supported_set_types = [ + t for t in SUPPORTED_BASE_TYPES if t not in (Map, ZonedTimestamp) + ] + if base_type not in supported_set_types: + raise ValueError( + f"Type {type(base_type)} is currently not supported as a base type for Set." + ) self.base_type = base_type def to_value_type(self) -> ValueType: + if isinstance(self.base_type, (Array, Set)): + return ValueType.VALUE_SET assert isinstance(self.base_type, PrimitiveFeastType) value_type_name = PRIMITIVE_FEAST_TYPES_TO_VALUE_TYPES[self.base_type.name] value_type_set_name = value_type_name + "_SET" return ValueType[value_type_set_name] + def __eq__(self, other): + if isinstance(other, Set): + return self.base_type == other.base_type + return False + + def __hash__(self): + return hash(("Set", hash(self.base_type))) + def __str__(self): return f"Set({self.base_type})" @@ -297,6 +352,17 @@ def __hash__(self): ValueType.FLOAT_SET: Set(Float32), ValueType.BOOL_SET: Set(Bool), ValueType.UNIX_TIMESTAMP_SET: Set(UnixTimestamp), + ValueType.UUID: Uuid, + ValueType.TIME_UUID: TimeUuid, + ValueType.UUID_LIST: Array(Uuid), + ValueType.TIME_UUID_LIST: Array(TimeUuid), + ValueType.UUID_SET: Set(Uuid), + ValueType.TIME_UUID_SET: Set(TimeUuid), + ValueType.DECIMAL: Decimal, + ValueType.DECIMAL_LIST: Array(Decimal), + ValueType.DECIMAL_SET: Set(Decimal), + ValueType.SCALAR_MAP: ScalarMap, + ValueType.ZONED_TIMESTAMP: ZonedTimestamp, } FEAST_TYPES_TO_PYARROW_TYPES = { @@ -308,8 +374,13 @@ def __hash__(self): Float64: pyarrow.float64(), # Note: datetime only supports microseconds https://github.com/python/cpython/blob/3.8/Lib/datetime.py#L1559 UnixTimestamp: pyarrow.timestamp("us", tz=_utc_now().tzname()), + # Per-value zone is carried in the proto; the Arrow column type is tz-aware UTC. + ZonedTimestamp: pyarrow.timestamp("us", tz="UTC"), Map: pyarrow.map_(pyarrow.string(), pyarrow.string()), Json: pyarrow.large_string(), + Uuid: pyarrow.string(), + TimeUuid: pyarrow.string(), + Decimal: pyarrow.string(), } FEAST_VECTOR_TYPES: List[Union[ValueType, PrimitiveFeastType, ComplexFeastType]] = [ @@ -347,6 +418,8 @@ def from_feast_to_pyarrow_type(feast_type: FeastType) -> pyarrow.DataType: base_type = feast_type.base_type if isinstance(base_type, Struct): return pyarrow.list_(base_type.to_pyarrow_type()) + if isinstance(base_type, (Array, Set)): + return pyarrow.list_(from_feast_to_pyarrow_type(base_type)) if isinstance(base_type, PrimitiveFeastType): if base_type == Map: return pyarrow.list_(pyarrow.map_(pyarrow.string(), pyarrow.string())) @@ -354,6 +427,8 @@ def from_feast_to_pyarrow_type(feast_type: FeastType) -> pyarrow.DataType: return pyarrow.list_(FEAST_TYPES_TO_PYARROW_TYPES[base_type]) elif isinstance(feast_type, Set): base_type = feast_type.base_type + if isinstance(base_type, (Array, Set)): + return pyarrow.list_(from_feast_to_pyarrow_type(base_type)) if isinstance(base_type, PrimitiveFeastType): if base_type in FEAST_TYPES_TO_PYARROW_TYPES: return pyarrow.list_(FEAST_TYPES_TO_PYARROW_TYPES[base_type]) @@ -384,6 +459,13 @@ def from_value_type( if value_type == ValueType.STRUCT_LIST: return Array(Struct({"_value": String})) + # Nested collection types use placeholder inner types. + # Real inner type is restored from Field tags during deserialization. + if value_type == ValueType.VALUE_LIST: + return Array(Array(String)) + if value_type == ValueType.VALUE_SET: + return Set(Array(String)) + raise ValueError(f"Could not convert value type {value_type} to FeastType.") @@ -408,6 +490,12 @@ def from_feast_type( if isinstance(feast_type, Array) and isinstance(feast_type.base_type, Struct): return ValueType.STRUCT_LIST + # Handle nested collection types + if isinstance(feast_type, Array) and isinstance(feast_type.base_type, (Array, Set)): + return ValueType.VALUE_LIST + if isinstance(feast_type, Set) and isinstance(feast_type.base_type, (Array, Set)): + return ValueType.VALUE_SET + if feast_type in VALUE_TYPES_TO_FEAST_TYPES.values(): return list(VALUE_TYPES_TO_FEAST_TYPES.keys())[ list(VALUE_TYPES_TO_FEAST_TYPES.values()).index(feast_type) diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py index 99a4abc9c81..f9a9733d8a1 100644 --- a/sdk/python/feast/ui_server.py +++ b/sdk/python/feast/ui_server.py @@ -1,20 +1,803 @@ import json -import threading +import logging from importlib import resources as importlib_resources -from typing import Callable, Optional +from typing import Any, Dict, List, Optional +import pandas as pd import uvicorn from fastapi import FastAPI, Response, status from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles +from pydantic import BaseModel import feast +logger = logging.getLogger(__name__) + + +def _safe_error_response( + operation: str, status_code: int = status.HTTP_400_BAD_REQUEST +) -> Response: + """Return a generic error response without exposing internal details.""" + return Response( + content=json.dumps( + {"detail": f"{operation} failed. Check server logs for details."} + ), + status_code=status_code, + media_type="application/json", + ) + + +def _build_projects_list( + store: "feast.FeatureStore", + project_id: str, + root_path: str, +): + """Build the projects list for the UI.""" + discovered_projects = [] + registry_path_template = f"{root_path}/api/v1" + + try: + projects = store.registry.list_projects(allow_cache=True) + for proj in projects: + discovered_projects.append( + { + "name": proj.name.replace("_", " ").title(), + "description": proj.description or f"Project: {proj.name}", + "id": proj.name, + "registryPath": registry_path_template, + } + ) + except Exception: + pass + + if not discovered_projects: + discovered_projects.append( + { + "name": "Project", + "description": "Test project", + "id": project_id, + "registryPath": registry_path_template, + } + ) + + if len(discovered_projects) > 1: + all_projects_entry = { + "name": "All Projects", + "description": "View data across all projects", + "id": "all", + "registryPath": registry_path_template, + } + discovered_projects.insert(0, all_projects_entry) + + return {"projects": discovered_projects} + + +def _setup_rest_mode(app: FastAPI, store: "feast.FeatureStore"): + """Mount the REST registry API routes on the UI server under /api/v1.""" + from feast.api.registry.rest import register_all_routes + from feast.registry_server import RegistryServer + + grpc_handler = RegistryServer(store.registry) + + rest_app = FastAPI(root_path="/api/v1") + register_all_routes(rest_app, grpc_handler, store=store) + + class PushRequest(BaseModel): + push_source_name: str + df: Dict[str, List] + to: Optional[str] = "online" + + @rest_app.post("/push") + def push_labels(request: PushRequest): + """Push label data to a LabelView (or any PushSource-backed FeatureView).""" + try: + df = pd.DataFrame(request.df) + if "event_timestamp" in df.columns: + df["event_timestamp"] = pd.to_datetime( + df["event_timestamp"], utc=True + ).dt.tz_localize(None) + to = request.to or "online" + if to == "online_and_offline": + store.push( + request.push_source_name, + df, + to=feast.data_source.PushMode.ONLINE_AND_OFFLINE, + ) + elif to == "offline": + store.push( + request.push_source_name, df, to=feast.data_source.PushMode.OFFLINE + ) + else: + store.push( + request.push_source_name, df, to=feast.data_source.PushMode.ONLINE + ) + return {"status": "ok"} + except Exception: + logger.exception("Push failed") + return _safe_error_response("Push") + + class GetOnlineFeaturesRequest(BaseModel): + feature_view: str + entity_keys: Dict[str, List] + + @rest_app.post("/get-online-labels") + def get_online_labels(request: GetOnlineFeaturesRequest): + """Retrieve current label values from the online store for given entity keys.""" + try: + fv_name = request.feature_view + + fv: Any = None + try: + fv = store.get_feature_view(fv_name) + except Exception: + pass + + if fv is None: + try: + fv = store.registry.get_label_view(fv_name, store.project) + except Exception: + pass + + if fv is None: + return Response( + content=json.dumps( + {"detail": f"Feature view or label view '{fv_name}' not found"} + ), + status_code=status.HTTP_404_NOT_FOUND, + media_type="application/json", + ) + + feature_refs = [f"{fv_name}:{f.name}" for f in fv.features] + + result = store.get_online_features( + features=feature_refs, + entity_rows=[ + {k: v[i] for k, v in request.entity_keys.items()} + for i in range(len(next(iter(request.entity_keys.values())))) + ], + ) + + result_dict = result.to_dict() + return {"results": result_dict} + except Exception: + logger.exception("get-online-labels failed") + return _safe_error_response("Get online labels") + + class ListLabelsRequest(BaseModel): + feature_view: str + limit: Optional[int] = 100 + + @rest_app.post("/list-labels") + def list_labels(request: ListLabelsRequest): + """List resolved labels from the offline store with conflict policy enforcement.""" + try: + from feast.labeling.conflict_policy import ConflictPolicy + from feast.labeling.conflict_resolver import resolve_conflicts + + fv_name = request.feature_view + fv: Any = None + try: + fv = store.registry.get_label_view(fv_name, store.project) + except Exception: + try: + fv = store.get_feature_view(fv_name) + except Exception: + pass + + if fv is None: + return Response( + content=json.dumps({"detail": f"Label view '{fv_name}' not found"}), + status_code=status.HTTP_404_NOT_FOUND, + media_type="application/json", + ) + + batch_source = getattr(fv, "batch_source", None) + if batch_source is None: + return Response( + content=json.dumps({"detail": f"No batch source for '{fv_name}'"}), + status_code=status.HTTP_400_BAD_REQUEST, + media_type="application/json", + ) + + feature_names = [f.name for f in fv.features] + join_keys = ( + fv.join_keys + if hasattr(fv, "join_keys") + else (fv.entities if fv.entities else []) + ) + + provider = store._get_provider() + timestamp_field = batch_source.timestamp_field + + conflict_policy = getattr( + fv, "conflict_policy", ConflictPolicy.LAST_WRITE_WINS + ) + labeler_field = getattr(fv, "labeler_field", "labeler") + + try: + job = provider.offline_store.pull_all_from_table_or_query( + config=store.config, + data_source=batch_source, + join_key_columns=join_keys, + feature_name_columns=feature_names, + timestamp_field=timestamp_field, + ) + df = job.to_df() + except Exception: + return { + "labels": [], + "columns": join_keys + feature_names, + "feature_names": feature_names, + "entity_names": join_keys, + "total_count": 0, + "total_entities": 0, + "conflict_policy": conflict_policy.value, + "hint": "No label data found yet. Push labels to get started.", + } + + df = resolve_conflicts( + df=df, + join_key_columns=join_keys, + feature_name_columns=feature_names, + timestamp_field=timestamp_field, + labeler_field=labeler_field, + conflict_policy=conflict_policy, + ) + + limit = request.limit or 100 + df = df.head(limit) + + result = df.to_dict(orient="records") + for row in result: + for k, v in row.items(): + if pd.isna(v): + row[k] = None + elif hasattr(v, "isoformat"): + row[k] = v.isoformat() + + return { + "labels": result, + "columns": list(df.columns), + "feature_names": feature_names, + "entity_names": join_keys, + "total_count": len(result), + "total_entities": len(result), + "conflict_policy": conflict_policy.value, + } + except Exception: + logger.exception("list-labels failed") + return _safe_error_response("List labels") + + class LabelQualityRequest(BaseModel): + feature_view: str + + @rest_app.post("/label-quality") + def label_quality(request: LabelQualityRequest): + """Compute label quality metrics with conflict policy enforcement.""" + try: + from datetime import datetime, timezone + + from feast.labeling.conflict_policy import ConflictPolicy + from feast.labeling.conflict_resolver import resolve_conflicts + + fv_name = request.feature_view + fv: Any = None + try: + fv = store.registry.get_label_view(fv_name, store.project) + except Exception: + try: + fv = store.get_feature_view(fv_name) + except Exception: + pass + + if fv is None: + return Response( + content=json.dumps({"detail": f"Label view '{fv_name}' not found"}), + status_code=status.HTTP_404_NOT_FOUND, + media_type="application/json", + ) + + batch_source = getattr(fv, "batch_source", None) + if batch_source is None: + return Response( + content=json.dumps({"detail": f"No batch source for '{fv_name}'"}), + status_code=status.HTTP_400_BAD_REQUEST, + media_type="application/json", + ) + + feature_names = [f.name for f in fv.features] + join_keys = ( + fv.join_keys + if hasattr(fv, "join_keys") + else (fv.entities if fv.entities else []) + ) + + provider = store._get_provider() + timestamp_field = batch_source.timestamp_field + labeler_field = getattr(fv, "labeler_field", "labeler") + conflict_policy = getattr( + fv, "conflict_policy", ConflictPolicy.LAST_WRITE_WINS + ) + + try: + job = provider.offline_store.pull_all_from_table_or_query( + config=store.config, + data_source=batch_source, + join_key_columns=join_keys, + feature_name_columns=feature_names, + timestamp_field=timestamp_field, + ) + raw_df = job.to_df() + except Exception: + return { + "total_entities": 0, + "total_annotations": 0, + "feature_names": feature_names, + "distributions": {}, + "coverage_pct": {}, + "null_counts": {}, + "labeler_stats": {}, + "staleness_seconds": None, + "oldest_label_ts": None, + "newest_label_ts": None, + "labeler_field": labeler_field, + "conflict_policy": conflict_policy.value, + "hint": "No label data found yet. Push labels to compute quality metrics.", + } + + total_annotations = len(raw_df) + + # Labeler stats computed on raw data (before resolution) + labeler_stats: Dict[str, int] = {} + if labeler_field and labeler_field in raw_df.columns: + labeler_stats = ( + raw_df[labeler_field].dropna().astype(str).value_counts().to_dict() + ) + + # Resolve conflicts to get one row per entity + df = resolve_conflicts( + df=raw_df, + join_key_columns=join_keys, + feature_name_columns=feature_names, + timestamp_field=timestamp_field, + labeler_field=labeler_field, + conflict_policy=conflict_policy, + ) + + total_entities = len(df) + ts_col = timestamp_field + + staleness_seconds = None + oldest_ts = None + newest_ts = None + if ts_col in df.columns and not df[ts_col].empty: + ts_series = pd.to_datetime(df[ts_col], utc=True) + oldest_ts = ts_series.min().isoformat() + newest_ts = ts_series.max().isoformat() + staleness_seconds = ( + datetime.now(timezone.utc) - ts_series.max() + ).total_seconds() + + distributions: Dict[str, Dict[str, int]] = {} + coverage: Dict[str, float] = {} + null_counts: Dict[str, int] = {} + + for fn in feature_names: + if fn in df.columns: + col = df[fn] + nulls = int(col.isna().sum()) + total = len(col) + null_counts[fn] = nulls + coverage[fn] = ((total - nulls) / total * 100) if total > 0 else 0.0 + non_null = col.dropna() + distributions[fn] = ( + non_null.astype(str).value_counts().head(20).to_dict() + ) + else: + null_counts[fn] = total_entities + coverage[fn] = 0.0 + distributions[fn] = {} + + return { + "total_entities": total_entities, + "total_annotations": total_annotations, + "feature_names": feature_names, + "distributions": distributions, + "coverage_pct": coverage, + "null_counts": null_counts, + "labeler_stats": labeler_stats, + "staleness_seconds": staleness_seconds, + "oldest_label_ts": oldest_ts, + "newest_label_ts": newest_ts, + "labeler_field": labeler_field, + "conflict_policy": conflict_policy.value, + } + except Exception: + logger.exception("Label quality failed") + return _safe_error_response("Label quality") + + # --- Active Learning Endpoint (offline-store-based, backend-agnostic) --- + + class ActiveLearningRequest(BaseModel): + feature_view: str + reference_feature_view: Optional[str] = None + limit: Optional[int] = 50 + + @rest_app.post("/active-learning/candidates") + def active_learning_candidates(request: ActiveLearningRequest): + """Find entities that exist in a reference feature view but have NOT been labeled yet.""" + try: + fv_name = request.feature_view + fv: Any = None + try: + fv = store.registry.get_label_view(fv_name, store.project) + except Exception: + pass + + if fv is None: + return Response( + content=json.dumps({"detail": f"Label view '{fv_name}' not found"}), + status_code=status.HTTP_404_NOT_FOUND, + media_type="application/json", + ) + + ref_fv_name = request.reference_feature_view or ( + getattr(fv, "reference_feature_view", None) or "" + ) + + if not ref_fv_name: + return Response( + content=json.dumps( + { + "detail": "No reference feature view specified. " + "Provide a feature view containing all entities." + } + ), + status_code=status.HTTP_400_BAD_REQUEST, + media_type="application/json", + ) + + ref_fv: Any = None + try: + ref_fv = store.get_feature_view(ref_fv_name) + except Exception: + pass + + if ref_fv is None: + return Response( + content=json.dumps( + {"detail": f"Reference feature view '{ref_fv_name}' not found"} + ), + status_code=status.HTTP_404_NOT_FOUND, + media_type="application/json", + ) + + provider = store._get_provider() + + # Get all entities from reference feature view + ref_batch_source = getattr(ref_fv, "batch_source", None) + if ref_batch_source is None: + return Response( + content=json.dumps( + { + "detail": f"No batch source for reference view '{ref_fv_name}'" + } + ), + status_code=status.HTTP_400_BAD_REQUEST, + media_type="application/json", + ) + + ref_join_keys = ( + ref_fv.join_keys + if hasattr(ref_fv, "join_keys") + else (ref_fv.entities if ref_fv.entities else []) + ) + ref_feature_names = [f.name for f in ref_fv.features] + + try: + ref_job = provider.offline_store.pull_all_from_table_or_query( + config=store.config, + data_source=ref_batch_source, + join_key_columns=ref_join_keys, + feature_name_columns=ref_feature_names[:1], + timestamp_field=ref_batch_source.timestamp_field, + created_timestamp_column=getattr( + ref_batch_source, "created_timestamp_column", None + ), + ) + ref_df = ref_job.to_df() + except Exception: + return Response( + content=json.dumps( + { + "detail": f"Could not read reference feature view '{ref_fv_name}'. Ensure data exists." + } + ), + status_code=status.HTTP_400_BAD_REQUEST, + media_type="application/json", + ) + + # Get labeled entities from the label view + label_batch_source = getattr(fv, "batch_source", None) + label_join_keys = ( + fv.join_keys + if hasattr(fv, "join_keys") + else (fv.entities if fv.entities else []) + ) + label_feature_names = [f.name for f in fv.features] + + labeled_keys: set = set() + if label_batch_source: + try: + label_job = provider.offline_store.pull_all_from_table_or_query( + config=store.config, + data_source=label_batch_source, + join_key_columns=label_join_keys, + feature_name_columns=label_feature_names, + timestamp_field=label_batch_source.timestamp_field, + created_timestamp_column=getattr( + label_batch_source, + "created_timestamp_column", + None, + ), + ) + label_df = label_job.to_df() + if not label_df.empty and label_join_keys: + labeled_keys = set( + label_df[label_join_keys[0]].dropna().astype(str) + ) + except Exception: + labeled_keys = set() + + # Find unlabeled entities (in ref but not in labels) + common_key = label_join_keys[0] if label_join_keys else ref_join_keys[0] + unlabeled_entities: List[Dict[str, Any]] = [] + + if common_key in ref_df.columns: + seen_keys: set = set() + for _, row in ref_df.iterrows(): + key_val = ( + str(row[common_key]) if pd.notna(row[common_key]) else None + ) + if ( + key_val + and key_val not in labeled_keys + and key_val not in seen_keys + ): + seen_keys.add(key_val) + entity = {common_key: row[common_key]} + unlabeled_entities.append(entity) + if len(unlabeled_entities) >= (request.limit or 50): + break + + return { + "unlabeled_entities": unlabeled_entities, + "total_labeled": len(labeled_keys), + "total_unlabeled": len(unlabeled_entities), + "entity_names": label_join_keys, + "feature_names": label_feature_names, + "label_view": fv_name, + "reference_feature_view": ref_fv_name, + } + except Exception: + logger.exception("Active learning candidates failed") + return _safe_error_response("Active learning candidates") + + # --- Production Label Management Endpoints --- + + class BatchPushRequest(BaseModel): + push_source_name: str + data: List[Dict[str, Any]] + to: Optional[str] = "online" + + @rest_app.post("/batch-push") + def batch_push(request: BatchPushRequest): + """Batch push labels from CSV/parquet upload or external systems (Argilla, Label Studio).""" + try: + df = pd.DataFrame(request.data) + to = request.to or "online" + if to == "online_and_offline": + store.push( + request.push_source_name, + df, + to=feast.data_source.PushMode.ONLINE_AND_OFFLINE, + ) + elif to == "offline": + store.push( + request.push_source_name, df, to=feast.data_source.PushMode.OFFLINE + ) + else: + store.push( + request.push_source_name, df, to=feast.data_source.PushMode.ONLINE + ) + return {"status": "ok", "rows_pushed": len(df)} + except Exception: + logger.exception("Batch push failed") + return _safe_error_response("Batch push") + + class WebhookPushRequest(BaseModel): + push_source_name: str + records: List[Dict[str, Any]] + api_key: Optional[str] = None + + @rest_app.post("/webhook/label-ingest") + def webhook_label_ingest(request: WebhookPushRequest): + """Webhook endpoint for external annotation tools (Argilla, Label Studio) to push labels.""" + try: + from datetime import datetime, timezone + + for record in request.records: + if "event_timestamp" not in record: + record["event_timestamp"] = datetime.now(timezone.utc).isoformat() + + df = pd.DataFrame(request.records) + store.push( + request.push_source_name, + df, + to=feast.data_source.PushMode.ONLINE_AND_OFFLINE, + ) + return { + "status": "ok", + "records_ingested": len(request.records), + "push_source": request.push_source_name, + } + except Exception: + logger.exception("Webhook label ingest failed") + return _safe_error_response("Webhook label ingest") + + class TrainingExportRequest(BaseModel): + feature_service: str + entity_df: Dict[str, List] + start_date: Optional[str] = None + end_date: Optional[str] = None + + @rest_app.post("/training-dataset/export") + def export_training_dataset(request: TrainingExportRequest): + """Generate a training dataset using get_historical_features and return as JSON (downloadable).""" + try: + from datetime import datetime, timezone + + entity_df = pd.DataFrame(request.entity_df) + + if "event_timestamp" not in entity_df.columns: + if request.end_date: + ts = pd.Timestamp(request.end_date, tz="UTC") + else: + ts = pd.Timestamp(datetime.now(timezone.utc)) + entity_df["event_timestamp"] = ts + + fs = store.get_feature_service(request.feature_service) + training_df = store.get_historical_features( + entity_df=entity_df, + features=fs, + ).to_df() + + result = training_df.to_dict(orient="records") + for row in result: + for k, v in row.items(): + if pd.isna(v): + row[k] = None + elif hasattr(v, "isoformat"): + row[k] = v.isoformat() + + return { + "data": result, + "columns": list(training_df.columns), + "row_count": len(training_df), + "feature_service": request.feature_service, + } + except Exception: + logger.exception("Training dataset export failed") + return _safe_error_response("Training dataset export") + + @rest_app.get("/webhook/config/{label_view_name}") + def webhook_config(label_view_name: str): + """Return webhook configuration info for integrating external annotation tools.""" + try: + fv = store.registry.get_label_view(label_view_name, store.project) + push_source_name = fv.source.name if fv.source else None + feature_names = [f.name for f in fv.features] + entity_names = [ec.name for ec in fv.entity_columns] + labeler_field = getattr(fv, "labeler_field", None) + + return { + "label_view": label_view_name, + "push_source_name": push_source_name, + "webhook_url": "/api/v1/webhook/label-ingest", + "batch_url": "/api/v1/batch-push", + "required_fields": entity_names + + feature_names + + ([labeler_field] if labeler_field else []), + "entity_fields": entity_names, + "label_fields": feature_names, + "labeler_field": labeler_field, + "payload_example": { + "push_source_name": push_source_name, + "records": [ + { + **{e: f"<{e}_value>" for e in entity_names}, + **{f: f"<{f}_value>" for f in feature_names}, + **( + {"event_timestamp": "2026-01-01T00:00:00Z"} + if True + else {} + ), + **( + {labeler_field: ""} if labeler_field else {} + ), + } + ], + }, + } + except Exception: + logger.exception("Webhook config lookup failed") + return _safe_error_response("Webhook config", status.HTTP_404_NOT_FOUND) + + @rest_app.get("/annotation-config/{label_view_name}") + def annotation_config(label_view_name: str): + """Return annotation profile and field role config parsed from LabelView tags. + + The UI uses this to select the right annotation method and map + user interactions to schema fields. + """ + try: + fv = store.registry.get_label_view(label_view_name, store.project) + + tags = dict(getattr(fv, "tags", {})) + profile = tags.get("feast.io/labeling-method", "table") + + field_roles: Dict[str, str] = {} + label_values: Dict[str, List] = {} + label_widgets: Dict[str, str] = {} + + for key, value in tags.items(): + if key.startswith("feast.io/field-role:"): + field_name = key[len("feast.io/field-role:") :] + field_roles[field_name] = value + elif key.startswith("feast.io/label-values:"): + field_name = key[len("feast.io/label-values:") :] + label_values[field_name] = [v.strip() for v in value.split(",")] + elif key.startswith("feast.io/label-widget:"): + field_name = key[len("feast.io/label-widget:") :] + label_widgets[field_name] = value + + entity_names = fv.entities if fv.entities else [] + feature_names = [f.name for f in fv.features] + labeler_field = getattr(fv, "labeler_field", "labeler") + push_source_name = fv.source.name if fv.source else None + + return { + "label_view": label_view_name, + "profile": profile, + "field_roles": field_roles, + "label_values": label_values, + "label_widgets": label_widgets, + "entities": entity_names, + "features": feature_names, + "labeler_field": labeler_field, + "push_source_name": push_source_name, + } + except Exception: + logger.exception("Annotation config lookup failed") + return _safe_error_response("Annotation config", status.HTTP_404_NOT_FOUND) + + app.mount("/api/v1", rest_app) + + @app.get("/health") + def health(): + try: + store.registry.list_projects(allow_cache=True) + return Response(status_code=status.HTTP_200_OK) + except Exception: + return Response(status_code=status.HTTP_503_SERVICE_UNAVAILABLE) + + logger.info("REST registry API mounted at /api/v1") + def get_app( store: "feast.FeatureStore", project_id: str, - registry_ttl_secs: int, root_path: str = "", ): app = FastAPI() @@ -27,102 +810,288 @@ def get_app( allow_headers=["*"], ) - # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down - registry_proto = None - shutting_down = False - active_timer: Optional[threading.Timer] = None - - def async_refresh(): - store.refresh_registry() - nonlocal registry_proto - registry_proto = store.registry.proto() - if shutting_down: - return - nonlocal active_timer - active_timer = threading.Timer(registry_ttl_secs, async_refresh) - active_timer.start() - - @app.on_event("shutdown") - def shutdown_event(): - nonlocal shutting_down - shutting_down = True - if active_timer: - active_timer.cancel() - - async_refresh() + _setup_rest_mode(app, store) ui_dir_ref = importlib_resources.files(__spec__.parent) / "ui/build/" # type: ignore[name-defined, arg-type] with importlib_resources.as_file(ui_dir_ref) as ui_dir: - # Initialize with the projects-list.json file + projects_dict = _build_projects_list(store, project_id, root_path) with ui_dir.joinpath("projects-list.json").open(mode="w") as f: - # Get all projects from the registry - discovered_projects = [] - registry = store.registry.proto() - - # Use the projects list from the registry - if registry and registry.projects and len(registry.projects) > 0: - for proj in registry.projects: - if proj.spec and proj.spec.name: - discovered_projects.append( - { - "name": proj.spec.name.replace("_", " ").title(), - "description": proj.spec.description - or f"Project: {proj.spec.name}", - "id": proj.spec.name, - "registryPath": f"{root_path}/registry", - } - ) - else: - # If no projects in registry, use the current project from feature_store.yaml - discovered_projects.append( + f.write(json.dumps(projects_dict)) + + @app.get("/api/mlflow-runs") + def get_mlflow_runs(max_results: int = 50): + """Return MLflow runs linked to this Feast project via auto-logging.""" + mlflow_cfg = getattr(store.config, "mlflow", None) + if not mlflow_cfg or not mlflow_cfg.enabled: + return {"runs": [], "mlflow_uri": None} + + try: + import mlflow + + tracking_uri = mlflow_cfg.get_tracking_uri() + mlflow_ui_base = tracking_uri or mlflow.get_tracking_uri() or "" + client = mlflow.MlflowClient(tracking_uri=tracking_uri) + + project_name = store.config.project + experiment = client.get_experiment_by_name(project_name) + if experiment is None: + return {"runs": [], "mlflow_uri": mlflow_ui_base or None} + experiment_ids = [experiment.experiment_id] + + safe_project = project_name.replace("\\", "\\\\").replace("'", "\\'") + filter_str = ( + f"tags.`feast.project` = '{safe_project}' " + f"AND tags.`feast.retrieval_type` != ''" + ) + + max_results = min(max(max_results, 1), 200) + runs = client.search_runs( + experiment_ids=experiment_ids, + filter_string=filter_str, + max_results=max_results, + order_by=["start_time DESC"], + ) + + run_id_to_models: Dict[str, List[dict]] = {} + try: + for rm in client.search_registered_models(): + for mv in rm.latest_versions or []: + if mv.run_id: + run_id_to_models.setdefault(mv.run_id, []).append( + { + "model_name": rm.name, + "version": mv.version, + "stage": mv.current_stage, + "mlflow_url": ( + f"{mlflow_ui_base}/#/models/" + f"{rm.name}/versions/{mv.version}" + ), + } + ) + except Exception: + pass + + result = [] + for run in runs: + run_tags = run.data.tags + run_params = run.data.params + fv_raw = run_tags.get("feast.feature_views", "") + refs_raw = run_tags.get( + "feast.feature_refs", + run_params.get("feast.feature_refs", ""), + ) + result.append( { - "name": "Project", - "description": "Test project", - "id": project_id, - "registryPath": f"{root_path}/registry", + "run_id": run.info.run_id, + "run_name": run.info.run_name, + "status": run.info.status, + "start_time": run.info.start_time, + "feature_service": run_tags.get("feast.feature_service"), + "feature_views": [v for v in fv_raw.split(",") if v], + "feature_refs": [v for v in refs_raw.split(",") if v], + "retrieval_type": run_tags.get("feast.retrieval_type"), + "entity_count": run_tags.get( + "feast.entity_count", + run_params.get("feast.entity_count"), + ), + "mlflow_url": ( + f"{mlflow_ui_base}/#/experiments/" + f"{run.info.experiment_id}/runs/{run.info.run_id}" + ), + "registered_models": run_id_to_models.get(run.info.run_id, []), } ) - # Add "All Projects" option at the beginning if there are multiple projects - if len(discovered_projects) > 1: - all_projects_entry = { - "name": "All Projects", - "description": "View data across all projects", - "id": "all", - "registryPath": f"{root_path}/registry", - } - discovered_projects.insert(0, all_projects_entry) + return {"runs": result, "mlflow_uri": mlflow_ui_base or None} + except ImportError: + return { + "runs": [], + "mlflow_uri": None, + "error": "mlflow is not installed", + } + except Exception: + return { + "runs": [], + "mlflow_uri": None, + "error": "Failed to fetch MLflow runs", + } - projects_dict = {"projects": discovered_projects} - f.write(json.dumps(projects_dict)) + _feature_usage_cache: Dict = {"data": None, "timestamp": 0.0} + _FEATURE_USAGE_TTL_SECONDS = 300 - @app.get("/registry") - def read_registry(): - if registry_proto is None: - return Response( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE - ) # Service Unavailable - return Response( - content=registry_proto.SerializeToString(), - media_type="application/octet-stream", - ) + @app.get("/api/mlflow-feature-usage") + def get_mlflow_feature_usage(): + """Return per-feature-view usage stats aggregated from MLflow runs. - @app.get("/health") - def health(): - return ( - Response(status_code=status.HTTP_200_OK) - if registry_proto - else Response(status_code=status.HTTP_503_SERVICE_UNAVAILABLE) - ) + Caches results for 5 minutes to avoid hammering the MLflow server. + """ + import time as _time + + mlflow_cfg = getattr(store.config, "mlflow", None) + if not mlflow_cfg or not mlflow_cfg.enabled: + return {"feature_usage": {}, "mlflow_enabled": False} + + now = _time.monotonic() + if ( + _feature_usage_cache["data"] is not None + and (now - _feature_usage_cache["timestamp"]) < _FEATURE_USAGE_TTL_SECONDS + ): + return _feature_usage_cache["data"] + + try: + import mlflow + + tracking_uri = mlflow_cfg.get_tracking_uri() + client = mlflow.MlflowClient(tracking_uri=tracking_uri) + project_name = store.config.project + + experiment = client.get_experiment_by_name(project_name) + if experiment is None: + result = {"feature_usage": {}, "mlflow_enabled": True} + _feature_usage_cache["data"] = result + _feature_usage_cache["timestamp"] = now + return result + + safe_project = project_name.replace("\\", "\\\\").replace("'", "\\'") + filter_str = ( + f"tags.`feast.project` = '{safe_project}' " + f"AND tags.`feast.retrieval_type` != ''" + ) + runs = client.search_runs( + experiment_ids=[experiment.experiment_id], + filter_string=filter_str, + max_results=200, + order_by=["start_time DESC"], + ) + + run_id_to_models: Dict[str, List[str]] = {} + try: + for rm in client.search_registered_models(): + for mv in rm.latest_versions or []: + if mv.run_id: + run_id_to_models.setdefault(mv.run_id, []).append(rm.name) + except Exception: + pass + + usage: Dict[str, dict] = {} + for run in runs: + refs_raw = run.data.tags.get("feast.feature_refs", "") + fv_names = set() + for ref in refs_raw.split(","): + ref = ref.strip() + if ":" in ref: + fv_names.add(ref.split(":")[0]) + + run_models = run_id_to_models.get(run.info.run_id, []) + + for fv_name in fv_names: + if fv_name not in usage: + usage[fv_name] = { + "run_count": 0, + "last_used": None, + "models": [], + } + usage[fv_name]["run_count"] += 1 + run_ts = run.info.start_time + if usage[fv_name]["last_used"] is None or ( + run_ts and run_ts > usage[fv_name]["last_used"] + ): + usage[fv_name]["last_used"] = run_ts + for m in run_models: + if m not in usage[fv_name]["models"]: + usage[fv_name]["models"].append(m) + + result = {"feature_usage": usage, "mlflow_enabled": True} + _feature_usage_cache["data"] = result + _feature_usage_cache["timestamp"] = now + return result + except ImportError: + return { + "feature_usage": {}, + "mlflow_enabled": False, + "error": "mlflow is not installed", + } + except Exception as e: + logger.debug("Failed to fetch feature usage: %s", e) + return { + "feature_usage": {}, + "mlflow_enabled": True, + "error": "Failed to fetch usage data", + } + + @app.get("/api/mlflow-feature-models") + def get_mlflow_feature_models(): + """Return a mapping of feature_ref -> registered models that use it. + + Walks the MLflow Model Registry, inspects the training run for each + model's latest version(s), reads the ``feast.feature_refs`` tag, and + inverts it into a reverse index so the UI can show which registered + models depend on a given feature. + """ + mlflow_cfg = getattr(store.config, "mlflow", None) + if not mlflow_cfg or not mlflow_cfg.enabled: + return {"feature_models": {}} + + try: + import mlflow + + tracking_uri = mlflow_cfg.get_tracking_uri() + mlflow_ui_base = tracking_uri or mlflow.get_tracking_uri() or "" + client = mlflow.MlflowClient(tracking_uri=tracking_uri) + project_name = store.config.project + + feature_models: Dict[str, List[dict]] = {} + + for rm in client.search_registered_models(): + model_name = rm.name + latest_versions = rm.latest_versions or [] + for mv in latest_versions: + if not mv.run_id: + continue + try: + run = client.get_run(mv.run_id) + except Exception: + continue + + tags = run.data.tags + if tags.get("feast.project") != project_name: + continue + + refs_raw = tags.get("feast.feature_refs", "") + feature_refs = [r for r in refs_raw.split(",") if r] + + model_info = { + "model_name": model_name, + "version": mv.version, + "stage": mv.current_stage, + "mlflow_url": ( + f"{mlflow_ui_base}/#/models/" + f"{model_name}/versions/{mv.version}" + ), + } + + for ref in feature_refs: + feature_models.setdefault(ref, []).append(model_info) + + return {"feature_models": feature_models} + except ImportError: + return { + "feature_models": {}, + "error": "mlflow is not installed", + } + except Exception as e: + logger.debug("Failed to fetch MLflow feature-model mapping: %s", e) + return { + "feature_models": {}, + "error": "Failed to fetch model data", + } # For all other paths (such as paths that would otherwise be handled by react router), pass to React @app.api_route("/p/{path_name:path}", methods=["GET"]) def catch_all(): filename = ui_dir.joinpath("index.html") - with open(filename) as f: content = f.read() - return Response(content, media_type="text/html") app.mount( @@ -138,9 +1107,7 @@ def start_server( store: "feast.FeatureStore", host: str, port: int, - get_registry_dump: Callable, project_id: str, - registry_ttl_sec: int, root_path: str = "", tls_key_path: str = "", tls_cert_path: str = "", @@ -148,9 +1115,11 @@ def start_server( app = get_app( store, project_id, - registry_ttl_sec, root_path, ) + + logger.info(f"Starting Feast UI server on {host}:{port}") + if tls_key_path and tls_cert_path: uvicorn.run( app, diff --git a/sdk/python/feast/utils.py b/sdk/python/feast/utils.py index 511186066c6..4c10c1903e5 100644 --- a/sdk/python/feast/utils.py +++ b/sdk/python/feast/utils.py @@ -1,10 +1,12 @@ import copy import itertools +import logging import os +import threading import typing import warnings from collections import Counter, defaultdict -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone from pathlib import Path from typing import ( Any, @@ -60,6 +62,55 @@ USER_AGENT = "{}/{}".format(APPLICATION_NAME, get_version()) +def _parse_feature_ref(ref: str) -> Tuple[str, Optional[int], str]: + """Parse 'fv_name@version:feature' into (fv_name, version_number, feature_name). + + If no @version is present, version_number is None (meaning 'latest'). + Examples: + 'driver_stats:trips' -> ('driver_stats', None, 'trips') + 'driver_stats@v2:trips' -> ('driver_stats', 2, 'trips') + 'driver_stats@latest:trips' -> ('driver_stats', None, 'trips') + """ + import re + + colon_idx = ref.find(":") + if colon_idx < 0: + raise ValueError( + f"Invalid feature reference '{ref}'. Expected format: ':' " + f"or '@:'" + ) + + fv_part = ref[:colon_idx] + feature_name = ref[colon_idx + 1 :] + + at_idx = fv_part.find("@") + if at_idx < 0: + return (fv_part, None, feature_name) + + fv_name = fv_part[:at_idx] + version_str = fv_part[at_idx + 1 :] + + if not version_str or version_str.lower() == "latest": + return (fv_name, None, feature_name) + + # Parse version number from formats like "v2", "V2" + match = re.match(r"^[vV](\d+)$", version_str) + if not match: + # Not a recognized version format — treat entire fv_part as the name + return (fv_part, None, feature_name) + + return (fv_name, int(match.group(1)), feature_name) + + +def _strip_version_from_ref(ref: str) -> str: + """Strip @version from a feature reference, returning 'fv_name:feature'. + + Used to produce clean refs for output column naming. + """ + fv_name, _, feature_name = _parse_feature_ref(ref) + return f"{fv_name}:{feature_name}" + + def get_user_agent(): return USER_AGENT @@ -72,6 +123,37 @@ def make_tzaware(t: datetime) -> datetime: return t +def compute_non_entity_date_range( + feature_views: List["FeatureView"], + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + default_window_days: int = 30, +) -> Tuple[datetime, datetime]: + if end_date is None: + end_date = datetime.now(tz=timezone.utc) + else: + end_date = make_tzaware(end_date) + + if start_date is None: + max_ttl_seconds = max( + ( + int(fv.ttl.total_seconds()) + for fv in feature_views + if fv.ttl and isinstance(fv.ttl, timedelta) + ), + default=0, + ) + start_date = end_date - timedelta( + seconds=max_ttl_seconds + if max_ttl_seconds > 0 + else default_window_days * 86400 + ) + else: + start_date = make_tzaware(start_date) + + return start_date, end_date + + def make_df_tzaware(t: pd.DataFrame) -> pd.DataFrame: """Make all datetime type columns tzaware; leave everything else intact.""" df = t.copy() # don't modify incoming dataframe inplace @@ -118,9 +200,12 @@ def _get_requested_feature_views_to_features_dict( ) for ref in feature_refs: - ref_parts = ref.split(":") - feature_view_from_ref = ref_parts[0] - feature_from_ref = ref_parts[1] + fv_name, version_num, feature_from_ref = _parse_feature_ref(ref) + # Build the key that matches projection.name_to_use() + if version_num is not None: + feature_view_from_ref = f"{fv_name}@v{version_num}" + else: + feature_view_from_ref = fv_name found = False for fv in feature_views: @@ -493,7 +578,7 @@ def _validate_feature_refs(feature_refs: List[str], full_feature_names: bool = F ref for ref, occurrences in Counter(feature_refs).items() if occurrences > 1 ] else: - feature_names = [ref.split(":")[1] for ref in feature_refs] + feature_names = [_parse_feature_ref(ref)[2] for ref in feature_refs] collided_feature_names = [ ref for ref, occurrences in Counter(feature_names).items() @@ -540,7 +625,12 @@ def _group_feature_refs( on_demand_view_features = defaultdict(set) for ref in features: - view_name, feat_name = ref.split(":") + fv_name, version_num, feat_name = _parse_feature_ref(ref) + # Build the key that matches projection.name_to_use() + if version_num is not None: + view_name = f"{fv_name}@v{version_num}" + else: + view_name = fv_name if view_name in view_index: if hasattr(view_index[view_name], "write_to_online_store"): tmp_feat_name = [ @@ -577,30 +667,6 @@ def _group_feature_refs( return fvs_result, odfvs_result -def construct_response_feature_vector( - values_vector: Iterable[Any], - statuses_vector: Iterable[Any], - timestamp_vector: Iterable[Any], - mapping_indexes: Iterable[List[int]], - output_len: int, -) -> GetOnlineFeaturesResponse.FeatureVector: - values_output: Iterable[Any] = [None] * output_len - statuses_output: Iterable[Any] = [None] * output_len - timestamp_output: Iterable[Any] = [None] * output_len - - for i, destinations in enumerate(mapping_indexes): - for idx in destinations: - values_output[idx] = values_vector[i] # type: ignore[index] - statuses_output[idx] = statuses_vector[i] # type: ignore[index] - timestamp_output[idx] = timestamp_vector[i] # type: ignore[index] - - return GetOnlineFeaturesResponse.FeatureVector( - values=values_output, - statuses=statuses_output, - event_timestamps=timestamp_output, - ) - - def _apply_aggregations_to_response( response_data: Union[pyarrow.Table, Dict[str, List[Any]]], aggregations, @@ -662,6 +728,7 @@ def _augment_response_with_on_demand_transforms( feature_refs: List[str], requested_on_demand_feature_views: List["OnDemandFeatureView"], full_feature_names: bool, + feature_types: Optional[Dict[str, "ValueType"]] = None, ): """Computes on demand feature values and adds them to the result rows. @@ -684,7 +751,7 @@ def _augment_response_with_on_demand_transforms( odfv_feature_refs = defaultdict(list) for feature_ref in feature_refs: - view_name, feature_name = feature_ref.split(":") + view_name, _, feature_name = _parse_feature_ref(feature_ref) if view_name in requested_odfv_feature_names: odfv_feature_refs[view_name].append( f"{requested_odfv_map[view_name].projection.name_to_use()}__{feature_name}" @@ -692,15 +759,33 @@ def _augment_response_with_on_demand_transforms( else feature_name ) - initial_response = OnlineResponse(online_features_response) + initial_response = OnlineResponse( + online_features_response, feature_types=feature_types + ) initial_response_arrow: Optional[pyarrow.Table] = None initial_response_dict: Optional[Dict[str, List[Any]]] = None + def _is_metrics_active(): + try: + from feast.metrics import _config + + return _config.online_features + except Exception: + return False + + _metrics_active = _is_metrics_active() + # Apply on demand transformations and augment the result rows odfv_result_names = set() for odfv_name, _feature_refs in odfv_feature_refs.items(): odfv = requested_odfv_map[odfv_name] if not odfv.write_to_online_store: + _should_track = _metrics_active and getattr(odfv, "track_metrics", False) + if _should_track: + import time as _time + + _transform_start = _time.monotonic() + # Apply aggregations if configured. if odfv.aggregations: if odfv.mode == "python": @@ -721,11 +806,12 @@ def _augment_response_with_on_demand_transforms( odfv.entities, odfv.mode, ) + continue # Apply transformation. Note: aggregations and transformation configs are mutually exclusive # TODO: Fix to make it work for having both aggregation and transformation # ticket: https://github.com/feast-dev/feast/issues/5689 - elif odfv.mode == "python": + if odfv.mode == "python": if initial_response_dict is None: initial_response_dict = initial_response.to_dict() transformed_features_dict: Dict[str, List[Any]] = odfv.transform_dict( @@ -742,6 +828,13 @@ def _augment_response_with_on_demand_transforms( f"Invalid OnDemandFeatureMode: {odfv.mode}. Expected one of 'pandas', 'python', or 'substrait'." ) + if _should_track: + from feast.metrics import track_transformation + + track_transformation( + odfv_name, odfv.mode, _time.monotonic() - _transform_start + ) + transformed_features = ( transformed_features_dict if odfv.mode == "python" @@ -1017,98 +1110,6 @@ def ensure_request_data_values_exist( raise RequestDataNotFoundInEntityRowsException(feature_names=missing_features) -def _populate_response_from_feature_data( - feature_data: Iterable[ - Tuple[ - Iterable[Timestamp], Iterable["FieldStatus.ValueType"], Iterable[ValueProto] - ] - ], - indexes: Iterable[List[int]], - online_features_response: GetOnlineFeaturesResponse, - full_feature_names: bool, - requested_features: Iterable[str], - table: "FeatureView", - output_len: int, -): - """Populate the GetOnlineFeaturesResponse with feature data. - - This method assumes that `_read_from_online_store` returns data for each - combination of Entities in `entity_rows` in the same order as they - are provided. - - Args: - feature_data: A list of data in Protobuf form which was retrieved from the OnlineStore. - indexes: A list of indexes which should be the same length as `feature_data`. Each list - of indexes corresponds to a set of result rows in `online_features_response`. - online_features_response: The object to populate. - full_feature_names: A boolean that provides the option to add the feature view prefixes to the feature names, - changing them from the format "feature" to "feature_view__feature" (e.g., "daily_transactions" changes to - "customer_fv__daily_transactions"). - requested_features: The names of the features in `feature_data`. This should be ordered in the same way as the - data in `feature_data`. - table: The FeatureView that `feature_data` was retrieved from. - output_len: The number of result rows in `online_features_response`. - """ - # Add the feature names to the response. - table_name = table.projection.name_to_use() - requested_feature_refs = [ - f"{table_name}__{feature_name}" if full_feature_names else feature_name - for feature_name in requested_features - ] - online_features_response.metadata.feature_names.val.extend(requested_feature_refs) - - # Process each feature vector in a single pass - for timestamp_vector, statuses_vector, values_vector in feature_data: - response_vector = construct_response_feature_vector( - values_vector, statuses_vector, timestamp_vector, indexes, output_len - ) - online_features_response.results.append(response_vector) - - -def _populate_response_from_feature_data_v2( - feature_data: Iterable[ - Tuple[ - Iterable[Timestamp], Iterable["FieldStatus.ValueType"], Iterable[ValueProto] - ] - ], - indexes: Iterable[List[int]], - online_features_response: GetOnlineFeaturesResponse, - requested_features: Iterable[str], - output_len: int, -): - """Populate the GetOnlineFeaturesResponse with feature data. - - This method assumes that `_read_from_online_store` returns data for each - combination of Entities in `entity_rows` in the same order as they - are provided. - - Args: - feature_data: A list of data in Protobuf form which was retrieved from the OnlineStore. - indexes: A list of indexes which should be the same length as `feature_data`. Each list - of indexes corresponds to a set of result rows in `online_features_response`. - online_features_response: The object to populate. - full_feature_names: A boolean that provides the option to add the feature view prefixes to the feature names, - changing them from the format "feature" to "feature_view__feature" (e.g., "daily_transactions" changes to - "customer_fv__daily_transactions"). - requested_features: The names of the features in `feature_data`. This should be ordered in the same way as the - data in `feature_data`. - output_len: The number of result rows in `online_features_response`. - """ - # Add the feature names to the response. - requested_feature_refs = [(feature_name) for feature_name in requested_features] - online_features_response.metadata.feature_names.val.extend(requested_feature_refs) - - timestamps, statuses, values = zip(*feature_data) - - # Populate the result with data fetched from the OnlineStore - # which is guaranteed to be aligned with `requested_features`. - for timestamp_vector, statuses_vector, values_vector in feature_data: - response_vector = construct_response_feature_vector( - values_vector, statuses_vector, timestamp_vector, indexes, output_len - ) - online_features_response.results.append(response_vector) - - def _convert_entity_key_to_proto_to_dict( entity_key_vals: List[EntityKeyProto], ) -> Dict[str, List[ValueProto]]: @@ -1205,16 +1206,67 @@ def _get_feature_views_to_use( if isinstance(features, FeatureService): feature_views = [ - (projection.name, projection) + (projection.name, None, projection) for projection in features.feature_view_projections ] else: assert features is not None - feature_views = [(feature.split(":")[0], None) for feature in features] # type: ignore[misc] + # Parse version-qualified refs: 'fv@v2:feat' -> ('fv', 2, None) + parsed = [] + seen = set() + for feature in features: + fv_name, version_num, _ = _parse_feature_ref(feature) + key = (fv_name, version_num) + if key not in seen: + seen.add(key) + parsed.append((fv_name, version_num, None)) + feature_views = parsed # type: ignore[assignment] fvs_to_use, od_fvs_to_use = [], [] - for name, projection in feature_views: - fv = registry.get_any_feature_view(name, project, allow_cache) + for name, version_num, projection in feature_views: + if version_num is not None: + if not getattr(registry, "enable_online_versioning", False): + raise ValueError( + f"Version-qualified ref '{name}@v{version_num}' not supported: " + f"online versioning is disabled. Set 'enable_online_feature_view_versioning: true' " + f"under 'registry' in feature_store.yaml." + ) + # Version-qualified reference: look up the specific version snapshot + try: + fv = registry.get_feature_view_by_version( + name, project, version_num, allow_cache + ) + except NotImplementedError: + # Fall back for v0 on registries that don't implement versioned lookup + if version_num == 0: + fv = registry.get_any_feature_view(name, project, allow_cache) + else: + raise + # Set version_tag on the projection so name_to_use() returns versioned key + if hasattr(fv, "projection") and fv.projection is not None: + fv.projection.version_tag = version_num + else: + fv = registry.get_any_feature_view(name, project, allow_cache) + + if hasattr(fv, "enabled") and not fv.enabled: + raise ValueError( + f"Feature view '{name}' is disabled and cannot serve features. " + f"Enable it with `feast feature-views enable {name}` or set enabled=True." + ) + + # Enforce lifecycle state gate: only serve if state is AVAILABLE_ONLINE + # or STATE_UNSPECIFIED (backward compat for pre-state feature views). + if hasattr(fv, "state"): + from feast.feature_view import FeatureViewState + + if isinstance(fv.state, FeatureViewState) and fv.state not in ( + FeatureViewState.STATE_UNSPECIFIED, + FeatureViewState.AVAILABLE_ONLINE, + ): + raise ValueError( + f"Feature view '{name}' is in state '{fv.state.name}' " + f"and cannot serve features. Only AVAILABLE_ONLINE feature views can serve." + ) if isinstance(fv, OnDemandFeatureView): od_fvs_to_use.append( @@ -1246,9 +1298,11 @@ def _get_feature_views_to_use( ): fv.entities = [] # type: ignore[attr-defined] fv.entity_columns = [] # type: ignore[attr-defined] - fvs_to_use.append( - fv.with_projection(copy.copy(projection)) if projection else fv - ) + if projection: + fv = fv.with_projection(copy.copy(projection)) + if version_num is not None: + fv.projection.version_tag = version_num + fvs_to_use.append(fv) return (fvs_to_use, od_fvs_to_use) @@ -1290,13 +1344,20 @@ def _get_online_request_context( requested_on_demand_feature_views, ) - requested_result_row_names = { - feat_ref.replace(":", "__") for feat_ref in _feature_refs - } - if not full_feature_names: - requested_result_row_names = { - name.rpartition("__")[-1] for name in requested_result_row_names - } + # Build expected result names, including version tag when present so + # multi-version queries (e.g. fv@v1:feat, fv@v2:feat) match the response. + requested_result_row_names = set() + for feat_ref in _feature_refs: + fv_name, version_num, feature_name = _parse_feature_ref(feat_ref) + if full_feature_names: + if version_num is not None: + requested_result_row_names.add( + f"{fv_name}@v{version_num}__{feature_name}" + ) + else: + requested_result_row_names.add(f"{fv_name}__{feature_name}") + else: + requested_result_row_names.add(feature_name) feature_views = list(view for view, _ in grouped_refs) @@ -1321,6 +1382,96 @@ def _get_online_request_context( ) +_feature_resolution_cache: Dict[tuple, tuple] = {} +_feature_resolution_cache_lock = threading.Lock() +_feature_resolution_registry_ts: Optional[datetime] = None + +_logger = logging.getLogger(__name__) + + +def _get_cached_request_context( + registry, + project: str, + features: Union[List[str], "FeatureService"], + full_feature_names: bool, +): + """Return the output of _get_online_request_context plus resolved ODFV + entity join keys, using a cache that is invalidated whenever the + registry refreshes or its cache TTL expires.""" + from feast.feature_service import FeatureService as _FS + + global _feature_resolution_cache, _feature_resolution_registry_ts + + registry_ts = getattr(registry, "cached_registry_proto_created", None) + + if isinstance(features, _FS): + features_key: tuple = ("__fs__", features.name) + else: + features_key = tuple(features) + + cache_key = (features_key, project, full_feature_names) + + is_cache_valid = getattr(registry, "is_cache_valid", None) + registry_cache_valid = is_cache_valid() if callable(is_cache_valid) else False + + if registry_ts is not None and registry_cache_valid: + with _feature_resolution_cache_lock: + if registry_ts != _feature_resolution_registry_ts: + _feature_resolution_cache.clear() + _feature_resolution_registry_ts = registry_ts + _logger.debug("Feature resolution cache cleared (registry refreshed)") + else: + cached = _feature_resolution_cache.get(cache_key) + if cached is not None: + return cached + + ctx = _get_online_request_context(registry, project, features, full_feature_names) + + ( + feature_refs, + requested_on_demand_feature_views, + entity_name_to_join_key_map, + entity_type_map, + join_keys_set, + grouped_refs, + requested_result_row_names, + needed_request_data, + entityless_case, + ) = ctx + + odfv_join_keys: set = set() + for on_demand_feature_view in requested_on_demand_feature_views: + entities_for_odfv = getattr(on_demand_feature_view, "entities", []) + if len(entities_for_odfv) > 0 and isinstance(entities_for_odfv[0], str): + entities_for_odfv = [ + registry.get_entity(entity_name, project, allow_cache=True) + for entity_name in entities_for_odfv + ] + odfv_join_keys.update(entities_for_odfv) + + result = ( + feature_refs, + requested_on_demand_feature_views, + entity_name_to_join_key_map, + entity_type_map, + join_keys_set | odfv_join_keys, + grouped_refs, + frozenset(requested_result_row_names), + needed_request_data, + entityless_case, + ) + + registry_ts_after = getattr(registry, "cached_registry_proto_created", None) + if registry_ts_after is not None: + with _feature_resolution_cache_lock: + if registry_ts_after != _feature_resolution_registry_ts: + _feature_resolution_cache.clear() + _feature_resolution_registry_ts = registry_ts_after + _feature_resolution_cache[cache_key] = result + + return result + + def _prepare_entities_to_read_from_online_store( registry, project, @@ -1340,10 +1491,13 @@ def _prepare_entities_to_read_from_online_store( entity_type_map, join_keys_set, grouped_refs, - requested_result_row_names, + requested_result_row_names_frozen, needed_request_data, entityless_case, - ) = _get_online_request_context(registry, project, features, full_feature_names) + ) = _get_cached_request_context(registry, project, features, full_feature_names) + + # Mutable copy — downstream code adds join keys to this set. + requested_result_row_names = set(requested_result_row_names_frozen) # Extract Sequence from RepeatedValue Protobuf. entity_value_lists: Dict[str, Union[List[Any], List[ValueProto]]] = { @@ -1365,23 +1519,6 @@ def _prepare_entities_to_read_from_online_store( num_rows = _validate_entity_values(entity_proto_values) - odfv_entities: List[Entity] = [] - request_source_keys: List[str] = [] - for on_demand_feature_view in requested_on_demand_feature_views: - entities_for_odfv = getattr(on_demand_feature_view, "entities", []) - if len(entities_for_odfv) > 0 and isinstance(entities_for_odfv[0], str): - entities_for_odfv = [ - registry.get_entity(entity_name, project, allow_cache=True) - for entity_name in entities_for_odfv - ] - odfv_entities.extend(entities_for_odfv) - for source in on_demand_feature_view.source_request_sources: - source_schema = on_demand_feature_view.source_request_sources[source].schema - for column in source_schema: - request_source_keys.append(column.name) - - join_keys_set.update(set(odfv_entities)) - join_key_values: Dict[str, List[ValueProto]] = {} request_data_features: Dict[str, List[ValueProto]] = {} # Entity rows may be either entities or request data. @@ -1442,36 +1579,108 @@ def _get_entity_key_protos( return entity_key_protos -def _convert_rows_to_protobuf( +def _populate_response_from_feature_data( requested_features: List[str], read_rows: List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]], -) -> List[Tuple[List[Timestamp], List["FieldStatus.ValueType"], List[ValueProto]]]: - n_rows = len(read_rows) + indexes: Iterable[List[int]], + online_features_response: GetOnlineFeaturesResponse, + full_feature_names: bool, + table: "FeatureView", + output_len: int, + include_feature_view_version_metadata: bool = False, +): + """Populate the GetOnlineFeaturesResponse from raw online_read rows. + + Converts raw rows from the OnlineStore into protobuf FeatureVectors and + appends them to the response. This method assumes that ``online_read`` + returns data for each unique entity in the same order as ``indexes``. + + Args: + requested_features: The names of the features to extract from + each row. Determines the order of FeatureVectors in the response. + read_rows: Raw output from ``OnlineStore.online_read`` — a list of + ``(event_timestamp, feature_dict)`` tuples, one per unique entity. + ``feature_dict`` may be ``None`` when the entity is not found. + indexes: A tuple of lists that maps each unique entity (by position + in ``read_rows``) to one or more output positions in the response. + Used to fan-out deduplicated reads back to the original request rows. + online_features_response: The protobuf response object to populate. + full_feature_names: If True, feature names are prefixed with the + feature view name (e.g. ``"driver_fv__trips_today"``). + table: The FeatureView that ``read_rows`` was retrieved from. + output_len: Total number of result rows in the response. + include_feature_view_version_metadata: If True, version metadata + for the feature view is added to the response. + """ + n_features = len(requested_features) + + table_name = table.projection.name_to_use() + clean_table_name = table.projection.name_alias or table.projection.name + feature_refs = [ + f"{table_name}__{fn}" if full_feature_names else fn for fn in requested_features + ] + online_features_response.metadata.feature_names.val.extend(feature_refs) + + if include_feature_view_version_metadata: + existing_names = [ + fvm.name for fvm in online_features_response.metadata.feature_view_metadata + ] + if clean_table_name not in existing_names: + fv_metadata = online_features_response.metadata.feature_view_metadata.add() + fv_metadata.name = clean_table_name + fv_metadata.version = getattr(table, "current_version_number", 0) or 0 null_value = ValueProto() - null_status = FieldStatus.NOT_FOUND - present_status = FieldStatus.PRESENT + null_ts = Timestamp() + PRESENT = FieldStatus.PRESENT + NOT_FOUND = FieldStatus.NOT_FOUND - # Pre-compute timestamps once per entity (not per feature) - # This reduces O(features * entities) to O(entities) for timestamp conversion - row_timestamps = [] + row_ts_protos = [] for row_ts, _ in read_rows: - ts_proto = Timestamp() + ts = Timestamp() if row_ts is not None: - ts_proto.FromDatetime(row_ts) - row_timestamps.append(ts_proto) - - requested_features_vectors = [] - for feature_name in requested_features: - ts_vector = list(row_timestamps) # Shallow copy of pre-computed timestamps - status_vector = [null_status] * n_rows - value_vector = [null_value] * n_rows - for idx, (_, feature_data) in enumerate(read_rows): - if (feature_data is not None) and (feature_name in feature_data): - status_vector[idx] = present_status - value_vector[idx] = feature_data[feature_name] - requested_features_vectors.append((ts_vector, status_vector, value_vector)) - return requested_features_vectors + ts.FromDatetime(row_ts) + row_ts_protos.append(ts) + + ts_template = [null_ts] * output_len + indexes_tuple = tuple(indexes) + for row_idx, destinations in enumerate(indexes_tuple): + ts = row_ts_protos[row_idx] + for out_idx in destinations: + ts_template[out_idx] = ts + + feat_values = [[null_value] * output_len for _ in range(n_features)] + feat_statuses = [[NOT_FOUND] * output_len for _ in range(n_features)] + + feat_idx_map = {name: i for i, name in enumerate(requested_features)} + for row_idx, destinations in enumerate(indexes_tuple): + _, feature_data = read_rows[row_idx] + if feature_data is None: + continue + for feat_name, feat_val in feature_data.items(): + f_idx = feat_idx_map.get(feat_name) + if f_idx is not None: + for out_idx in destinations: + feat_values[f_idx][out_idx] = feat_val + feat_statuses[f_idx][out_idx] = PRESENT + + try: + from feast.metrics import track_feature_statuses + + _present = sum(s == PRESENT for row in feat_statuses for s in row) + _not_found = (n_features * output_len) - _present + track_feature_statuses(table.name, _present, _not_found) + except Exception: + pass + + for f_idx in range(n_features): + online_features_response.results.append( + GetOnlineFeaturesResponse.FeatureVector( + values=feat_values[f_idx], + statuses=feat_statuses[f_idx], + event_timestamps=list(ts_template), + ) + ) def has_all_tags( diff --git a/sdk/python/feast/value_type.py b/sdk/python/feast/value_type.py index d05691199b4..0ea16002f80 100644 --- a/sdk/python/feast/value_type.py +++ b/sdk/python/feast/value_type.py @@ -71,6 +71,19 @@ class ValueType(enum.Enum): JSON_LIST = 33 STRUCT = 34 STRUCT_LIST = 35 + UUID = 36 + TIME_UUID = 37 + UUID_LIST = 38 + TIME_UUID_LIST = 39 + UUID_SET = 40 + TIME_UUID_SET = 41 + VALUE_LIST = 42 + VALUE_SET = 43 + DECIMAL = 44 + DECIMAL_LIST = 45 + DECIMAL_SET = 46 + SCALAR_MAP = 47 + ZONED_TIMESTAMP = 48 ListType = Union[ diff --git a/sdk/python/feast/version_utils.py b/sdk/python/feast/version_utils.py new file mode 100644 index 00000000000..5811e89e936 --- /dev/null +++ b/sdk/python/feast/version_utils.py @@ -0,0 +1,51 @@ +import re +import uuid +from typing import Tuple + +LATEST_VERSION = "latest" +_VERSION_PATTERN = re.compile(r"^v(?:ersion)?(\d+)$", re.IGNORECASE) + + +def parse_version(version: str) -> Tuple[bool, int]: + """Parse a version string into (is_latest, version_number). + + Accepts "latest", "vN", or "versionN" (case-insensitive). + Returns (True, 0) for "latest", (False, N) for pinned versions. + + Raises: + ValueError: If the version string is invalid. + """ + if not version or version.lower() == LATEST_VERSION: + return True, 0 + + match = _VERSION_PATTERN.match(version) + if not match: + raise ValueError( + f"Invalid version string '{version}'. " + f"Expected 'latest', 'vN', or 'versionN' (e.g. 'v2', 'version3')." + ) + return False, int(match.group(1)) + + +def normalize_version_string(version: str) -> str: + """Normalize a version string for comparison. + + Empty string and "latest" both normalize to "latest". + "v2" and "version2" both normalize to "v2". + """ + if not version or version.lower() == LATEST_VERSION: + return LATEST_VERSION + is_latest, num = parse_version(version) + if is_latest: + return LATEST_VERSION + return version_tag(num) + + +def version_tag(n: int) -> str: + """Convert an integer version number to the canonical short form 'vN'.""" + return f"v{n}" + + +def generate_version_id() -> str: + """Generate a UUID for a version record.""" + return str(uuid.uuid4()) diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index a5976ffcc9e..a81987bd0be 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -1,5 +1,5 @@ [tool.ruff] -exclude = [".git","__pycache__","docs/conf.py","dist","feast/protos","feast/embedded_go/lib","feast/infra/utils/snowflake/snowpark/snowflake_udfs.py"] +exclude = [".git","__pycache__","docs/conf.py","dist","feast/protos","feast/embedded_go/lib","feast/infra/utils/snowflake/snowpark/snowflake_udfs.py","**/node_modules","**/*_pb2.py","**/*_pb2.pyi","**/*_pb2_grpc.py"] [tool.ruff.lint] select = ["E","F","W","I"] diff --git a/sdk/python/pytest.ini b/sdk/python/pytest.ini index 1ad76b978e4..d5ad19660b7 100644 --- a/sdk/python/pytest.ini +++ b/sdk/python/pytest.ini @@ -21,6 +21,7 @@ markers = cloud: Tests requiring cloud credentials local_only: Tests that run entirely locally xdist_group: Group tests to run in the same xdist worker + mongodb: Tests requiring MongoDB timeout = 300 timeout_method = thread diff --git a/sdk/python/requirements/py3.10-ci-requirements.txt b/sdk/python/requirements/py3.10-ci-requirements.txt index b130f1150ee..3ed659370d2 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -4,138 +4,139 @@ accelerate==1.13.0 \ --hash=sha256:cf1a3efb96c18f7b152eb0fa7490f3710b19c3f395699358f08decca2b8b62e0 \ --hash=sha256:d631b4e0f5b3de4aff2d7e9e6857d164810dfc3237d54d017f075122d057b236 # via docling-ibm-models -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a # via # aiobotocore # fsspec + # kubernetes + # mlflow aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -148,6 +149,10 @@ alabaster==0.7.16 \ --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 # via sphinx +alembic==1.18.4 \ + --hash=sha256:a5ed4adcf6d8a4cb575f3d759f071b03cd6e5c7618eb796cb52497be25bfe19a \ + --hash=sha256:cb6e1fd84b6174ab8dbb2329f86d631ba9559dd78df550b57804d607672cedbc + # via mlflow altair==4.2.2 \ --hash=sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5 \ --hash=sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87 @@ -160,9 +165,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # elasticsearch # httpx @@ -224,9 +229,9 @@ asttokens==3.0.1 \ --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 # via stack-data -async-lru==2.2.0 \ - --hash=sha256:80abae2a237dbc6c60861d621619af39f0d920aea306de34cb992c879e01370c \ - --hash=sha256:e2c1cf731eba202b59c5feedaef14ffd9d02ad0037fcda64938699f2c380eafe +async-lru==2.3.0 \ + --hash=sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6 \ + --hash=sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315 # via jupyterlab async-property==0.2.2 \ --hash=sha256:17d9bd6ca67e27915a75d92549df64b5c7174e9dc806b30a3934dc4ff0506380 \ @@ -242,28 +247,28 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonlines # jsonschema # openlineage-python # referencing -azure-core==1.38.2 \ - --hash=sha256:074806c75cf239ea284a33a66827695ef7aeddac0b4e19dda266a93e4665ead9 \ - --hash=sha256:67562857cb979217e48dc60980243b61ea115b77326fa93d83b729e7ff0482e7 +azure-core==1.41.0 \ + --hash=sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d \ + --hash=sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a # via # azure-identity # azure-storage-blob -azure-identity==1.25.2 \ - --hash=sha256:030dbaa720266c796221c6cdbd1999b408c079032c919fef725fcc348a540fe9 \ - --hash=sha256:1b40060553d01a72ba0d708b9a46d0f61f56312e215d8896d836653ffdc6753d +azure-identity==1.25.3 \ + --hash=sha256:ab23c0d63015f50b630ef6c6cf395e7262f439ce06e5d07a64e874c724f8d9e6 \ + --hash=sha256:f4d0b956a8146f30333e071374171f3cfa7bdb8073adb8c3814b65567aa7447c # via feast (pyproject.toml) -azure-storage-blob==12.28.0 \ - --hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \ - --hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41 +azure-storage-blob==12.29.0 \ + --hash=sha256:2824ddd7ebc9056034ebc76b17971a38e9aa5835abb0d565b9700493f2a6c657 \ + --hash=sha256:ccf8a1bcd5e49df83ab85aab793b579e5ba2eeea2ad8900b2f62ca3a37dc391f # via feast (pyproject.toml) babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ @@ -277,73 +282,79 @@ beautifulsoup4==4.14.3 \ # via # docling # nbconvert -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -bleach[css]==6.3.0 \ - --hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \ - --hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6 +bleach[css]==6.4.0 \ + --hash=sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452 \ + --hash=sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081 # via nbconvert -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +blinker==1.9.0 \ + --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ + --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc + # via flask +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # moto # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # moto # s3transfer # snowflake-connector-python -build==1.4.0 \ - --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ - --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 +build==1.5.0 \ + --hash=sha256:13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f \ + --hash=sha256:302c22c3ba2a0fd5f3911918651341ebb3896176cbdec15bd421f80b1afc7647 # via # feast (pyproject.toml) # pip-tools # singlestoredb -cassandra-driver==3.29.3 \ - --hash=sha256:064bf45d3ca87239e11168c0110676fc64f7fdbddb4bcba9be787b8ad5f6d734 \ - --hash=sha256:0785f6e0986089e922378ae3b64b5f696440aeb595fb84c2cf3ccef220c6ae91 \ - --hash=sha256:158f7e5cb894a76a592aa0ca659a8e7c2a57ef603e04c07bbbc289a70e9ac893 \ - --hash=sha256:1c241ba08473baf31a333feb59793190d01625541c2368d3bbb0f43a586f1d6a \ - --hash=sha256:26013d768b2ea4728c09144b08c0eb86ad692e85cb15f4e52e3107abca83683c \ - --hash=sha256:27adf8869937461ad08c5fefb47857532e467b408db496db4dbf8b132a4bd623 \ - --hash=sha256:281f67af1b8df88741eef551afbb49f78e4f366a7ab23e7060a1f0d6ba655752 \ - --hash=sha256:29fc241475801872dc27c3dd1a3976373536223dd4fd1c01868ff86bdbbfd48b \ - --hash=sha256:2b72312a8b62a905da6133effbba9b0731c8e30af96e10ca77fc5c34532c6827 \ - --hash=sha256:2cb72808dfc46c40a6ee352ace181ce3170adde1cfd1447da91709a8cf482e20 \ - --hash=sha256:38216e13d6f2e0d4513a5b8806e70ce4a8f28a82962793a67371582fc2c7141b \ - --hash=sha256:3f654b01d8d49f68deedfaff1edcff314e3103d29130b2a034df6c490c522351 \ - --hash=sha256:51d6a5390e2454b599500049f0a5c72aa701db155c1e542f9a1157c1c45814b1 \ - --hash=sha256:54afde4aaa5b55fbc2c075e1c55fb14a5739459428f3bb81f849ad020f7d5bcf \ - --hash=sha256:572bd5a01089ab92da12f4f52b32b878547bbc544a798d8cfd042e7fc2601c75 \ - --hash=sha256:5a0113020d86e8f61c7a2ae3d508720cd036df7462a55926b85dd97ada27e143 \ - --hash=sha256:5f9858b5ccdf75dd89c20d74474b59dd3a2e2f86c7251b310011c46acdef3874 \ - --hash=sha256:638047c1f70fb14c9d8f743931d4f4f42aff6793b47afded3097c002ef8c1165 \ - --hash=sha256:63adca0f9219be3fe8789f4aa7b77c5f6a7bf65d6442959db52c653140ca4185 \ - --hash=sha256:7552fb7189acd06161f8feac7045a387dc9e03b3b9f7dcb5675178906cee792e \ - --hash=sha256:7a2f371af54cd1d153ef373a733889ebfbcc9c30e00429fc12a2569bad9239e1 \ - --hash=sha256:84b24f69a7bbe76302330d47422a7fcc1998a6a96ffd414a795d7d95992b49cb \ - --hash=sha256:891a1b6a111a591ad9f1c9e088846848dc9e6be030a6086c8c3aa5d2d837f266 \ - --hash=sha256:96ad742f5cbfb771df512959ab5de36e248ce9aa2c487fd81c37d5c0a627c094 \ - --hash=sha256:9abedc832e9a6636741299aae46c032d8c1248b507d8cebbaa2f48ec202904bc \ - --hash=sha256:9b7032b44769c454e96aa11483bfd167a87ea341268f1075b0ff84f780c910a9 \ - --hash=sha256:c935431682557ffcd3efc1c7bcb01b0f6769a1c90751a7154d5e3c905a6a2042 \ - --hash=sha256:e1d09691d757f5b1900a98cc3b6cc7d8506683a2188c01eca86545f91edbbaf5 \ - --hash=sha256:facd488c2b9be8bffcad5903566581e96d2863d2ec4bcad7f114d1b2b2f39ad0 \ - --hash=sha256:fcf45725ae1751cb934b9b827a7d9cd899bbd09eb1ad28e2160b4584de35ba77 \ - --hash=sha256:ff6b82ee4533f6fd4474d833e693b44b984f58337173ee98ed76bce08721a636 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via + # mlflow-skinny + # mlflow-tracing + # pymilvus +cassandra-driver==3.30.0 \ + --hash=sha256:0c28a8e84917acebecbaed39844047c2f135739c3627dd7b9f8541af33e11df3 \ + --hash=sha256:0f4225082a11d9529416c223553ab38a29c4e65da6646b40159c554480dc002c \ + --hash=sha256:136b46437b9902673264e101cdaab309d3e40607bff34430bda86b785badc6e4 \ + --hash=sha256:137498e2a9b6f578d1902e1af8a988e50b8fe134c76a176f1b8a774e906bc66c \ + --hash=sha256:17fb53587c9fc6a27b5c4a89b4f3d9169be43fc572d6f3f67494aa74708be936 \ + --hash=sha256:1d64cbdce764c33e284d339b9a749736d68971edf8b537888f2d13c4b0d1313f \ + --hash=sha256:212af4d8ff934c30538f4bdf7da61f14dc9a30349f6cac2161c8125e56fad928 \ + --hash=sha256:2637644eac9274e46b0c2a7f729158bdf8582b6842dc48e18297211dd3ee1fec \ + --hash=sha256:289e86c81be2543cb9055600c0819850db921e6e138a84e5c88ec160662c7207 \ + --hash=sha256:2a0679ebcfdcecb3763c690b5bc6a517e0c0803f7bc88e0a6c793e5e421b558a \ + --hash=sha256:385134eba72f048707cd800de0a61cf3c23246113edffe9bc6bc2eb86282d26b \ + --hash=sha256:5c6cbb396ad6fe456efc799d3b8b6bda360ffc06552c5be2ce1a88ac381a305c \ + --hash=sha256:61d7eeb17d8f76d5b4a9b1239145250f2a9f7bf949c30e2cc36196b5a0523ce1 \ + --hash=sha256:6a5c8982f2b9eb4e789fc12cdd930b1e1511b6d046dde31d0703f855745556a3 \ + --hash=sha256:6d449f49ce866ac20a1c3d80b1f9245ecdfd1e67b843dccd3d6eccdfe519c02e \ + --hash=sha256:7e4cfd6ec3023576ed0ffa34882d9778e4bacfd918048ae9139ccdd00628ed85 \ + --hash=sha256:83a9148d408a3dbb48ea1802d643d60fa53cd69dc7b9a244511ecf5b917e4f53 \ + --hash=sha256:8c4acd28791854c23ca68be50a7a750c9413ba80fec0ca5c27c2be05f6f3fe0a \ + --hash=sha256:8d5e3575ec01d8c043b56ff25de6f61ff4c9ed5cb3ea4c3d9df98def71ba710c \ + --hash=sha256:923a6e1c3fa5f98f846a028b1a7207ec9e7d8cfa54ea47a507d41122efa2f54f \ + --hash=sha256:c1b4aa6c7706dec839134adb6a2094d90c5f6f35efa08028ed6aae6e67c8643e \ + --hash=sha256:c64e20bf46b49f8ef64569208d4a395b0928c27d5960559922a2d13471924d0d \ + --hash=sha256:d2f9e00127f70dff42d4ef932df8a6b81170c2861d4e75c8b13f4b4816b4450c \ + --hash=sha256:d73c0429813045ba86b92fc033fbcfd495aa10e9d4a40fe30b6e9dfe8b5d3ab4 \ + --hash=sha256:e12dfcd3f0074c16f4bfe650242edb406b935864373ae86160e09e3f5e437e84 \ + --hash=sha256:ff2e9fbdc1be54c1d041ea3f7d09812442f334be14bb5ad7aede175544765d25 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # clickhouse-connect # docling @@ -447,200 +458,215 @@ cfgv==3.5.0 \ --hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \ --hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132 # via pre-commit -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask + # flask # geomet # great-expectations + # mlflow-skinny # pip-tools # ray # typer # uvicorn -clickhouse-connect==0.13.0 \ - --hash=sha256:0f7223ccfc24394e24c6376c32f63325e3eb56df7e0a7e3e7b23040d7a73e180 \ - --hash=sha256:170e39ef6d76a2da322aa8f06ee4b0f2a91954a9a894b5dbb24e3e0ebaf994ff \ - --hash=sha256:17a6c60fddcc7894245692729fac88769036ae2e9243c45882dcd0234227a1a9 \ - --hash=sha256:18303de2a0058bf594dc7991d5bba95d4258249c80d7c04770cfd410a5238924 \ - --hash=sha256:1b2b1258d8fa4e840be929142f0cd60e534d4763c9132d59f1be7bc9529042d3 \ - --hash=sha256:2b8bbf54bd5cb69791201a4cf4fd4c4a677d7e4cc2a6f60c58af6092f715d0cc \ - --hash=sha256:33fd35aa22ef3a5b44a46ef2fc7510723db2bc5b1c466d147da34c2da974fd9c \ - --hash=sha256:4d4266f5bf7f26a00d335de4eaabb74cf7dbf71056ee256673b040ac68378805 \ - --hash=sha256:4fb2394c9300265f2cb9739ae8acc71630b2aa6e53d829706fe3da9a05c26599 \ - --hash=sha256:52ced166cff735db529780d388c3192d8ec4fb09d5e5acf46ed6dc43e9aa5d80 \ - --hash=sha256:56bb65b08bb40e0c356559666a47c164e55266181601367f8165524052019079 \ - --hash=sha256:56edc95c954e14ec4d5360ee93382566a48c7f00196c4b8d75d5f4874f93c730 \ - --hash=sha256:5a1a654db64fca213920c2dc07524a99b8ecab64f1c0dca321c9f389694dc5af \ - --hash=sha256:5a5e58fb3229f06fb0c60a9e893cda1d181e21ff2e31fb8c51641dd035d12c34 \ - --hash=sha256:5c4ea58b450a0815a85550ce6e10b7ed9a6e0b902bf4d97286c9cf73f9692e4c \ - --hash=sha256:7121fa8c80554dc3facc65c930e04e43033e7fa5d7fc3359e2c0d85c39854d58 \ - --hash=sha256:7322aec94c8e337a6cb120c806fa13b8fd9b1286c89ed755b2cfa9937953f2ed \ - --hash=sha256:746254b0c6c97fc912f0b4b11909d4576b57db614fbc408cfcc45804474fb7de \ - --hash=sha256:804c4be52695ddd8a87b870bbab38dc071f5bf33bbe29566d4378321dbc67d04 \ - --hash=sha256:8569a33c5c884da1c8442172603f1376871876e726d0b679901834e767918ad4 \ - --hash=sha256:859d58c8f0ddc632885ee206bf96e27f02cec6e985995d77f18a458929cd808a \ - --hash=sha256:8832c907756b8564f3b9cdc1a41c22cddcb69801613eefd15b2a9eea2e40ed53 \ - --hash=sha256:8d4283d6e8a41ebbd304574f2da2773c74e12b6e9fd32ed2ea133494e4f6ca7e \ - --hash=sha256:913a53f6b0d948b60fbafe5cb5ae2c10fc2347cf0e17917c842223e571bdbaa5 \ - --hash=sha256:974b0800656b372aa001c9e0fd958a4b43086e4650bbc571aaed3993607bdc69 \ - --hash=sha256:97d00f52f7611ff2e7a0b58d8e3cb0ea470dcbfc56ac6469163c36e4caf7d14c \ - --hash=sha256:993eb2887b01a9714da4d68c1b8c97d91e267ba5510374955c0dc5ae34554923 \ - --hash=sha256:99f198ed4cb99924cc80b69270a4fea1f25cde8cf2f6fb26fde4f9ac9e99cc97 \ - --hash=sha256:9ff33742d7380a1b072e19f84ae9dd7863ae00483731f3a5ff3b18cdcc9a60e9 \ - --hash=sha256:a373713c1f2c3964474cdfc69cff29090ead1d142c41c6fa8cda3ab34dce2916 \ - --hash=sha256:a4712c2ce29f70c1f194f3f92c98169d600390f288295271c6eb0feda8b24548 \ - --hash=sha256:a668810f0b670d7c284c119100af019a3e405cd3d61e08a4a2dff3ecea802c4d \ - --hash=sha256:ae8b308a34b4c6b1e0d77c977a46fbd2841d926bedea37f57618c4dd6cef636d \ - --hash=sha256:af5a6e924111b2fa4e6c17d7425f842f54fb2a014ad7a793a91462dccbdbca4e \ - --hash=sha256:af703d0477c081e2d32297abf8af2fe9aa61a9aa818b1f3b7a473de9c58d822e \ - --hash=sha256:b11ae56992f7d972692ae4d38e79de2a52333a5e38a55a144fb47f644b921cc5 \ - --hash=sha256:b1b0c92c91f2f3d0f2422d1c938af221abad2d6fda50bb4c816ebac373d5ddf1 \ - --hash=sha256:b5a2eb5851dfd8469d4b6253f5ec4666fb9fba018b47ac35d15fa2bca62b4979 \ - --hash=sha256:b60b54ffbbd65a630bc551fa979bfa47f0ca3dceeccd6ebdc043c66b30eed714 \ - --hash=sha256:b7f4cdc2b34f7b88e4c96c3e13a2574732c3bd6c21a6b2b2ab2b1fc3914301f1 \ - --hash=sha256:b9ae5a28c511e7680224f868acd461f7cd3d8793ea8545f22bafb71d4235b663 \ - --hash=sha256:bb8e8d508ff0331e34aef747d0cf5748ca0736e982c785b4aa08fca984459db5 \ - --hash=sha256:cc9781d0fdd31108d1c707cd3c3b7e50f97f819c6dc10d71b86c2d3bb6b83a49 \ - --hash=sha256:ccbb7d8e43904074eb66ac99dd58750b4d68501d2e794169ca8e3b27ba6c35db \ - --hash=sha256:d30ce9f85033325ab042e9f515dc2d9375fd972f71169d46181bc41ede77305b \ - --hash=sha256:d7756cac9afa4dde22549f271b3bbf6739f4f4a533e45f1ffc3faaaf87086371 \ - --hash=sha256:d7a574b53d41769e352a149fe52904859ffccd423cf11c69dc21938ff94235e7 \ - --hash=sha256:d96fb3c6912cd570b37a4de5e93cc7528afe56f10e5d8f33ed8c7a26fe24e7d1 \ - --hash=sha256:dbc8871ead7d06db00980bd6d59d899add80b0184e52b33a14ed23ac4a8109ea \ - --hash=sha256:dcc6c5106b436cb63af4b47b22dd75f38497e61857b3fefb2226562040884a5b \ - --hash=sha256:e04d4b11b54e33d12218add69a6eac2d4fa3262b522489663ab948c08eb27f1f \ - --hash=sha256:e2267b41e69203e334761f28f1102ad47d3ff218e565b06b215b61f1f62e4171 \ - --hash=sha256:e449006b1606e22822695c85d4fc1faf3c1d0a5a3622d4b8fc28bfa014dbb295 \ - --hash=sha256:e72aded5dbb2e2fa8d6a2d70ef061556ff94baec3eca8b800c45e103507aa90f \ - --hash=sha256:ed741ab68b6226669f3b09fc663710764b985f83c0c9f753a8ae98276893284b \ - --hash=sha256:efa3d8d968e66ef0fe79fc880b824368787329e63b61feab86194e113a7795ff \ - --hash=sha256:f0c9efea902187f1de351bc32995d08d1f1f27350798508f8a6c238ecac4ccb0 \ - --hash=sha256:f1ee372499dfa784653cba035df6a6b12ed67c74c8c42ace13c3af99db4491f0 \ - --hash=sha256:fa9ef035faaa60f06470b15f6c1912b4b402b03dc9d4de07d445b9e817c933f0 +clickhouse-connect==1.1.1 \ + --hash=sha256:0b602967810358408ebd55693fd582f3a20e08800f721fb72ae320f0f74686ff \ + --hash=sha256:0bb2c8f82bb2bd5f645c0114d5d766a95dc1e0dec33c07deafa5a68dbb75f898 \ + --hash=sha256:0e9e294601aac4de51ac7cd2423176fe5111da41b5d120047606eb855795853c \ + --hash=sha256:0ec2f574530c65412a490ac6a29445509ca6346dbb15d39a825e27c73d680f3a \ + --hash=sha256:10055ae880742ffc61244eb129bbbafa6fe97731aa959d717b16513b5094255a \ + --hash=sha256:10c0354b858f500f4f26195dc37cd6047eb4d324b0b08ca6873e2241ea4a2ea8 \ + --hash=sha256:11ca173d36405d446f97dfea0a3e1531389d90d23c686ec18ebcbc0eed17200e \ + --hash=sha256:1284cb2a73b6af208aac06ad04d9121a8aa33f4b971b9d5a65264d2137b5cf0f \ + --hash=sha256:1781f330cd0678b203dc35d5df85c3b212577412c0dcf664432edbfc71a20489 \ + --hash=sha256:1e2b000c55e698220cba80e660349c60d7acb3b82172c320a51519d191e24826 \ + --hash=sha256:22ed08e9a361e1d21762c68275610ee0e023f281fe9a1653763b62fc5585a6f0 \ + --hash=sha256:233cc6eae3dbec122ed7ff694f657aa9676b36c2acbcef64e97166e4f75f5040 \ + --hash=sha256:27b665a01711e9a5b08e4412d501baf76ce4ccbeb937ec67e73040094492adbc \ + --hash=sha256:2913a4c96c3aede2b39489731eb8c39e37792755df9b56548b162ab1e09df4f3 \ + --hash=sha256:2c9a1bdb1d9705a270ec8036cd89113db04f4437a4d3b5db0774312ec4d06e30 \ + --hash=sha256:3cdae5ce54cc7d5fdaced13857612b25ae58f0830987a4b17ebcf376d71df3b2 \ + --hash=sha256:43e1fb7d588a799a3e55a4982946d59484edf1e960abc9e7ac330a3330ee4fc5 \ + --hash=sha256:49cb0d82e3f68d7304275bf350419095c080ddd49f99704dd44a956273fa7c09 \ + --hash=sha256:4f0c6c52245322c04bdccc71565ac8db9731e1787c90665df9167928101f0b89 \ + --hash=sha256:4ff227719006516877b5152e89cba514ceee9807e6b030a1ddba8d9355b87412 \ + --hash=sha256:6062c400d67dd4ab03fc3f9473134fc0a240593c242998d032d32cb04a65f083 \ + --hash=sha256:646408372c2a4b0e4068145897a35100cefc6974a409c68b20ba22403665fe5a \ + --hash=sha256:68d6e245db80ea42c59c32dbed655f28e82337d61405dde6aa5e009c507a6eee \ + --hash=sha256:70b9dee3c4629e06f2b5788d02b6cded0a32d2509966bc293cf1c39abc395a29 \ + --hash=sha256:763f7fabc921ee9fb4c07d180447a6324980bfeb981c3f53065d04bda5f133b7 \ + --hash=sha256:770da683bf65d3536c46d564e5a9311d6cd40d191a0357a762ac702813774965 \ + --hash=sha256:784a1c9513a33f6f8df0c260e43ea5cdc5fde0a2c91bca7e69ce26bc4990abcd \ + --hash=sha256:7fb296b2c51e5ad8d7f677a08a093b3b122cd4411619678a968567f3b34bf075 \ + --hash=sha256:8857676711197c981afc317a38ad1b92aedcf81b7052e67098f40adcf4b5d4ba \ + --hash=sha256:8b0590065a4c6551d1145229adf3405befc053843f6b1ffeb3802ae7221d53dc \ + --hash=sha256:8f2f9029f6589d2d349912a94a17d9997c550a7f19dd5b747f6b452764dc0e54 \ + --hash=sha256:92d885943b1b0a1489501408d6af91ec2d96189dbc475f3552f22cd43c9c6270 \ + --hash=sha256:9de3999bad13146823e9c6811dbe9a66653bf5c71980472f8fe5165d186451ee \ + --hash=sha256:a4639a1c6291358a0dd40ba0a6a6059eb5fcc9acd6f4cd61eb52b3cb5165d37e \ + --hash=sha256:a4740e012dc4ed2fab769dba4b13be92142e2df2bfb0de547b0b73f13296bcb8 \ + --hash=sha256:a6c0a8f1c4e4954161051b26bee8d24f1e53254125d2bf6e18c9360cd41fe059 \ + --hash=sha256:a706631a540ac21aac4434a446d50263c0872c9507bc6a0ccfb51467c0ff74a4 \ + --hash=sha256:ad6b32a1bb391f15345c6af4ecee152e04362c6331cd93472f2fa5e64f8a9aaa \ + --hash=sha256:b1e83e71d5b0df09cb807657ab0457eb1fd116a331039d3c5d3051387092ff6a \ + --hash=sha256:c336452cd5aeada902ac41d57296498766f95a175cb1dcf13d48479b5b31ac6b \ + --hash=sha256:c54bdd8870a644a9baa7cd68fdfc5100f5b19aa246657be863788a6a7bf4052e \ + --hash=sha256:ca28e361a51afe2e7e2fcff47c1423fd61271d26af7d19e37f6ff0ab67bf086f \ + --hash=sha256:cd501e3ccee60d4cccf5cde4b4c92632b62763563b08aa07dbfd3e2583c12005 \ + --hash=sha256:d1df245b5c21fa7bd70193164cc97f3937ccee3087dbc7906daf2e97b226b2a8 \ + --hash=sha256:d3b3806986340192ed2b197241be193649717cc58f7ef9bdf86d119758289a0f \ + --hash=sha256:d4a5e4b36219d678d495120007d0ba8b7d1bf4c5105292b35fa4473038fc2892 \ + --hash=sha256:d749389301b201ae7329c8fc96599fc116de8aadc16a5a4416e399483c569ea9 \ + --hash=sha256:d84c8ed4cc26976d2cc6725e36b85d4e24f1c43c11d82483b3060116ac0bcfd4 \ + --hash=sha256:dcdfee2f707225bfbd80ba2da5c995a38393aa02920adf770264c6f5b041e9ed \ + --hash=sha256:e762f70ebf57cb43a6257daa6196f5beb574d69915dd06c29735d5811dfd8dce \ + --hash=sha256:ee7d8308c8a688c6851b19d2bc743a02ed5d6f8679203a13872a80cf4066dd57 \ + --hash=sha256:f205be896551d7ea0a0140a86e36d261e249f99541d68a3dfdd47dd8c7c2bbbb \ + --hash=sha256:f552668320b8c533b6f2b93d03dd4840cfe0e8f5f01c76ea0d2989e4127fa60e \ + --hash=sha256:f75e0d62bdb53ba72fa2aa962950c5c107627158c9fe8900ca14da557295bdb2 # via feast (pyproject.toml) cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ --hash=sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a - # via dask + # via + # dask + # mlflow-skinny colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 @@ -653,6 +679,65 @@ comm==0.2.3 \ # via # ipykernel # ipywidgets +contourpy==1.3.2 \ + --hash=sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f \ + --hash=sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92 \ + --hash=sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16 \ + --hash=sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f \ + --hash=sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f \ + --hash=sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7 \ + --hash=sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e \ + --hash=sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08 \ + --hash=sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841 \ + --hash=sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5 \ + --hash=sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2 \ + --hash=sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415 \ + --hash=sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878 \ + --hash=sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0 \ + --hash=sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab \ + --hash=sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445 \ + --hash=sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43 \ + --hash=sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c \ + --hash=sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823 \ + --hash=sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69 \ + --hash=sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15 \ + --hash=sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef \ + --hash=sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5 \ + --hash=sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73 \ + --hash=sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9 \ + --hash=sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912 \ + --hash=sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5 \ + --hash=sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85 \ + --hash=sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d \ + --hash=sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631 \ + --hash=sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2 \ + --hash=sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54 \ + --hash=sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773 \ + --hash=sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934 \ + --hash=sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a \ + --hash=sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441 \ + --hash=sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422 \ + --hash=sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532 \ + --hash=sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739 \ + --hash=sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b \ + --hash=sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f \ + --hash=sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1 \ + --hash=sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87 \ + --hash=sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52 \ + --hash=sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1 \ + --hash=sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd \ + --hash=sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989 \ + --hash=sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb \ + --hash=sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f \ + --hash=sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad \ + --hash=sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9 \ + --hash=sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512 \ + --hash=sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd \ + --hash=sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83 \ + --hash=sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe \ + --hash=sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0 \ + --hash=sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c + # via matplotlib couchbase==4.3.2 \ --hash=sha256:032a180afd6621358b2c73543b9c5db9939b442fc3ad6d54417c36c8a8f65838 \ --hash=sha256:11ce688ed46edf8387bf51866618c7b4e06399e7fb34a6df002764996c109d1f \ @@ -719,142 +804,164 @@ couchbase-columnar==1.0.0 \ --hash=sha256:fc0fad2d386c5b5df7aaaccd8751e01caa886cc640cc8c92523dd07c4e7be519 \ --hash=sha256:fc4efa3e15190c3731478006de494b046bc57785e9c8ae99ac8b375a91683e38 # via feast (pyproject.toml) -coverage[toml]==7.13.4 \ - --hash=sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246 \ - --hash=sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459 \ - --hash=sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 \ - --hash=sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6 \ - --hash=sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415 \ - --hash=sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf \ - --hash=sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80 \ - --hash=sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 \ - --hash=sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0 \ - --hash=sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b \ - --hash=sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9 \ - --hash=sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b \ - --hash=sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f \ - --hash=sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505 \ - --hash=sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47 \ - --hash=sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55 \ - --hash=sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def \ - --hash=sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689 \ - --hash=sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012 \ - --hash=sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5 \ - --hash=sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3 \ - --hash=sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95 \ - --hash=sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9 \ - --hash=sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601 \ - --hash=sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997 \ - --hash=sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c \ - --hash=sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac \ - --hash=sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c \ - --hash=sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa \ - --hash=sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750 \ - --hash=sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3 \ - --hash=sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d \ - --hash=sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12 \ - --hash=sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a \ - --hash=sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932 \ - --hash=sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356 \ - --hash=sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92 \ - --hash=sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148 \ - --hash=sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39 \ - --hash=sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634 \ - --hash=sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6 \ - --hash=sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72 \ - --hash=sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98 \ - --hash=sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef \ - --hash=sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3 \ - --hash=sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9 \ - --hash=sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0 \ - --hash=sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a \ - --hash=sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9 \ - --hash=sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552 \ - --hash=sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc \ - --hash=sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f \ - --hash=sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525 \ - --hash=sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940 \ - --hash=sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a \ - --hash=sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23 \ - --hash=sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f \ - --hash=sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc \ - --hash=sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b \ - --hash=sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056 \ - --hash=sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7 \ - --hash=sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb \ - --hash=sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a \ - --hash=sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd \ - --hash=sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea \ - --hash=sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126 \ - --hash=sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299 \ - --hash=sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9 \ - --hash=sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b \ - --hash=sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00 \ - --hash=sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf \ - --hash=sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda \ - --hash=sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2 \ - --hash=sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5 \ - --hash=sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d \ - --hash=sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9 \ - --hash=sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 \ - --hash=sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b \ - --hash=sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa \ - --hash=sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092 \ - --hash=sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58 \ - --hash=sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea \ - --hash=sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26 \ - --hash=sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea \ - --hash=sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9 \ - --hash=sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053 \ - --hash=sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f \ - --hash=sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0 \ - --hash=sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3 \ - --hash=sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256 \ - --hash=sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a \ - --hash=sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903 \ - --hash=sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91 \ - --hash=sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd \ - --hash=sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505 \ - --hash=sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7 \ - --hash=sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0 \ - --hash=sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2 \ - --hash=sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a \ - --hash=sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71 \ - --hash=sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985 \ - --hash=sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242 \ - --hash=sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d \ - --hash=sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af \ - --hash=sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c \ - --hash=sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0 +coverage[toml]==7.14.1 \ + --hash=sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86 \ + --hash=sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd \ + --hash=sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d \ + --hash=sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5 \ + --hash=sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42 \ + --hash=sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de \ + --hash=sha256:10274a1fbeb8ec5d72966e17bb198a3104257aca4ac09d98667c5f8aca8c8548 \ + --hash=sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1 \ + --hash=sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7 \ + --hash=sha256:1238cb94638e610e972c60dac68e813f868dc7d6e982535270558443058d9d59 \ + --hash=sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906 \ + --hash=sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af \ + --hash=sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1 \ + --hash=sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d \ + --hash=sha256:196a13319ad88d6d8ef5ab489ec4f44ddde2143c0c7d5b27786f6c3ffd56a7e1 \ + --hash=sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be \ + --hash=sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02 \ + --hash=sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42 \ + --hash=sha256:23bf7fa51ac02e07fc7c96849b82946da47ae862dc8f86d183b2a4864fc38129 \ + --hash=sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e \ + --hash=sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be \ + --hash=sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e \ + --hash=sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65 \ + --hash=sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54 \ + --hash=sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1 \ + --hash=sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5 \ + --hash=sha256:3a56abc20a472baf0304c455721bc601477440d28ecfde8a03dde79ede07e0df \ + --hash=sha256:3c18ebc343e15be53049b3a2dce38fe82d58f37e20ab9094b3a39c0aa4f6bb47 \ + --hash=sha256:3d452fd08b5c72c5167c93e6867b5c08500bd40f2a21e1e854a500550b6cc36f \ + --hash=sha256:3e3680291c4a1d0dadfa84a2c459576a4af5133abb617905714339a0c73138cf \ + --hash=sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37 \ + --hash=sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4 \ + --hash=sha256:478b5bcd63c2e1357c5c7e16c070690df7b07f676b1c114d7b93e533c664309f \ + --hash=sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84 \ + --hash=sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1 \ + --hash=sha256:4ea1c034f95c9b056e856b794630b17f9fa3d57e4800ff1e503d3be0f9c9078c \ + --hash=sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8 \ + --hash=sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e \ + --hash=sha256:59baf88468dbc8d63b1887afd92bda52e40bb1561696e5819670601403810cec \ + --hash=sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d \ + --hash=sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54 \ + --hash=sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890 \ + --hash=sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b \ + --hash=sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d \ + --hash=sha256:62a9f70b52e0b5a95cfef4a5c5641b06983cadc5e538a3feeb5c00211f523ac2 \ + --hash=sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33 \ + --hash=sha256:6a3cb83d1552c0cd1b4906655b6a33fd4a8473229633a901c6b73bf86914dee9 \ + --hash=sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e \ + --hash=sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6 \ + --hash=sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce \ + --hash=sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247 \ + --hash=sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901 \ + --hash=sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36 \ + --hash=sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69 \ + --hash=sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416 \ + --hash=sha256:7f02d09f70776579b926d889a4c9c235070a1f47c40458aeaca563fae5acfdb5 \ + --hash=sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500 \ + --hash=sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad \ + --hash=sha256:84ac9499e48700399a5dd0ea7085b5091961fec52c68d66b4ec0d3cf7f4441b1 \ + --hash=sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b \ + --hash=sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b \ + --hash=sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a \ + --hash=sha256:87ebdf787d4888e3f3f2d523eadc6e18c6d18c6d0eb173801a189641627fb37e \ + --hash=sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee \ + --hash=sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07 \ + --hash=sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a \ + --hash=sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d \ + --hash=sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c \ + --hash=sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343 \ + --hash=sha256:a24a81f9715ee42ef59a316cc11611c98fe23920f7c81861315c9f3ff4a230f4 \ + --hash=sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2 \ + --hash=sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8 \ + --hash=sha256:a5274669f37f2343635a347b91a60777621341ab3378e9c6ac9335eee704bddf \ + --hash=sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb \ + --hash=sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c \ + --hash=sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff \ + --hash=sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e \ + --hash=sha256:b84ffdf877644e7096aa936991efeed873f7f3df57b9cd001312b7668ab08550 \ + --hash=sha256:bcaa50684dcaadfa599ac48f81103c756d791cfd85c97203d2217c593d48b860 \ + --hash=sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793 \ + --hash=sha256:c643734307300234fafa36bf2a040a7235f8f177ea1fd6ec1423aea6fb7b929f \ + --hash=sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851 \ + --hash=sha256:c7e057326434e441306226fbeb5d1aaf14a2637efe97ba668306635835f32ad7 \ + --hash=sha256:c912c259304cfb5ee584481cfb7ce1ff932b4d61e6c9140b8f19cb7b5ed82332 \ + --hash=sha256:ce66d8e46da2bb5ee313a745cbd2e391d319176c1f7a9451bfcd3a2fb920859b \ + --hash=sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2 \ + --hash=sha256:cfe5a5fec635799ef33428f1e5e61bafa45a92a96190ba731561ba558ccc214d \ + --hash=sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a \ + --hash=sha256:d34d75f892b3ab73ba11cab5442cce7b3e168fd64162b16f0e1e0d09c508edef \ + --hash=sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474 \ + --hash=sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee \ + --hash=sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43 \ + --hash=sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034 \ + --hash=sha256:dd34767fa19848d35659ffc0a75314f58c7af3f1cd87ec521e8292a1238398a3 \ + --hash=sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c \ + --hash=sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d \ + --hash=sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7 \ + --hash=sha256:e854312c4103f2ad4c0dc023b69b77ebfd2c89db5f86c4c94dc2353f9a92167e \ + --hash=sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d \ + --hash=sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4 \ + --hash=sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9 \ + --hash=sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52 \ + --hash=sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a \ + --hash=sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c \ + --hash=sha256:fc459e5d73be2d6332fcfe8dbf3d8994671fe33c700f4565988ecfa511547253 \ + --hash=sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c # via pytest-cov -cryptography==43.0.3 \ - --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ - --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ - --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ - --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ - --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ - --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ - --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ - --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ - --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ - --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ - --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ - --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ - --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ - --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ - --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ - --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ - --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ - --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ - --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ - --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ - --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ - --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ - --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ - --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ - --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ - --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ - --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # feast (pyproject.toml) # azure-identity @@ -862,6 +969,7 @@ cryptography==43.0.3 \ # google-auth # great-expectations # jwcrypto + # mlflow # moto # msal # oracledb @@ -870,59 +978,69 @@ cryptography==43.0.3 \ # snowflake-connector-python # types-pyopenssl # types-redis -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +cycler==0.12.1 \ + --hash=sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 \ + --hash=sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c + # via matplotlib +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.6.1 \ - --hash=sha256:140ce500bc41939ff6ce995702d66b1f4b2ee7f117bb9b07512fab6804d4070a \ - --hash=sha256:f53228e6dadc9f837037b1bf3051d7d8c054abbb3eb29f1f022926e08090e0da +databricks-sdk==0.114.0 \ + --hash=sha256:25a40b83d76fa6c8a621f884da41e45e3ae5267218dafa71db9b363dd9238f57 \ + --hash=sha256:d62e6fcb1dc98b0b390d369261d1d68a6cf9f91139c34cf659865faf50b1d044 + # via + # mlflow-skinny + # mlflow-tracing +datasets==5.0.0 \ + --hash=sha256:7dd34927a0fd7046e98aad5cb9430e699c373238a15befa7b9bf22b991a7fee6 \ + --hash=sha256:83dbbbdb07a33b82192b8c419deb18739b138ee2ce1a322d55ce6b100954ec1a # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.12.0 \ - --hash=sha256:3db93df7969c3f22c6fbf75a51b0af4c21b189d8db6f3c54e8471102c775bb0d \ - --hash=sha256:9d1c0ed41926102c1c39fdd780e1a332f58c9b794e94dba0dcf5dfefc847d6ea +dbt-artifacts-parser==0.13.2 \ + --hash=sha256:9eca1e413f7eee522cc1556634b0b9effe790b70d8ffcc46ae2328b9868efaf1 \ + --hash=sha256:abb798aa73ff8cc295b4ecf03ee02d6a3bc48ad79f7d093d4bb3ffef68e77fb4 # via feast (pyproject.toml) -debugpy==1.8.20 \ - --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ - --hash=sha256:0dfd9adb4b3c7005e9c33df430bcdd4e4ebba70be533e0066e3a34d210041b66 \ - --hash=sha256:157e96ffb7f80b3ad36d808646198c90acb46fdcfd8bb1999838f0b6f2b59c64 \ - --hash=sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb \ - --hash=sha256:20d6e64ea177ab6732bffd3ce8fc6fb8879c60484ce14c3b3fe183b1761459ca \ - --hash=sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f \ - --hash=sha256:3ca85463f63b5dd0aa7aaa933d97cbc47c174896dcae8431695872969f981893 \ - --hash=sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390 \ - --hash=sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d \ - --hash=sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33 \ - --hash=sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 \ - --hash=sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a \ - --hash=sha256:60f89411a6c6afb89f18e72e9091c3dfbcfe3edc1066b2043a1f80a3bbb3e11f \ - --hash=sha256:70ad9ae09b98ac307b82c16c151d27ee9d68ae007a2e7843ba621b5ce65333b5 \ - --hash=sha256:760813b4fff517c75bfe7923033c107104e76acfef7bda011ffea8736e9a66f8 \ - --hash=sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec \ - --hash=sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344 \ - --hash=sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf \ - --hash=sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b \ - --hash=sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173 \ - --hash=sha256:9eeed9f953f9a23850c85d440bf51e3c56ed5d25f8560eeb29add815bd32f7ee \ - --hash=sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3 \ - --hash=sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be \ - --hash=sha256:b773eb026a043e4d9c76265742bc846f2f347da7e27edf7fe97716ea19d6bfc5 \ - --hash=sha256:bff8990f040dacb4c314864da95f7168c5a58a30a66e0eea0fb85e2586a92cd6 \ - --hash=sha256:c1178ae571aff42e61801a38b007af504ec8e05fde1c5c12e5a7efef21009642 \ - --hash=sha256:c29dd9d656c0fbd77906a6e6a82ae4881514aa3294b94c903ff99303e789b4a2 \ - --hash=sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393 \ - --hash=sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b \ - --hash=sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7 +debugpy==1.8.21 \ + --hash=sha256:0042da0ecd0a8b50dc4a54395ecd870d258d73fa18776f50c91fdcabdcad2675 \ + --hash=sha256:0fddfdc130ac6d8bfc0415b0409822fa901c8f310e5c945ac5653a0352532344 \ + --hash=sha256:13678151fc401e2d68c9880b91e28714f797d40422994572b24560ef80910a88 \ + --hash=sha256:15d4963bd5ffa48f0da0947fd06757fa7621945048a14ad7705431566d3c0e7c \ + --hash=sha256:2c2ae706dec41d99a9ca1f7ebc987a83e65578363be6f6b3ac9067504917fae1 \ + --hash=sha256:3d6922439bf33fd38a3e2c447869ebc7b97da5cd3d329ff1ef9bc06c4903437e \ + --hash=sha256:4743373c1cac7f9e74a1b9915bf1dbe0e900eca657ffb170ae07ac8363205ae9 \ + --hash=sha256:4e70cc8b5079f885cb43910924ee0aab73b8b6b2a14eff23afdd9895d86e79eb \ + --hash=sha256:4e7c2d784d78ad4b71a5f8cd7b59c167719ec8a7a0211dbb3eb1bfeda78bc4e2 \ + --hash=sha256:72b5d676c4cbfac3bac5bb01c138a4656e843f93f03ce2a5f4e394ad49fbee73 \ + --hash=sha256:84c564d8cc701d41843b29a92814c1f1bef6798724ca9d675c284ad9f6a547d7 \ + --hash=sha256:8eeab7b5462f683452c57c0126aaa5ec4e974ddb705f39ba87dff8818c8e08f9 \ + --hash=sha256:9bb2a685287a2ac9b181cde89edcec64845cb51de7faaa75badb9a698bc24782 \ + --hash=sha256:9f5171176a0084b95d2ebe55a4d1f7b2a75b74c5dbec577ebd3a85c740551c36 \ + --hash=sha256:9f96713896f39c3dff0ee841f47320c3f2983d33c341e009361bb0ebc79adc4e \ + --hash=sha256:a3c53278e84c94e11bd87c53970ec391d1a67396c8b22609fcac576520e611a6 \ + --hash=sha256:a7fe47fd23da57b9e0bec3f4a8ee65a2dc55782455ed7f2141d75ab5d2eaeef5 \ + --hash=sha256:aa648733047443eb1d07682c4ef287d36a54507b643ffdf38b09a3ef002c72a0 \ + --hash=sha256:aa9d941d6dfe3d0407e4b3ca0b9ec466030e260fbf1174094f68785680f66db6 \ + --hash=sha256:b1e37d333663c8851516a47364ef473da127f9caebe4417e6df6f5825a7e9a92 \ + --hash=sha256:bd7ba9dd3daa7c2f942c6ca8d4695a16bf9ac16b63615261c7982bc74f7ed20c \ + --hash=sha256:c193d474f0a211191f2b4449d2d06157c689013035bd952f3b617e0ef422b176 \ + --hash=sha256:da456226c7b4c69e35dbe35dcee6623d912000a77816db7856a41af1c72a0264 \ + --hash=sha256:e935f9dc0501be523c8a8e1853c39432e1354e9ece717ae5998fd2371c4542c3 \ + --hash=sha256:ecbd158386c31ffe71d46f72d44d56e66331ab9b16cad649156d514368f23ab2 \ + --hash=sha256:f15c10084f9861b5e8414a48f18f8e4aadf51a98a59e72c16aa28281ca994672 \ + --hash=sha256:f68b891688e61bdc08b8d364d919ff0051e0b94657b39dcd027bc3173edb7cdc \ + --hash=sha256:f843a8b08c2edeaf9b1582eed4f25441af21a297c22ff16bf76a662557aa9c9e \ + --hash=sha256:fe0744a12353406de0ae8ccff0d0a4a666f00801a3db8fd04e7a5f761cd520e8 \ + --hash=sha256:ffd932c6796afadab6993ec96745918a8cb2444dbd392074f769db5ea40ab440 # via ipykernel -decorator==5.2.1 \ - --hash=sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360 \ - --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a +decorator==5.3.1 \ + --hash=sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82 \ + --hash=sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c # via ipython defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ @@ -939,6 +1057,10 @@ deltalake==0.25.5 \ --hash=sha256:cb1c7e826fd7c3bdd3676c7471d3b551e1a3674e44cd8e3747a0017a2c0292b7 \ --hash=sha256:e8f0d24bf64455f702da8402307b22e01f91e0f76694f7c5e33c9513011e8d29 # via feast (pyproject.toml) +deprecated==1.3.1 \ + --hash=sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f \ + --hash=sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223 + # via cassandra-driver deprecation==2.1.0 \ --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a @@ -950,28 +1072,36 @@ dill==0.3.9 \ # feast (pyproject.toml) # datasets # multiprocess -distlib==0.4.0 \ - --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ - --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d +distlib==0.4.1 \ + --hash=sha256:9c2c552c68cbadc619f2d0ed3a69e27c351a3f4c9baa9ffb7df9e9cdc3d19a97 \ + --hash=sha256:c3804d0d2d4b5fcd44036eb860cb6660485fcdf5c2aba53dc324d805837ea65b # via virtualenv +dnspython==2.8.0 \ + --hash=sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af \ + --hash=sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f + # via + # feast (pyproject.toml) + # pymongo docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 - # via testcontainers + # via + # mlflow + # testcontainers docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.69.0 \ - --hash=sha256:4c3817ce00c7cb5622e59ddb4e5268a58083ae67f6e1436b36a84b6b4bbf6899 \ - --hash=sha256:9760e13063de5f373dbc3417de3ef9a3709c6eb18c0e60ada3c1f96c8b37c14e +docling-core[chunking]==2.78.1 \ + --hash=sha256:7463a2ce3e70590f330cf16dce11a7dbb761ece007a50e9082b44b7fed849820 \ + --hash=sha256:a700d4dc98592e95c05c57ae8d25698f514b8dfbe25e97f36a314f85e9cc0684 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.12.0 \ - --hash=sha256:008fe1f5571db413782efe510c1d6327ea9df20b5255d416d0f4b56cfd090238 \ - --hash=sha256:85c2b6c9dbb7fbb8eaf0f2a462b5984626457a6dc33148643491270c27767b46 +docling-ibm-models==3.13.3 \ + --hash=sha256:50fc83d244ce2dc43158e02155d1caa68374d7a169d0f34e67d7eb14f396ffe6 \ + --hash=sha256:8c8b55e80b3d20fc74d85ca49a4d064578ef75b9f7251eec42fc9df6af426218 # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1006,42 +1136,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1050,13 +1180,13 @@ durationpy==0.10 \ easyocr==1.7.2 \ --hash=sha256:5be12f9b0e595d443c9c3d10b0542074b50f0ec2d98b141a109cd961fd1c177c # via docling -elastic-transport==9.2.1 \ - --hash=sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4 \ - --hash=sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d +elastic-transport==9.4.1 \ + --hash=sha256:186a29e6c66ff269487e33f7b17176316e18b6061702c25eb0bb15681302e91d \ + --hash=sha256:d12c86ea73528690ebf63a488d9ae323292e6aa5ee55e1e29f14293472f4197f # via elasticsearch -elasticsearch==9.3.0 \ - --hash=sha256:67bd2bb4f0800f58c2847d29cd57d6e7bf5bc273483b4f17421f93e75ba09f39 \ - --hash=sha256:f76e149c0a22d5ccbba58bdc30c9f51cf894231b359ef4fd7e839b558b59f856 +elasticsearch==9.4.1 \ + --hash=sha256:1d78fdfba97a903ec35a5eb5808a74e33392b7c620bd5f742d465a3a26c27d75 \ + --hash=sha256:71ab71c3d1b20fd88c2922fb82c3277cce7ea03c160686e7b9368b265c2b4cac # via feast (pyproject.toml) entrypoints==0.4 \ --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ @@ -1108,12 +1238,13 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp + # mlflow-skinny fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d @@ -1122,9 +1253,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via # datasets # huggingface-hub @@ -1137,6 +1268,68 @@ filetype==1.2.0 \ --hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \ --hash=sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25 # via docling +flask==3.1.3 \ + --hash=sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb \ + --hash=sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c + # via + # flask-cors + # mlflow +flask-cors==6.0.2 \ + --hash=sha256:6e118f3698249ae33e429760db98ce032a8bf9913638d085ca0f4c5534ad2423 \ + --hash=sha256:e57544d415dfd7da89a9564e1e3a9e515042df76e12130641ca6f3f2f03b699a + # via mlflow +fonttools==4.63.0 \ + --hash=sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69 \ + --hash=sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c \ + --hash=sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac \ + --hash=sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096 \ + --hash=sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d \ + --hash=sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68 \ + --hash=sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616 \ + --hash=sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78 \ + --hash=sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f \ + --hash=sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b \ + --hash=sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b \ + --hash=sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02 \ + --hash=sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d \ + --hash=sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f \ + --hash=sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8 \ + --hash=sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272 \ + --hash=sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49 \ + --hash=sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419 \ + --hash=sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001 \ + --hash=sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03 \ + --hash=sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196 \ + --hash=sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9 \ + --hash=sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e \ + --hash=sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5 \ + --hash=sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007 \ + --hash=sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380 \ + --hash=sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8 \ + --hash=sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27 \ + --hash=sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40 \ + --hash=sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e \ + --hash=sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0 \ + --hash=sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263 \ + --hash=sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb \ + --hash=sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94 \ + --hash=sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b \ + --hash=sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6 \ + --hash=sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579 \ + --hash=sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4 \ + --hash=sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59 \ + --hash=sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0 \ + --hash=sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e \ + --hash=sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be \ + --hash=sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd \ + --hash=sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18 \ + --hash=sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22 \ + --hash=sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0 \ + --hash=sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b \ + --hash=sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b \ + --hash=sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af \ + --hash=sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745 + # via matplotlib fqdn==1.5.1 \ --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 @@ -1275,9 +1468,9 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec[http]==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec[http]==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask @@ -1288,9 +1481,17 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +gitdb==4.0.12 \ + --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ + --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + # via gitpython +gitpython==3.1.50 \ + --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \ + --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 + # via mlflow-skinny +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1300,10 +1501,11 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via + # databricks-sdk # google-api-core # google-auth-oauthlib # google-cloud-bigquery @@ -1314,37 +1516,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -1388,88 +1590,100 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status +graphene==3.4.3 \ + --hash=sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa \ + --hash=sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71 + # via mlflow +graphql-core==3.2.11 \ + --hash=sha256:0b3e35ff41e9adba53021ab0cef475eb18f57c7f53f0f2ca55567fbf3c537ea0 \ + --hash=sha256:e7e156d10beb127cab5c89ff0da71416fc73d27c484a4757d3b2d35633774802 + # via + # graphene + # graphql-relay +graphql-relay==3.2.0 \ + --hash=sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c \ + --hash=sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5 + # via graphene great-expectations==0.18.8 \ --hash=sha256:ab41cfa3de829a4f77bdcd4a23244684cbb67fdacc734d38910164cd02ec95b6 \ --hash=sha256:c1205bede593f679e22e0b3826d6ae1623c439cafd553f9f0bc2b0fd441f6ed9 # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1480,77 +1694,81 @@ grpcio==1.62.3 \ # grpcio-tools # pymilvus # qdrant-client -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -grpcio-testing==1.62.3 \ - --hash=sha256:06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb \ - --hash=sha256:f63577f28aaa95ea525124a0fd63c3429d71f769f4179b13f5e6cbc54979bfab +grpcio-testing==1.81.0 \ + --hash=sha256:32370bdffc0cd09abade928fd880f919bf070afe5d012a2de1412427b2dc1921 \ + --hash=sha256:f754ea3efd110127920513f0177f31b5c9bcbdc7e4af9ac568d8b3a5684df3c6 # via feast (pyproject.toml) -grpcio-tools==1.62.3 \ - --hash=sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133 \ - --hash=sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e \ - --hash=sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e \ - --hash=sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7 \ - --hash=sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf \ - --hash=sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa \ - --hash=sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5 \ - --hash=sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c \ - --hash=sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373 \ - --hash=sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184 \ - --hash=sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1 \ - --hash=sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950 \ - --hash=sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61 \ - --hash=sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0 \ - --hash=sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26 \ - --hash=sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5 \ - --hash=sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1 \ - --hash=sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23 \ - --hash=sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d \ - --hash=sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833 \ - --hash=sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492 \ - --hash=sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43 \ - --hash=sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7 \ - --hash=sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3 \ - --hash=sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc \ - --hash=sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed \ - --hash=sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a \ - --hash=sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557 \ - --hash=sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193 \ - --hash=sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325 \ - --hash=sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b \ - --hash=sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf \ - --hash=sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d \ - --hash=sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10 \ - --hash=sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9 \ - --hash=sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc \ - --hash=sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5 \ - --hash=sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5 \ - --hash=sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f \ - --hash=sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc \ - --hash=sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f \ - --hash=sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6 \ - --hash=sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29 \ - --hash=sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434 \ - --hash=sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14 \ - --hash=sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667 \ - --hash=sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57 \ - --hash=sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d +grpcio-tools==1.81.0 \ + --hash=sha256:0034997767960644f0f4a2aecf35df5fc426d43fa5639dd1b8317da835bab2a4 \ + --hash=sha256:012d580d98db189e4bd231a6529b162bc27a5f52c4854e2d21a4016edc47c760 \ + --hash=sha256:019f05a17b5495d561603f75a74a4a76ad22456a95dc7623c7be4e4b44391b88 \ + --hash=sha256:0733d773eca8cb461f4f2a1b79c64c123db9661be41b08184b81497b2b991ccb \ + --hash=sha256:1e21049aeedd9d62e5e58146e5d00f3b75674d8d8d3cc69709ab950082be8421 \ + --hash=sha256:1ecb833118bfa2c3051e534692f2b43f7c6db14e1eac9b1e7f6e66b6b6dc5074 \ + --hash=sha256:23831f5c66038c5793cb5d2651120bc24a33705e1ce2887a88f54272b73b240f \ + --hash=sha256:244619491a12d1f8d4119bb5930272827084a1e7caa8f9d5a0d4ca6595bb1dea \ + --hash=sha256:283bb3465331a4034b14dce35425c47b0cfbd287b09a6e9d15c9f26fbb17e799 \ + --hash=sha256:2a369a9e27fcb6279387744778d67a64551de82db0e9cf7e1e9451c22f719e07 \ + --hash=sha256:33c579bf24040dbdce751e05b5bcedc13dafffa8f2dfa07193bc05960dc95b49 \ + --hash=sha256:3401d6d4668c064c9ed344825fe97ff076cd8ba719a24e3d3c7169b604cbf00f \ + --hash=sha256:374fe0435447f283e3c69f719ef1bc66f2e187a239ce25444b2de45cb3a6a744 \ + --hash=sha256:3f1ac691debbdbf00e7635ecacf28647f48f67fb4b14120a4541c8bb0f8333ae \ + --hash=sha256:404ca893d54f26fddb868bbd4a54b203fbf914264d26c52e2f2aff35851a9f72 \ + --hash=sha256:40b7a17629e5c944c8ba98a438f051b9affaf30794e6e096578ba0030725f90c \ + --hash=sha256:42e1eaa98199bd4f900f8af091e27aef804dd53b59c92adafcc9faabc0a92240 \ + --hash=sha256:475286558410e4d0394fc8129559080c22835ece3c23cac194b46c5ad7d0fad1 \ + --hash=sha256:4a8d9fdf42537cd1924f7e95013771aa73c89501ccf112b7517c22ca825be9f5 \ + --hash=sha256:52687858c044a6a4dd3fc4049b012b131254a3061360d6de2f97c3e38a7aedd9 \ + --hash=sha256:564624654f5a0377adc69f226f93ec5ff52715030c2f846af6c54ccc4ca2d225 \ + --hash=sha256:5783b6758244f6eaceb41a0e651828824b0d0c92724ddf4b68879ced9bfd9b50 \ + --hash=sha256:58e65dd13f7ffc25f5a9cd9890fddfd39b3c51e5c3c1acd987813b1dc1173704 \ + --hash=sha256:5a7c89432a3b200be306e76307b866716663b4c71d7816bdf382af81e00abd51 \ + --hash=sha256:5c5f44305786c1295320fed477f5673be4ca5f6ed1b31f8696f0791d4b12906d \ + --hash=sha256:61d9ad6b5c0f3857663701bdc2cbb3da7f7d835ce9a8d597ffca443124a96894 \ + --hash=sha256:677207d88b659048f63697c237bf650b123a7a1de36158db57176f84c5bca84a \ + --hash=sha256:69f8355b723db7b5e26a3bff76f9deb3a407d22fe289bca486ccf95d6133cad0 \ + --hash=sha256:760775f79bbefa321cd327fe1019a9d6ad0d93acb1ede7b7905c712679542fd7 \ + --hash=sha256:78c2514bf172b20631685840fea0c5d1bec5518b649d0a498f6dd8f91dfce56a \ + --hash=sha256:7af4faf34376c57f4f3c42aa05f065d3b10e774b8a8d8b27d659d5cc351e5c75 \ + --hash=sha256:98b57a592a75553f4dd38db3993b037953245991b8df9f06927a8978962dcd82 \ + --hash=sha256:a741007631248dd903f880b575a63c0662433ed4b966262ab0f437ea860c9b7e \ + --hash=sha256:a87ea8056beea56b24353d27b7f0ab814daabb372aa517d2e179470e66fd8f6b \ + --hash=sha256:b2b26111795d0e7a72fa483d377a75b57203edaac8bbbac1e9b8f174e7b01ff3 \ + --hash=sha256:bac1c6ddc5eb3762257e773829b4e00ea7d0592f02498f27e5bdb75cd3182d69 \ + --hash=sha256:bf19fdc8b6258fbf36ea65f5672206483ef4639a16d33e3367d77e4523b4089b \ + --hash=sha256:bf2ffd98c754d54a5affddfe3a18d4822b972c5c37ca6a33a456c94e6f3dd82b \ + --hash=sha256:d56060281599d87e66a0dc6840b68730d81c215dbb1b5c50882f819bc9b6aba5 \ + --hash=sha256:d744ea354c9ca33ca17522436825e2842df9b731bcc924a73f4a7d205ed53006 \ + --hash=sha256:dce33d09851bc15dead814bd9d21023bffdf0f838ecf65995a2456e5692831fd \ + --hash=sha256:e5d241c694a226bada06dae9accc47c5c25e586f49464823498e84cff63eedea \ + --hash=sha256:e9945945edc14022abab07caec0ebc16bf51219e586b4f008d09334cc479655c \ + --hash=sha256:f02d796474e58bba879965d228874c2c34164b6a5d96c0faf6bf896a6c3d8a0b \ + --hash=sha256:f1f407697873acbf1d961c6fb9223114a3e679938469d4186623b8b872dbdae0 \ + --hash=sha256:f35da7b3b9537ecce9a5cfd967b1316a815378d5a3729e9ea556b22a14f6e315 \ + --hash=sha256:f37ce0440e5dc563662da89d7d1edd20654e6fb615ada5c8027f15f881bd40d0 \ + --hash=sha256:fa529a1f7a946cdb6881141a07d8fc8fb074af2fd17323e5f3530c8718101680 \ + --hash=sha256:fbe12f98aeddfeaa74d3dbe41dc451f008edf3ab1b82eb62f7a61011003d4833 \ + --hash=sha256:ffa74b84d201bea407f22e00ac0367f12df48a0073b0ffd9f3be9d8126a55245 \ + --hash=sha256:ffb1e507f9849ee013473f732b1ca5d732457f9b1d0d298efe8a77c33bb65d3a # via feast (pyproject.toml) -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) + # mlflow # uvicorn-worker h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -1570,128 +1788,146 @@ hazelcast-python-client==5.6.0 \ --hash=sha256:834b87076a47c781ef80bdcb522b86abc75ff28992dfe384e47f669f06cabb18 \ --hash=sha256:e2cec409068990ca9b4381fe97160cc2375412334782bef45ab4c8fe4d10536c # via feast (pyproject.toml) -hf-xet==1.3.2 \ - --hash=sha256:06b724a361f670ae557836e57801b82c75b534812e351a87a2c739f77d1e0635 \ - --hash=sha256:06cdbde243c85f39a63b28e9034321399c507bcd5e7befdd17ed2ccc06dfe14e \ - --hash=sha256:1c88fbd90ad0d27c46b77a445f0a436ebaa94e14965c581123b68b1c52f5fd30 \ - --hash=sha256:211f30098512d95e85ad03ae63bd7dd2c4df476558a5095d09f9e38e78cbf674 \ - --hash=sha256:305f5489d7241a47e0458ef49334be02411d1d0f480846363c1c8084ed9916f7 \ - --hash=sha256:3155a02e083aa21fd733a7485c7c36025e49d5975c8d6bda0453d224dd0b0ac4 \ - --hash=sha256:31612ba0629046e425ba50375685a2586e11fb9144270ebabd75878c3eaf6378 \ - --hash=sha256:335a8f36c55fd35a92d0062f4e9201b4015057e62747b7e7001ffb203c0ee1d2 \ - --hash=sha256:35b855024ca37f2dd113ac1c08993e997fbe167b9d61f9ef66d3d4f84015e508 \ - --hash=sha256:433c77c9f4e132b562f37d66c9b22c05b5479f243a1f06a120c1c06ce8b1502a \ - --hash=sha256:4a6817c41de7c48ed9270da0b02849347e089c5ece9a0e72ae4f4b3a57617f82 \ - --hash=sha256:4bc995d6c41992831f762096020dc14a65fdf3963f86ffed580b596d04de32e3 \ - --hash=sha256:7c2a054a97c44e136b1f7f5a78f12b3efffdf2eed3abc6746fc5ea4b39511633 \ - --hash=sha256:83d8ec273136171431833a6957e8f3af496bee227a0fe47c7b8b39c106d1749a \ - --hash=sha256:91b1dc03c31cbf733d35dc03df7c5353686233d86af045e716f1e0ea4a2673cf \ - --hash=sha256:9298b47cce6037b7045ae41482e703c471ce36b52e73e49f71226d2e8e5685a1 \ - --hash=sha256:959083c89dee30f7d6f890b36cdadda823386c4de63b1a30384a75bfd2ae995d \ - --hash=sha256:a85d3d43743174393afe27835bde0cd146e652b5fcfdbcd624602daef2ef3259 \ - --hash=sha256:c1980abfb68ecf6c1c7983379ed7b1e2b49a1aaf1a5aca9acc7d48e5e2e0a961 \ - --hash=sha256:c1ae4d3a716afc774e66922f3cac8206bfa707db13f6a7e62dfff74bfc95c9a8 \ - --hash=sha256:c34e2c7aefad15792d57067c1c89b2b02c1bbaeabd7f8456ae3d07b4bbaf4094 \ - --hash=sha256:cfa760888633b08c01b398d212ce7e8c0d7adac6c86e4b20dfb2397d8acd78ee \ - --hash=sha256:d6dbdf231efac0b9b39adcf12a07f0c030498f9212a18e8c50224d0e84ab803d \ - --hash=sha256:e130ee08984783d12717444e538587fa2119385e5bd8fc2bb9f930419b73a7af \ - --hash=sha256:f93b7595f1d8fefddfede775c18b5c9256757824f7f6832930b49858483cd56f +hf-xet==1.5.0 \ + --hash=sha256:1e60df5a42e9bed8628b6416af2cba4cba57ae9f02de226a06b020d98e1aab18 \ + --hash=sha256:2806c7c17b4d23f8d88f7c4814f838c3b6150773fe339c20af23e1cfaf2797e4 \ + --hash=sha256:2baea1b0b989e5c152fe81425f7745ddc8901280ba3d97c98d8cdece7b706c60 \ + --hash=sha256:3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949 \ + --hash=sha256:4b35549ce62601b84da4ff9b24d970032ace3d4430f52d91bcbb26c901d6c690 \ + --hash=sha256:526345b3ed45f374f6317349df489167606736c876241ba984105afe7fd4839d \ + --hash=sha256:5906bf7718d3636dc13402914736abe723492cb730f744834f5f5b67d3a12702 \ + --hash=sha256:5f3dc2248fc01cc0a00cd392ab497f1ca373fcbc7e3f2da1f452480b384e839e \ + --hash=sha256:73a0dae8c71de3b0633a45c73f4a4a5ed09e94b43441d82981a781d4f12baa42 \ + --hash=sha256:786d28e2eb8315d5035544b9d137b4a842d600c434bb91bf7d0d953cce906ad4 \ + --hash=sha256:7d70fe2ce97b9db73b9c9b9c81fe3693640aec83416a966c446afea54acfae3c \ + --hash=sha256:872d5601e6deea30d15865ede55d29eac6daf5a534ab417b99b6ef6b076dd96c \ + --hash=sha256:8dbcbab554c9ef158ef2c991545c3e970ddd8cc7acdcd0a78c5a41095dab4ded \ + --hash=sha256:9929561f5abf4581c8ea79587881dfef6b8abb2a0d8a51915936fc2a614f4e73 \ + --hash=sha256:9a0ee58cd18d5ea799f7ed11290bbccbe56bdd8b1d97ca74b9cc49a3945d7a3b \ + --hash=sha256:a60290ec57e9b71767fba7c3645ddafdd0759974b540441510c629c6db6db24a \ + --hash=sha256:b285cea1b5bab46b758772716ba8d6854a1a0310fed1c249d678a8b38601e5a0 \ + --hash=sha256:b6c9df403040248c76d808d3e047d64db2d923bae593eb244c41e425cf6cd7be \ + --hash=sha256:c799d49f1a5544a0ef7591c0ee75e0d6b93d6f56dc7a4979f59f7518d2872216 \ + --hash=sha256:cf7b2dc6f31a4ea754bb50f74cde482dcf5d366d184076d8530b9872787f3761 \ + --hash=sha256:dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56 \ + --hash=sha256:e0fb0a34d9f406eed88233e829a67ec016bec5af19e480eac65a233ea289a948 \ + --hash=sha256:e5de0f6deada0dada870bb376a11bcd1f08abf3a968a6d118f33e72d1b1eb480 \ + --hash=sha256:f7b7bbae318e583a86fb21e5a4a175d6721d628a2874f4bd022d0e660c32a682 \ + --hash=sha256:fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a # via huggingface-hub -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1701,50 +1937,57 @@ httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx[http2]==0.27.2 \ --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ @@ -1762,6 +2005,10 @@ httpx-sse==0.4.3 \ --hash=sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc \ --hash=sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d # via mcp +huey==3.0.1 \ + --hash=sha256:5de8ff852021da670efe8d4d78db8719c0255ebbde0772766a0114f997ea61f6 \ + --hash=sha256:83ca54fa77c4ee27349393212fc13088142244f491be903f620a9e46e8fca4ce + # via mlflow huggingface-hub==0.36.2 \ --hash=sha256:1934304d2fb224f8afa3b87007d58501acfda9215b334eed53072dd5e815ff7a \ --hash=sha256:48f0c8eac16145dfce371e9d2d7772854a4f591bcb56c9cf548accf531d54270 @@ -1770,6 +2017,7 @@ huggingface-hub==0.36.2 \ # datasets # docling # docling-ibm-models + # sentence-transformers # timm # tokenizers # transformers @@ -1781,13 +2029,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.17 \ - --hash=sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0 \ - --hash=sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1803,15 +2051,16 @@ imagesize==2.0.0 \ --hash=sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 \ --hash=sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3 # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via # build # dask -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec + # mlflow-skinny +importlib-resources==7.1.0 \ + --hash=sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708 \ + --hash=sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1 # via happybase iniconfig==2.3.0 \ --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ @@ -1821,9 +2070,9 @@ ipykernel==7.2.0 \ --hash=sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e \ --hash=sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661 # via jupyterlab -ipython==8.38.0 \ - --hash=sha256:750162629d800ac65bb3b543a14e7a74b0e88063eac9b92124d4b2aa3f6d8e86 \ - --hash=sha256:9cfea8c903ce0867cc2f23199ed8545eb741f3a69420bfcf3743ad1cec856d39 +ipython==8.39.0 \ + --hash=sha256:4110ae96012c379b8b6db898a07e186c40a2a1ef5d57a7fa83166047d9da7624 \ + --hash=sha256:bb3c51c4fa8148ab1dea07a79584d1c854e234ea44aa1283bcb37bc75054651f # via # great-expectations # ipykernel @@ -1840,9 +2089,13 @@ isoduration==20.11.0 \ --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 # via jsonschema -jedi==0.19.2 \ - --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ - --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 +itsdangerous==2.2.0 \ + --hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \ + --hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173 + # via flask +jedi==0.20.0 \ + --hash=sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67 \ + --hash=sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011 # via ipython jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1850,6 +2103,7 @@ jinja2==3.1.6 \ # via # feast (pyproject.toml) # altair + # flask # great-expectations # jupyter-server # jupyterlab @@ -1869,9 +2123,9 @@ joblib==1.5.3 \ --hash=sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 \ --hash=sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3 # via scikit-learn -json5==0.13.0 \ - --hash=sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc \ - --hash=sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf +json5==0.14.0 \ + --hash=sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a \ + --hash=sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb # via jupyterlab-server jsonlines==4.0.0 \ --hash=sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74 \ @@ -1881,9 +2135,9 @@ jsonpatch==1.33 \ --hash=sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade \ --hash=sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c # via great-expectations -jsonpointer==3.0.0 \ - --hash=sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 \ - --hash=sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef +jsonpointer==3.1.1 \ + --hash=sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900 \ + --hash=sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca # via # jsonpatch # jsonschema @@ -1908,9 +2162,9 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -jupyter-client==8.8.0 \ - --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ - --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a +jupyter-client==8.9.0 \ + --hash=sha256:23c0c182e1901ffdab96b5a02cb7bc6f0b04524fd7fc43688a14c4ff2308fb77 \ + --hash=sha256:a0efc16adcec2bb6669d2cf91e3ba5337b338bd1ecd0d9c70940752fcb1144b2 # via # ipykernel # jupyter-server @@ -1926,17 +2180,17 @@ jupyter-core==5.9.1 \ # nbclient # nbconvert # nbformat -jupyter-events==0.12.0 \ - --hash=sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb \ - --hash=sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b +jupyter-events==0.12.1 \ + --hash=sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf \ + --hash=sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3 # via jupyter-server -jupyter-lsp==2.3.0 \ - --hash=sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245 \ - --hash=sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f +jupyter-lsp==2.3.1 \ + --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ + --hash=sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6 # via jupyterlab -jupyter-server==2.17.0 \ - --hash=sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5 \ - --hash=sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f +jupyter-server==2.19.0 \ + --hash=sha256:1731236bc32b680223e1ceb9d68209a845203475012ef68773a81434b46a31a7 \ + --hash=sha256:cb76591b76d7093584c2ad2ae72ac3d58614a4b597507a1bb04e1f9f683cf9ea # via # jupyter-lsp # jupyterlab @@ -1947,9 +2201,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.5 \ - --hash=sha256:a35694a40a8e7f2e82f387472af24e61b22adcce87b5a8ab97a5d9c486202a6d \ - --hash=sha256:eac620698c59eb810e1729909be418d9373d18137cac66637141abba613b3fda +jupyterlab==4.5.8 \ + --hash=sha256:7d514c856d0d607601ec7692374da4f26e2aaf3b6e7cd363136b422a50588d6c \ + --hash=sha256:af54d7242cc689a1e6c3ad213cc9b6d9781787d9ec67c52ec9a8f4707088cadd # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -1965,21 +2219,140 @@ jupyterlab-widgets==3.0.16 \ --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 # via ipywidgets -jwcrypto==1.5.6 \ - --hash=sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 \ - --hash=sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039 +jwcrypto==1.5.7 \ + --hash=sha256:70204d7cca406eda8c82352e3c41ba2d946610dafd19e54403f0a1f4f18633c6 \ + --hash=sha256:729463fefe28b6de5cf1ebfda3e94f1a1b41d2799148ef98a01cb9678ebe2bb0 # via python-keycloak -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kiwisolver==1.5.0 \ + --hash=sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9 \ + --hash=sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679 \ + --hash=sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0 \ + --hash=sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8 \ + --hash=sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 \ + --hash=sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96 \ + --hash=sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e \ + --hash=sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac \ + --hash=sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f \ + --hash=sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a \ + --hash=sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15 \ + --hash=sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7 \ + --hash=sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368 \ + --hash=sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02 \ + --hash=sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9 \ + --hash=sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681 \ + --hash=sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57 \ + --hash=sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 \ + --hash=sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4 \ + --hash=sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920 \ + --hash=sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374 \ + --hash=sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 \ + --hash=sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa \ + --hash=sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23 \ + --hash=sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859 \ + --hash=sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb \ + --hash=sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d \ + --hash=sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc \ + --hash=sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581 \ + --hash=sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c \ + --hash=sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099 \ + --hash=sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05 \ + --hash=sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9 \ + --hash=sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd \ + --hash=sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc \ + --hash=sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796 \ + --hash=sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303 \ + --hash=sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca \ + --hash=sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314 \ + --hash=sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489 \ + --hash=sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57 \ + --hash=sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1 \ + --hash=sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797 \ + --hash=sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021 \ + --hash=sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db \ + --hash=sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22 \ + --hash=sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028 \ + --hash=sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083 \ + --hash=sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65 \ + --hash=sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588 \ + --hash=sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0 \ + --hash=sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a \ + --hash=sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1 \ + --hash=sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c \ + --hash=sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac \ + --hash=sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476 \ + --hash=sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53 \ + --hash=sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3 \ + --hash=sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4 \ + --hash=sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615 \ + --hash=sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb \ + --hash=sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18 \ + --hash=sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b \ + --hash=sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1 \ + --hash=sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2 \ + --hash=sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c \ + --hash=sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac \ + --hash=sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d \ + --hash=sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf \ + --hash=sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2 \ + --hash=sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f \ + --hash=sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f \ + --hash=sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4 \ + --hash=sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9 \ + --hash=sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e \ + --hash=sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737 \ + --hash=sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b \ + --hash=sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed \ + --hash=sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3 \ + --hash=sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7 \ + --hash=sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08 \ + --hash=sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e \ + --hash=sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902 \ + --hash=sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd \ + --hash=sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6 \ + --hash=sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310 \ + --hash=sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537 \ + --hash=sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554 \ + --hash=sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e \ + --hash=sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87 \ + --hash=sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a \ + --hash=sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c \ + --hash=sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79 \ + --hash=sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e \ + --hash=sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16 \ + --hash=sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1 \ + --hash=sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875 \ + --hash=sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd \ + --hash=sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0 \ + --hash=sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9 \ + --hash=sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646 \ + --hash=sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657 \ + --hash=sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4 \ + --hash=sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232 \ + --hash=sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819 \ + --hash=sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384 \ + --hash=sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309 \ + --hash=sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede \ + --hash=sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2 \ + --hash=sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203 \ + --hash=sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7 \ + --hash=sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df \ + --hash=sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c \ + --hash=sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167 \ + --hash=sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3 \ + --hash=sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09 \ + --hash=sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398 + # via matplotlib +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.78.1 \ - --hash=sha256:f089b6d75e85b937f99693c93e8c16c0804008672c3dd2a3d25affd36f238100 \ - --hash=sha256:f941db80bf41db33f31df87b304e8b588f8166b813b0257c11c98f7a9d0aac71 +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2191,13 +2564,17 @@ makefun==1.16.0 \ --hash=sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4 \ --hash=sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947 # via great-expectations -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +mako==1.3.12 \ + --hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \ + --hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a + # via alembic +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich -marko==2.2.2 \ - --hash=sha256:6940308e655f63733ca518c47a68ec9510279dbb916c83616e4c4b5829f052e8 \ - --hash=sha256:f064ae8c10416285ad1d96048dc11e98ef04e662d3342ae416f662b70aa7959e +marko==2.2.3 \ + --hash=sha256:8e1d7a0387281e59dfbc52a381b58c570156970e36b2bbe047f8a3a2f368cacc \ + --hash=sha256:e31ec2875383bc62f9093d16babed5a2c2cde601c00d834ea935a2222120ec19 # via docling markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -2290,22 +2667,81 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via + # flask # jinja2 + # mako # nbconvert # werkzeug marshmallow==3.26.2 \ --hash=sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73 \ --hash=sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57 # via great-expectations -matplotlib-inline==0.2.1 \ - --hash=sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76 \ - --hash=sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe +matplotlib==3.10.9 \ + --hash=sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9 \ + --hash=sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42 \ + --hash=sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d \ + --hash=sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b \ + --hash=sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37 \ + --hash=sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b \ + --hash=sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456 \ + --hash=sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc \ + --hash=sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f \ + --hash=sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6 \ + --hash=sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2 \ + --hash=sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4 \ + --hash=sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320 \ + --hash=sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20 \ + --hash=sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf \ + --hash=sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c \ + --hash=sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80 \ + --hash=sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9 \ + --hash=sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716 \ + --hash=sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585 \ + --hash=sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb \ + --hash=sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38 \ + --hash=sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4 \ + --hash=sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2 \ + --hash=sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217 \ + --hash=sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838 \ + --hash=sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4 \ + --hash=sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda \ + --hash=sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb \ + --hash=sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f \ + --hash=sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f \ + --hash=sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f \ + --hash=sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c \ + --hash=sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb \ + --hash=sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b \ + --hash=sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285 \ + --hash=sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294 \ + --hash=sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65 \ + --hash=sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e \ + --hash=sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d \ + --hash=sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f \ + --hash=sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8 \ + --hash=sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39 \ + --hash=sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6 \ + --hash=sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f \ + --hash=sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf \ + --hash=sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2 \ + --hash=sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe \ + --hash=sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99 \ + --hash=sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb \ + --hash=sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8 \ + --hash=sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1 \ + --hash=sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 \ + --hash=sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba \ + --hash=sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358 + # via mlflow +matplotlib-inline==0.2.2 \ + --hash=sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6 \ + --hash=sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79 # via # ipykernel # ipython -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -2316,19 +2752,29 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) minio==7.2.11 \ --hash=sha256:153582ed52ff3b5005ba558e1f25bfe1e9e834f7f0745e594777f28e3e81e1a0 \ --hash=sha256:4db95a21fe1e2022ec975292d8a1f83bd5b18f830d23d42a4518ac7a5281d7c5 # via feast (pyproject.toml) -mistune==3.2.0 \ - --hash=sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a \ - --hash=sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 +mistune==3.2.1 \ + --hash=sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048 \ + --hash=sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28 # via # great-expectations # nbconvert +mlflow==3.13.0 \ + --hash=sha256:7ca9cb2f623f300dabadaf5e985c85af77c5db3d7c36f56769d22c101b132f6c \ + --hash=sha256:a95198d592a8a15fad3db7f56b228acc9422c09f0daa7c6c976a9996ab73c3e2 + # via feast (pyproject.toml) +mlflow-skinny==3.13.0 \ + --hash=sha256:ced3d9a580564fae093d14732df8531fb180574f6483d4c642b6083879eb86fc \ + --hash=sha256:d2273bfa21f776359f7d6ab2267967e3a6732a5fb00996ad433d0e777dfa3b71 + # via mlflow +mlflow-tracing==3.13.0 \ + --hash=sha256:2f8187ce2b1af7419be71d2d8ab5fec53d207d4b8d703cd15e5db64939098d72 \ + --hash=sha256:42c435b0fdcab00f1865cab4a52f7a85a2a08d68a959f36bcf90a1c9fe65db0a + # via mlflow mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -2454,9 +2900,9 @@ mpmath==1.3.0 \ --hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \ --hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c # via sympy -msal==1.35.1 \ - --hash=sha256:70cac18ab80a053bff86219ba64cfe3da1f307c74b009e2da57ef040eb1b5656 \ - --hash=sha256:8f4e82f34b10c19e326ec69f44dc6b30171f2f7098f3720ea8a9f0c11832caa3 +msal==1.37.0 \ + --hash=sha256:1b1672a33ee467c1d70b341bb16cafd51bb3c817147a95b93263794b03971bec \ + --hash=sha256:dd17e95a7c71bce75e8108113438ba7c4a086b3bcad4f57a8c09b7af3d753c2d # via # azure-identity # msal-extensions @@ -2738,13 +3184,13 @@ mypy-protobuf==3.3.0 \ --hash=sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d \ --hash=sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248 # via feast (pyproject.toml) -nbclient==0.10.4 \ - --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ - --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 +nbclient==0.11.0 \ + --hash=sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a \ + --hash=sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895 # via nbconvert -nbconvert==7.17.0 \ - --hash=sha256:1b2696f1b5be12309f6c7d707c24af604b87dfaf6d950794c7b07acab96dda78 \ - --hash=sha256:4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518 +nbconvert==7.17.1 \ + --hash=sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2 \ + --hash=sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8 # via jupyter-server nbformat==5.10.4 \ --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ @@ -2789,9 +3235,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.4 \ - --hash=sha256:860e31782b3d3a25ca0819ff039f5cf77845d1bf30c78ef9528b88b25e0a9850 \ - --hash=sha256:b928b2ba22cb63aa83df2e0e76fe3697950a0c1c4a41b84ebccf1972b1bb5771 +notebook==7.5.7 \ + --hash=sha256:1f95f79d117e47d20b5555b5c85a397d2cfecf136978aaab767cf0314b09165b \ + --hash=sha256:d6d59288a25303b25e1dcb71e9b017ec3a785f7d92f38b9bc288ca1970d5b0a8 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -2859,6 +3305,7 @@ numpy==2.2.6 \ # feast (pyproject.toml) # accelerate # altair + # contourpy # dask # datasets # db-dtypes @@ -2868,6 +3315,8 @@ numpy==2.2.6 \ # great-expectations # ibis-framework # imageio + # matplotlib + # mlflow # opencv-python-headless # pandas # pandas-gbq @@ -2876,7 +3325,9 @@ numpy==2.2.6 \ # scikit-image # scikit-learn # scipy + # sentence-transformers # shapely + # skops # tifffile # torchvision # transformers @@ -2894,131 +3345,171 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.44.1 \ - --hash=sha256:cc121f82cb15dcf5f2f1347bd30d4c83cae1d510809e6ccce111b98298271503 +openlineage-python==1.48.0 \ + --hash=sha256:107f460e5836f5a2d618c3b30f816ee5cd18974c7be899c86cac879a379b54c9 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ --hash=sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050 # via docling -oracledb==3.4.2 \ - --hash=sha256:00c79448017f367bb7ab6900efe0706658a53768abea2b4519a4c9b2d5743890 \ - --hash=sha256:0e16fe3d057e0c41a23ad2ae95bfa002401690773376d476be608f79ac74bf05 \ - --hash=sha256:0f04a2d62073407672f114d02529921de0677c6883ed7c64d8d1a3c04caa3238 \ - --hash=sha256:1617a1db020346883455af005efbefd51be2c4d797e43b1b38455a19f8526b48 \ - --hash=sha256:19fa80ef84f85ad74077aa626067bbe697e527bd39604b4209f9d86cb2876b89 \ - --hash=sha256:1e4930d7f6584832dcc15b8ca415a7957b0c45f5aa7c4f88702e070e5c53bf93 \ - --hash=sha256:23aa07c1eaca17ae74c6fdc86b218f58484d56452958aead1aa460c0596a76c1 \ - --hash=sha256:31b7ee83c23d0439778303de8a675717f805f7e8edb5556d48c4d8343bcf14f5 \ - --hash=sha256:3df8eee1410d25360599968b1625b000f10c5ae0e47274031a7842a9dc418890 \ - --hash=sha256:404ec1451d0448653ee074213b87d6c5bd65eaa74b50083ddf2c9c3e11c71c71 \ - --hash=sha256:46e0f2278ff1fe83fbc33a3b93c72d429323ec7eed47bc9484e217776cd437e5 \ - --hash=sha256:55397e7eb43bb7017c03a981c736c25724182f5210951181dfe3fab0e5d457fb \ - --hash=sha256:574c8280d49cbbe21dbe03fc28356d9b9a5b9e300ebcde6c6d106e51453a7e65 \ - --hash=sha256:59ad6438f56a25e8e1a4a3dd1b42235a5d09ab9ba417ff2ad14eae6596f3d06f \ - --hash=sha256:5d7befb014174c5ae11c3a08f5ed6668a25ab2335d8e7104dca70d54d54a5b3a \ - --hash=sha256:5ed78d7e7079a778062744ccf42141ce4806818c3f4dd6463e4a7edd561c9f86 \ - --hash=sha256:643c25d301a289a371e37fcedb59e5fa5e54fb321708e5c12821c4b55bdd8a4d \ - --hash=sha256:6d85622664cc88d5a82bbd7beccb62cd53bd272c550a5e15e7d5f8ae6b86f1f1 \ - --hash=sha256:9f434a739405557bd57cb39b62238142bb27855a524a70dc6d397a2a8c576c9d \ - --hash=sha256:a7396664e592881225ba66385ee83ce339d864f39003d6e4ca31a894a7e7c552 \ - --hash=sha256:ac25a0448fc830fb7029ad50cd136cdbfcd06975d53967e269772cc5cb8c203a \ - --hash=sha256:b1095d95d0c8b37e4d0e17cf1928919cb59222b6344362a1cf6a2f3ca205a28a \ - --hash=sha256:b26a10f9c790bd141ffc8af68520803ed4a44a9258bf7d1eea9bfdd36bd6df7f \ - --hash=sha256:b8e4b8a852251cef09038b75f30fce1227010835f4e19cfbd436027acba2697c \ - --hash=sha256:b974caec2c330c22bbe765705a5ac7d98ec3022811dec2042d561a3c65cb991b \ - --hash=sha256:d7ce75c498bff758548ec6e4424ab4271aa257e5887cc436a54bc947fd46199a \ - --hash=sha256:d8d75e4f879b908be66cce05ba6c05791a5dbb4a15e39abc01aa25c8a2492bd9 \ - --hash=sha256:e068ef844a327877bfefbef1bc6fb7284c727bb87af80095f08d95bcaf7b8bb2 \ - --hash=sha256:f8ea989965a4f636a309444bd696ab877bba373d5d67bf744785f9bd8c560865 \ - --hash=sha256:f93cae08e8ed20f2d5b777a8602a71f9418389c661d2c937e84d94863e7e7011 \ - --hash=sha256:ff3c89cecea62af8ca02aa33cab0f2edc0214c747eac7d3364ed6b2640cb55e4 +opentelemetry-api==1.42.1 \ + --hash=sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714 \ + --hash=sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716 + # via + # mlflow-skinny + # mlflow-tracing + # opentelemetry-sdk + # opentelemetry-semantic-conventions +opentelemetry-proto==1.42.1 \ + --hash=sha256:c6a51e6b4f05ae63565f3a113217f3d2bfaec68f78c02d7a6c85f9010d1cfca6 \ + --hash=sha256:dedb74cba2886c59c7789b227a7a670613025a07489040050aedff6e5c0fb43c + # via + # mlflow-skinny + # mlflow-tracing +opentelemetry-sdk==1.42.1 \ + --hash=sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d \ + --hash=sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7 + # via + # mlflow-skinny + # mlflow-tracing +opentelemetry-semantic-conventions==0.63b1 \ + --hash=sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9 \ + --hash=sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682 + # via opentelemetry-sdk +oracledb==4.0.1 \ + --hash=sha256:032ca4f558b05f03fa1bef1b04e59ec350ae0b22e6d85c47f4ac62ae98315823 \ + --hash=sha256:03afeda85bec3eca983ebf3ad9910d0f217d99300258366d287e015a041d6c13 \ + --hash=sha256:08e84a6af1b6e5921dba088dd9fc0738927206eafe5ce9763c34195f87556849 \ + --hash=sha256:0d3c6ed987df64b914ece0722692419fe494d07f15bb4d7715adeada4f914c3a \ + --hash=sha256:0ece951553c106a0896c8e1690bcdf69d472761fa65fec9b8152cbce13ab8b81 \ + --hash=sha256:10204432f0eea8707a79c75bdccb84071e43fd19c658cb3b34d1746b12c6e7fe \ + --hash=sha256:20a10f903c8da59e9689a98bd68012f78fa19bed950ad9f19cd8f5b8b97e73a0 \ + --hash=sha256:29ae0ff517a3241060eeee15a321b710c3f83a688cf2da7d5729adbe212e2b00 \ + --hash=sha256:34bbea44423ed8b24093aa859ca7ee9b6e76ea490f9acdc5f6ff01aa1083e343 \ + --hash=sha256:3b5ef1676a27b7e0a7ec55be27fd8f6d28d1601f5e8dfdae78705909f25b7c0a \ + --hash=sha256:416b324cd7715073cf5f3d577330387ffd59741463995c25bdc2d82b3e80b88e \ + --hash=sha256:443b2f03461e873ccd73dff3d8541fcf974c05e13e296a6687ffbb0c4a72c0a1 \ + --hash=sha256:4b42725337f80d433a3bd2928c08667e5b89da9ce05cf9ae3a4189c4fc4805ea \ + --hash=sha256:523b3356cde9d588ba250cefafdfc34869233d65c179f805ea6e4d3d6b209a7f \ + --hash=sha256:5332a4499d61c3cd659ed09bbd0d3c9a4c74a70bd51136d5c3de9127dc6d7434 \ + --hash=sha256:5646c126d4ab506ee2bda261e792f0036231ee929296057e79857ec678d86d4f \ + --hash=sha256:7156ef112a901967b3ee89b6c582bafc5a3082c47ca566de1a79e9ac3b48da32 \ + --hash=sha256:73ba32597fe1da72e0824aaa4b1900ec08a3b77268cb4eb45c733ae7e7043e70 \ + --hash=sha256:7bbe5611f9196f0ec15d4bf838ec728d89586a962a20d65cad898aec020e11c4 \ + --hash=sha256:7db5a43c29a23ed23923a29816c65c7a81fe00f2abfe6bf36d83ad952abd9b89 \ + --hash=sha256:8159c5bd8f25b0ca0ce30f21e7a732a2bdfb4adb81b9c8ea1ca75339d8ec8398 \ + --hash=sha256:828dd4c981b286f0467feab1c035fae8d3888cfdc707706841734821877ae1f3 \ + --hash=sha256:86a06d0afb3bb3a24bace0e72fb9abca2093efe0fa3457c65c13ba4eb5000b0b \ + --hash=sha256:86ac65cbc8d29626b1d9d203f9151566c26a78e55bdfc030c06169ae8017f458 \ + --hash=sha256:873fcca53306e2b3b445a7d657cddc19e415a7aa7e392c473dfd1a3ae3970989 \ + --hash=sha256:8e13ff1e6f28fdb863180d23fa94cb42c619c29d2981e24992431e51b97caa54 \ + --hash=sha256:8fcad6d9628923281bf21e48a391ac2f87ec6950dc63381d8fea470e3128aef0 \ + --hash=sha256:90586b3c7729b9cf3d40df902e81257f01e15e3408d8b6b9dbf91e939b64f72c \ + --hash=sha256:9f521b3f3f14fa9b8e748aeb79b064ae6767fcb0e8ff969a9aba7a852f059658 \ + --hash=sha256:a029dcee759bca56a8c95e952040c3d3f57e5ec05965355293b21930a66967fb \ + --hash=sha256:ae894ca2705929eb0ac228329336fd03388ad6e3b54002be6f5d4400a8feaf52 \ + --hash=sha256:b05bfadbfe462c39cc97258a973972f5bbbc9f8e2e9a4c2e0efcb1ec86b91088 \ + --hash=sha256:b09eec35681d72c9476e6d715b89bb775724a31e7363df6beba7470494ea8040 \ + --hash=sha256:b73820521eccd290506af94e1ffb9a8a5941b4018e3861df9b040652a7cef123 \ + --hash=sha256:c05a01d6ad610a88c2aa1a43b1dc0a8485f5fbd4374d2b36908859d4205de192 \ + --hash=sha256:c24b174aac8163065736072a726a50091791f6d30ac5c44965cf7044e86fbaf8 \ + --hash=sha256:c2d394453f669858bec942ff0da18b6ebade296ece823d582ad2b464ed5c6c90 \ + --hash=sha256:cb7727f93ff962ab826bc3d0bca4b0e5bf45ecb7c525551c70c9e094f0f27027 \ + --hash=sha256:ce3f25552fe58df5c266874f8b13f0a8ab7fcd09ab4b476bc15520a67527ca4b \ + --hash=sha256:ce6319ee01dcbb4d74f0e2a5794c6a566f339958ecac9830c67c7070521620e2 \ + --hash=sha256:cf61e42b9ef723dbdd0b23032b695e872009ed7341003df59d9a97cd960df977 \ + --hash=sha256:d132af7d95474d207632363575c7968b09e2d33dd24af3a36f539254433f4ae8 \ + --hash=sha256:d7cd278d59780e22e0a7451d208460756d779dc62b55bdbd95652f9640fbf8c3 \ + --hash=sha256:dbe8b44fea57385617838f2acfce8cc19f6c95cd9e65e7235e86b5932af1acd9 \ + --hash=sha256:e36581bb10e719d928dad12018c2d42606db2c34f49d6665b06f701f049255f0 \ + --hash=sha256:e3d54b624748cfe42248c4bc62c3f788632a2077058485a9acb3150312b1c396 \ + --hash=sha256:e4926e699a42c526137724960fa4303ecb0b542186b11d3705ac84414a896508 # via ibis-framework -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 # via - # feast (pyproject.toml) + # pymilvus # trino overrides==7.7.0 \ --hash=sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a \ --hash=sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 # via jupyter-server -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # accelerate # build @@ -3039,6 +3530,9 @@ packaging==26.0 \ # jupyterlab-server # lazy-loader # marshmallow + # matplotlib + # mlflow-skinny + # mlflow-tracing # nbconvert # openlineage-python # pandas-gbq @@ -3046,6 +3540,7 @@ packaging==26.0 \ # ray # safetensors # scikit-image + # skops # snowflake-connector-python # sphinx # transformers @@ -3117,6 +3612,7 @@ pandas==2.3.3 \ # google-cloud-bigquery # great-expectations # ibis-framework + # mlflow # pandas-gbq # pymilvus # snowflake-connector-python @@ -3132,9 +3628,9 @@ parsimonious==0.11.0 \ --hash=sha256:32e3818abf9f05b3b9f3b6d87d128645e30177e91f614d2277d88a0aea98fae2 \ --hash=sha256:e080377d98957beec053580d38ae54fcdf7c470fb78670ba4bf8b5f9d5cad2a9 # via singlestoredb -parso==0.8.6 \ - --hash=sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd \ - --hash=sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff +parso==0.8.7 \ + --hash=sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c \ + --hash=sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1 # via jedi parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -3267,12 +3763,13 @@ pillow==11.3.0 \ # docling-parse # easyocr # imageio + # matplotlib # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1.2 \ + --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ + --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3304,6 +3801,10 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) +prettytable==3.17.0 \ + --hash=sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0 \ + --hash=sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 + # via skops prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 @@ -3314,154 +3815,153 @@ prompt-toolkit==3.0.52 \ --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 # via ipython -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==4.25.8 \ - --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ - --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ - --hash=sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af \ - --hash=sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0 \ - --hash=sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd \ - --hash=sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0 \ - --hash=sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7 \ - --hash=sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9 \ - --hash=sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f \ - --hash=sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3 \ - --hash=sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24 +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) + # databricks-sdk # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable @@ -3473,7 +3973,10 @@ protobuf==4.25.8 \ # grpcio-status # grpcio-testing # grpcio-tools + # mlflow-skinny + # mlflow-tracing # mypy-protobuf + # opentelemetry-proto # proto-plus # pymilvus # qdrant-client @@ -3515,80 +4018,70 @@ psutil==5.9.0 \ # feast (pyproject.toml) # accelerate # ipykernel -psycopg[binary, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[binary, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-binary==3.2.5 \ - --hash=sha256:02fb96091e2fb3ea1470b113fef08953baaedbca1d39a3f72d82cb615177846c \ - --hash=sha256:11e3ed8b94c750d54fc3e4502dd930fb0fd041629845b6a7ce089873ac9756b0 \ - --hash=sha256:1494827c43265820d5dcdc6f8086521bc7dd04b9da8831310978a788cdcd2e62 \ - --hash=sha256:21b839f9bfd77ed074f7f71464a43f453400c57d038a0ba0716329a28e335897 \ - --hash=sha256:23a1dc61abb8f7cc702472ab29554167a9421842f976c201ceb3b722c0299769 \ - --hash=sha256:274e852f9e61252bc8e80a0a43d300ba352d40219e856733054023a3bb960eb4 \ - --hash=sha256:28bd5cb2324567e5e70f07fe1d646398d6b0e210e28b49be0e69593590a59980 \ - --hash=sha256:2b053eae21dd3a6828b516a1171e1274d1af5f7c07d2d9a8f597f2e19c732168 \ - --hash=sha256:2cbb8649cfdacbd14e17f5ab78edc52d33350013888518c73e90c5d17d7bea55 \ - --hash=sha256:2cc86657c05e09c701e97f87132cd58e0d55381dd568520081ac1fe7580a9bbb \ - --hash=sha256:2d10ce4c39eb9631381a0c3792727946a4391e843625a7ee9579ac6bb11495a5 \ - --hash=sha256:2d22a15e45f43d36ed35aed4d5261f8ef6ab7d9b84ee075576ca56ae03b9e0aa \ - --hash=sha256:2dbaf32c18c0d11c4480016b89c9c5cadb7b64c55de7f181d222b189bd13a558 \ - --hash=sha256:32b5673736f04c36ccbf8012800fe5bc01b46dac22c5d59e41b043bebaad9d3d \ - --hash=sha256:375149006e21d58ed8aba640e0295d8e636043064c433af94eb58057f9b96877 \ - --hash=sha256:393ab353196d364858b47317d27804ecc58ab56dbde32217bd67f0f2f2980662 \ - --hash=sha256:39e2cd10bf15442d95c3f48376b25dc33360418ea6c3c05884d8bf42407768c0 \ - --hash=sha256:3d2e57a1d06f3968e49e948ba374f21a7d8dcf44f37d582a4aeddeb7c85ce239 \ - --hash=sha256:3eb71cfc35116e4a8e336b7e785f1fe06ca23b4516a48ea91facd577d1a1fdf6 \ - --hash=sha256:3f893c0ed3d5c7b83b76b1f8f7d3ca5a03e38bcd3cab5d65b5c25a0d1064aca4 \ - --hash=sha256:473f6827cf1faf3924eb77146d1e85126a1b5e48a88053b8d8b78dd29e971d78 \ - --hash=sha256:48f97936145cb7de18b95d85670b2d3e2c257277263272be05815b74fb0ef195 \ - --hash=sha256:48fcb12a0a72fdfe4102bdb1252a7366e8d73a2c89fe6ce5923be890de367c2f \ - --hash=sha256:4914dc60f2fddf0884464985e31d775aa865b665471fa156ec2f56fa72a1a097 \ - --hash=sha256:51a96d9fe51f718912b4a0089784f1f32d800217499fd0f0095b888506aba4c5 \ - --hash=sha256:5244bebaa9734a236b7157fb57c065b6c0f2344281916187bd73f951df1899e0 \ - --hash=sha256:5b81342e139ddccfa417832089cd213bd4beacd7a1462ca4019cafe71682d177 \ - --hash=sha256:5d2253189aa4cca0a425e2ca896d1a29760cd3a2b10ab12194e4e827a566505c \ - --hash=sha256:5fd017d7ed71c58f19b0f614e7bfb8f01ec862bacb67ae584f494d090956102e \ - --hash=sha256:605f70e267222d567fc40de7813ee3fb29f8145a1a20aa6fd3dc62baba9312f1 \ - --hash=sha256:60d0f36a42a822e43c4c7472df8a0c980c0f32e5d74ed871333c423a4e942f11 \ - --hash=sha256:62965045cc0fe3dc5dd55d39779620b225ef75962825c7b1b533033cb91810bd \ - --hash=sha256:65162a9cc3f86d70b1d895dbda506e3c079f80d082eb41c54d3f6d33a00b3965 \ - --hash=sha256:659f2c675d478b1bc01b95a8d3ded74fa939b370e71ffbecd496f617b215eb05 \ - --hash=sha256:6b581da13126b8715c0c0585cd37ce934c9864d44b2a4019f5487c0b943275e6 \ - --hash=sha256:71d82dbc7c6c7f5746468e7992e5483aa45b12250d78d220a2431ab88795825c \ - --hash=sha256:7376b13504396da9678b646f5338462347da01286b2a688a0d8493ec764683a2 \ - --hash=sha256:7623659d44a6aa032be4a066c658ba45009d768c2481526fbef7c609702af116 \ - --hash=sha256:7a94020821723a6a210206ddb458001f3ed27e1e6a0555b9422bebf7ead8ff37 \ - --hash=sha256:7d5f1bfc848a94e0d63fe693adee4f88bd9e5c415ecb4c9c17d2d44eba6795a6 \ - --hash=sha256:7efe6c732fd2d7e22d72dc4f7cf9b644020adacfff61b0a8a151343da8e661c0 \ - --hash=sha256:8a602d9fdb567cca090ca19ac3ebf10219065be2a4f8cf9eb8356cffb5a7ab1d \ - --hash=sha256:8cd9ebf335262e864d740f9dad3f672f61162cc0d4825a5eb5cf50df334a688f \ - --hash=sha256:8e6f2bef5aed021fbdf46323d3cd8847bf960efb56394698644a8ee2306f8892 \ - --hash=sha256:93221d5a759bd39b1face1d7d887d2b9ede3e55aefaff8eacf1b663ccdcd204b \ - --hash=sha256:9639289b72f9339721982e156527c296693236d6192ccc31412ab36fccd1683c \ - --hash=sha256:98efaedf2bf79f4d563ca039a57a025b72847bd80568f54709cc39fc1404772c \ - --hash=sha256:9abe093a303e25ac58774a11241150e2fe2947358d1ca12521ad03c90b131060 \ - --hash=sha256:a4321ee8180982d70458d3e8378e31448901bf0ee40fe0d410a87413578f4098 \ - --hash=sha256:a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed \ - --hash=sha256:a91b0e096fdfeb52d86bb8f5ee25dc22483d6960af9b968e6b381a8ec5bfbf82 \ - --hash=sha256:b5e0acbc991472188c9df40eb56d8a97ad3ad00d4de560b8b74bdc2d94041a8f \ - --hash=sha256:b6b5a4542aca4095ab35e184517cb0d18895ba4b6661c92865b431fa7b7974d8 \ - --hash=sha256:ba4a610882171bdaae0779f14e0ff45f3ee271fd2dbf16cdadfc81bd67323232 \ - --hash=sha256:bc5bd9bf5f5894923b78a41c5becd52d6bced1e1e43744855bd85cb341376ca6 \ - --hash=sha256:c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 \ - --hash=sha256:c3c5fa3d4fa0a651cefab391b783f89bc5e331afa0a4e93c9b16141993fa05c8 \ - --hash=sha256:ca5e36a3e7480a5c09aed99ecdb8e6554b21485c3b064297fe77f7b1b5806106 \ - --hash=sha256:d4e0c1b1aa5283f6d9a384ffc7a8400d25386bb98fdb9bddae446e4ef4da7366 \ - --hash=sha256:dc8bc40d82d1ee8dec136e10707c7f3147a6322fd8014e174a0f3446fb793649 \ - --hash=sha256:de576c49d7deab2b78088feb24e1f6ae3e16a0020e8496cdd3b8543f5e350e87 \ - --hash=sha256:e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 \ - --hash=sha256:eb8293d66c6a4ddc72fceb7ad0e111cb196cc394954ae0f9b63c251d97f1b00e \ - --hash=sha256:ee6d8f489a9b116ea8dc797664a50671585a4ca20573359f067858e1231cc217 \ - --hash=sha256:efb878d08dd49d7d9d18512e791b418a1171d08f935475eec98305f0886b7c14 +psycopg-binary==3.3.4 \ + --hash=sha256:018fbed325936da502feb546642c982dcc4b9ffdea32dfef78dbf3b7f7ad4070 \ + --hash=sha256:0579252a1202cd73e4da137a1426e2dae993ae44e757605344282af3a082848c \ + --hash=sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc \ + --hash=sha256:13a7f380824c35896dcac7fe0f61440f7ca49d6dc73f3c13a9a4471e6a3b302e \ + --hash=sha256:17a21953a9e5ff3a16dab692625a3676e2f101db5e40072f39dbee2250194d68 \ + --hash=sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae \ + --hash=sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829 \ + --hash=sha256:22cdbf5f91ef7bb91fe0c5757e1962d3127a8010256eefd9c61fcaf441802097 \ + --hash=sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c \ + --hash=sha256:276904e3452d6a23d474ef9a21eee19f20eed3d53ddd2576af033827e0ba0992 \ + --hash=sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97 \ + --hash=sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6 \ + --hash=sha256:32a6fbf8481e3a370d0d72b860d35948a693cb01281da217f7b2f307636e591a \ + --hash=sha256:41f2ec0fea529832982bcb6c9415de3c86264ebe562b77a467c0fbcd7efbba8d \ + --hash=sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228 \ + --hash=sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e \ + --hash=sha256:494ca54901be8cf9eb7e02c25b731f2317c378efa44f43e8f9bd0e1184ae7be4 \ + --hash=sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41 \ + --hash=sha256:574ea21a9651958f1535c5a1c649c7409e9168bcbffa29a3f2f961f58b322949 \ + --hash=sha256:580ae30a5f95ccd90008ec697d3ed6a4a2047a516407ad904283fa42086936e9 \ + --hash=sha256:5ab28a2a7649df3b72e6b674b4c190e448e8e77cf496a65bd846472048de2089 \ + --hash=sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf \ + --hash=sha256:612a627d733f695b1de1f9b4bd511c15f999a5d8b915d444bbd7dd71cf3370da \ + --hash=sha256:6402a9d8146cf4b3974ded3fd28a971e83dc6a0333eb7822524a3aa20b546578 \ + --hash=sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014 \ + --hash=sha256:71e55ccbdfae79a2ed9c6369c3008a3025817ff9d7e27b32a2d84e2a4267e66e \ + --hash=sha256:7465bfe6087d2d5b42d4c53b9b11ca9f218e477317a4a162a10e3c19e984ba8e \ + --hash=sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31 \ + --hash=sha256:773d573e11f437ce0bdb95b7c18dc58390494f96d43f8b45b9760436114f7652 \ + --hash=sha256:77df19583501ea288eaf15ac0fe7ad01e6d8091a91d5c41df5c718f307d8e31b \ + --hash=sha256:7f7668f30b9dd5163197e5cbf4e0efd54e00f0a859cc566ce56cfc31f4054839 \ + --hash=sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277 \ + --hash=sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7 \ + --hash=sha256:ab8cca8ef8fb1ccf5b048ae5bd78ba55b9e4b5d472e3ce5ca39ff4d2a9c249e4 \ + --hash=sha256:ad3bc94054876155549fdaedf4a46d1ec69d39a5bcee377148afe498e84c4b8e \ + --hash=sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70 \ + --hash=sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf \ + --hash=sha256:b7bfff1ca23732b488cbca3076fc11bc98d520ee122514fdb17a8e20d3338f5a \ + --hash=sha256:bdef84570ebbce1d42b4e7ea952d21c414c5f118ad02fee00c5625f35e134429 \ + --hash=sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8 \ + --hash=sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3 \ + --hash=sha256:cf7f73a4a792bc5db58a4b385d8a1467e8d468f7548702fb0ed1e9b7501b1c13 \ + --hash=sha256:cffc3408d77a27973f33e5d909b624cce683db5fc25964b02fe0aae7886c1007 \ + --hash=sha256:d7b4d40c153fa352ab3cca530f3a0baedf7621b2ebcbd7f084009522c21788fc \ + --hash=sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38 \ + --hash=sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9 \ + --hash=sha256:e2631da29253a98bd496e6c4813b24e09a4fe3fb2a9e88513305d6f8747cce95 \ + --hash=sha256:e7510c37550f91a187e3660a8cc50d4b760f8c3b8b2f89ebc5698cd2c7f2c85d \ + --hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \ + --hash=sha256:eb4eed2079c01a4850bf467deacfab56d356d4225040170af03dc9958321242d \ + --hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \ + --hash=sha256:f80e3f2b5331dbbf0901bcb658056c03eeb2c1ef31d774afb0d61598b242e744 \ + --hash=sha256:f9b1c2533af01cd7648378599f82b0b8ae32f293296e6eec5753a625bc97ef28 \ + --hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \ + --hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg ptyprocess==0.7.0 \ --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ @@ -3612,57 +4105,57 @@ py4j==0.10.9.9 \ --hash=sha256:c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 \ --hash=sha256:f694cad19efa5bd1dee4f3e5270eb406613c974394035e5bfc4ec1aba870b879 # via pyspark -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -3671,18 +4164,17 @@ pyarrow==23.0.1 \ # deltalake # google-cloud-bigquery # ibis-framework + # mlflow # pandas-gbq # snowflake-connector-python pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -3776,9 +4268,9 @@ pycryptodome==3.23.0 \ --hash=sha256:e3f2d0aaf8080bda0587d58fc9fe4766e012441e2eed4269a77de6aea981c8be \ --hash=sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7 # via minio -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # dbt-artifacts-parser @@ -3790,145 +4282,147 @@ pydantic==2.12.5 \ # fastapi-mcp # great-expectations # mcp + # mlflow-skinny + # mlflow-tracing # pydantic-settings # qdrant-client -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # ipython @@ -3936,9 +4430,9 @@ pygments==2.19.2 \ # nbconvert # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp @@ -3948,9 +4442,82 @@ pyjwt[crypto]==2.11.0 \ pylatexenc==2.10 \ --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 # via docling -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 + # via feast (pyproject.toml) +pymongo==4.17.0 \ + --hash=sha256:0ff6bd2f735ab5356541e3e57d5b7dbfbc3f2ee1ccb10b6b0f82d58af69d1d8e \ + --hash=sha256:1175563375d682260f613a96fb7a53dce746ed752bfd924eab61de3bc5bfde34 \ + --hash=sha256:1195370a77baf003b59b10e91ecc4706297197f0dd9d29c840cc556dc08f7cee \ + --hash=sha256:12c4fded3a9f1d6a687e36ebd384ac6d00b9b00de1969aa74048e7051ec2a713 \ + --hash=sha256:15d3f3d732aecac1f8d481bde4029755615639bd3076f258a2147210aec8515a \ + --hash=sha256:20323b0b1c1d33770ad1fc68d429c757734ce9ad3594421c3d6618f10572b1b9 \ + --hash=sha256:2a0d5ac205728c86e0a02192f1aa5f865b0d7d51f8df6101c01a69a7fc620d72 \ + --hash=sha256:2db66aa8dd253a0fc1fad3b0d23d5b3993f7ebde02fbbd7727128debf2853675 \ + --hash=sha256:2e190827834fce70ecdf9d46796c6dbc0ce08ea87dc2ff5bc6f3f5579b605cb9 \ + --hash=sha256:320b34457b20bbcc79997801f95d25ce00472915ca5241167242b42c4359e027 \ + --hash=sha256:3689ea34f6b647c7d1e7bdc60fcfb214b2789ed1359a7fb96569c69f50e5f18f \ + --hash=sha256:37a8385c29881b43eab31f584100fa0eaddedd5607adf010147ba1810118be90 \ + --hash=sha256:3987e96e7c7be4083d42e8ac2cc6c0d5b78db9973c90fce42ae800b616ca6b20 \ + --hash=sha256:4141e6c6a339789b2974efa00ecd9409101672d77a0e3ee2cc3839eedf8ec4df \ + --hash=sha256:422fa50d7d7f5c22ea0953554396c9ef95684a2d775f860bd75a7b510538dfca \ + --hash=sha256:47b021363cd923ace5edc7a1d63c0ff8a6d9d43859b8a1ba23645f5afae63221 \ + --hash=sha256:485c8a8eaa4c739f00a331fc73757898ee7c092c214a79e63866ff76aaf282ff \ + --hash=sha256:48bbc576677b50af043df870d84ded67cc3a9b4aa7553201beef4da5dc050a0a \ + --hash=sha256:4ae22fafca69dd3c78261969e999782ac5fc23b76cf8cccfbc3707982a74cc3d \ + --hash=sha256:50e8f8e23c6df7c6d6929f5e734980b227706e73ee847517c9ba5af90f7fc466 \ + --hash=sha256:51e1915761f65f2aaabd0ba691a31d56551d3f19d1263c2d6bf261730603de5f \ + --hash=sha256:5376ad67bb30ae910d83affcf997f706d9dee37e8b5dad8b6fedb0626e262d85 \ + --hash=sha256:5960519b4d7168f1ecdd3ea10c81b2aedeb9423651aca953cfbc8e76705d3b38 \ + --hash=sha256:5a5de048e6da5c18e27cc2437e8c15b3b0cdc8385c15b41178b0caa3322a09c2 \ + --hash=sha256:5ab3b8ff79e0dfc49b68f3c925e8cc735ea95c60efaed84cfe75692dffcaac2a \ + --hash=sha256:64837adbbd72073301af51bb0fc80e3d7707fe5527cea1033ba0320f0b2f881b \ + --hash=sha256:6877214bff5f06f6884a9fc8d9016a4a7a5f51f537f5c51ac3a576f93e7dfb32 \ + --hash=sha256:68fca71e05ee5da23a8d73cee8379dfb3d26e609a377cae731d742771ed96946 \ + --hash=sha256:6c5f62862d0f87be481fa1fe8cb811994486773c94a2b61e509285e3f2890763 \ + --hash=sha256:6fe0de9d0f6791abce3471230b32b4817bf89d27b1182b6a550e1ec0fa72aa9a \ + --hash=sha256:70ffa08ba641468cc068cf46c06b34f01a8ce3489f6411309fcb5ceabe6b2fc0 \ + --hash=sha256:757f2a4c0c2c46cab87df0333681ce69e86c9d5b45bc5203ceba5410b3489e59 \ + --hash=sha256:75bc3aa5b94fdb7138d357ec6ca61cd97e0c79f4f7f0bd3efe9639b15cc50942 \ + --hash=sha256:77aa4bc164b4de60d5db193b322f0f5b6ead716e831031bfdef8e8bd92205556 \ + --hash=sha256:7db10678814cdf7ea39fd308c6f41395cfa7b29d904bcd7895288963d8f892ba \ + --hash=sha256:809ec74de3b9148ae43fa8df9faf53470f511c8d384f13b99d6f671f2a379f15 \ + --hash=sha256:8446ff4bfcb6ec2a2e50998c860986a1e992136f998b7f53e7a717fb8aa5a0b9 \ + --hash=sha256:8a1be016198a03fd7727cdd55998964bfa4e5a6fd9733c8e95830628cef34d29 \ + --hash=sha256:8e97e03fa13327c87e3fdc5656acd01e71817f0c1dc3221cd8f30de136bf4ec3 \ + --hash=sha256:93641192644fa1ee0f34030e774fd31022a27ad11ba22cb1716142231524f8bd \ + --hash=sha256:9543d8f84c2e5608565c08ac679774811e6730770d8a645439b073422a4276fb \ + --hash=sha256:9828485f72f63c7d802e0ec41f71906f633c2692621ab3af55ca990186b091b1 \ + --hash=sha256:9eb5d63a3c518cb0804ed678f5e2b875af032d89a7cf57a57360322cf6a4d222 \ + --hash=sha256:a431b737816bf4cddd4fa0fcef04e424ad36b7692734a64150f872fb8f3208be \ + --hash=sha256:a8f9c40a09bb7d4b9fc8b1da65ecf6efa79bda5cb2756f39d9b6940fac1d19ae \ + --hash=sha256:addd0498ebbdc6354227f6ed457ed9fce442d48a3bb30d5b5bad33e104996561 \ + --hash=sha256:b24598dc3c2feccbc83b43044be48145a0dc4f9bee49ef923e3d707d54a55d85 \ + --hash=sha256:b2dfcc795f5b9fedbe179a11fdf6051581479d196582a3fe819a92a00e9b9969 \ + --hash=sha256:b4384700cffc3f1dd98e088bc0072dedf6d7d68a230bb4b972665cf69c071c1e \ + --hash=sha256:b93b22eedc62598cf5ee9d8c8007a8e9121c50fd88137012d8985500e9dc3151 \ + --hash=sha256:ba2195d4f386f839a52a23ea1cfd60ffaaba78a3d7841db51b7e433001139918 \ + --hash=sha256:bb3ebc86782049f6928dcc583008287cb1c17d463501c94a620f035f5b4fd463 \ + --hash=sha256:bd835cdb37a1adec359dd072c24f8bb14809e2644fde86fab4ee2fc9719b9483 \ + --hash=sha256:c2292144505fb12156b981bd440f3dc994a883da06ac726c0c8692ccdbc1c510 \ + --hash=sha256:c4979e7e8887862bbb44d203f00cc8263a3f27237876fa691b6beba23e40e6d8 \ + --hash=sha256:c5c8e180cb2cabe37300e1e36c60aa4f2ff956cc579f0142135a5d2cba252243 \ + --hash=sha256:c797f8a80957134f6dd9690367a0f8f5906d672119af2c6aa55f0c527b656bed \ + --hash=sha256:c9786665926a09630c5d420c79762cfadbff35a9438bcbc4c81a9fb5ab9228b7 \ + --hash=sha256:cee36b3c0d0354f880fa7a7fdcdaf2bb5e542c2281e25c1bfadf8cfe21eba7d2 \ + --hash=sha256:d53ffa94b2340dbf6b055e09a0090618c60482c158ecfc9565642fc996bf0944 \ + --hash=sha256:df4a644af9ae132d4bfdb2e9516ea51a615fd881caddfbfbd071cf1354844479 \ + --hash=sha256:dff3de1294fbbc1db0ba6b511f77b8e540601d092538a31312e99c8a91a78b1e \ + --hash=sha256:e46767f28dea610e02edf6c5d956ce615c3c7790ea396660b9b1efd5c5ead2e0 \ + --hash=sha256:e4fab10f8403169ce92f3cea921609d9ee81107306caae06c08f592d4b8ad2b5 \ + --hash=sha256:e537e95514dae1aaa718f481ec03151a0f0394bcd05f1322896d8fc1330cb729 \ + --hash=sha256:e68c76b84e0c132d9dbf9307f12ff8185702328187a87b9aca8c941303873433 \ + --hash=sha256:e816db649ba5d7de0568cf3a9f287a9dc9aad21cf0ca667ab156a7ef47fca0b0 \ + --hash=sha256:f09645e0ce4e3825fa0baa8254064a716ed0be33f78feeedd4731016cb8aaa17 \ + --hash=sha256:f3ee3d241ed77a4fc99ce3cff3b289c3ebce37f61fdd7349d3592c23b82c8784 \ + --hash=sha256:faf03e4c2aafd6de626dbd30ba246d369ae33f47f10629d1bbe40f72115027a6 \ + --hash=sha256:ff5aa3f1c7e3f08eb0e7a016c91ba468b1850ccfd63d9b1f12f56350f4974cef # via feast (pyproject.toml) pymssql==2.3.2 \ --hash=sha256:06883bc9bdb297ae9132d9371b5b1a3a223c8f93dd6a87d1c112c6a688f26d53 \ @@ -4012,9 +4579,9 @@ pymssql==2.3.2 \ --hash=sha256:fb8a7b197aaf466a7577ca6690aa9d747081b653ab212d052d71f3cc10587c3b \ --hash=sha256:fdd774b26407babd0205ef85a098f90553e6b3da77a22322a1e7d2cb51f742c0 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) pyodbc==5.3.0 \ --hash=sha256:01166162149adf2b8a6dc21a212718f205cabbbdff4047dc0c415af3fd85867e \ @@ -4084,14 +4651,16 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==25.1.0 \ - --hash=sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab \ - --hash=sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ --hash=sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc - # via great-expectations + # via + # great-expectations + # matplotlib pypdfium2==4.30.0 \ --hash=sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e \ --hash=sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29 \ @@ -4113,8 +4682,8 @@ pyproject-hooks==1.2.0 \ # via # build # pip-tools -pyspark==4.1.1 \ - --hash=sha256:77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec +pyspark==4.1.2 \ + --hash=sha256:fa5d6159f700d0990a07f4f62df1b7449401dccee9cd7d5d6df8957530841602 # via feast (pyproject.toml) pytest==7.4.4 \ --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ @@ -4138,9 +4707,9 @@ pytest-benchmark==3.4.1 \ --hash=sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809 \ --hash=sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47 # via feast (pyproject.toml) -pytest-cov==7.0.0 \ - --hash=sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1 \ - --hash=sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861 +pytest-cov==7.1.0 \ + --hash=sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2 \ + --hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 # via feast (pyproject.toml) pytest-env==1.1.3 \ --hash=sha256:aada77e6d09fcfb04540a6e462c58533c37df35fa853da78707b17ec04d17dfc \ @@ -4167,112 +4736,146 @@ pytest-xdist==3.8.0 \ --hash=sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 \ --hash=sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1 # via feast (pyproject.toml) -python-bidi==0.6.7 \ - --hash=sha256:01ff2fd676ef8351f32e820b2d3b61eac875a21702d2118263a2641b458e1996 \ - --hash=sha256:05fe5971110013610f0db40505d0b204edc756e92eafac1372a464f8b9162b11 \ - --hash=sha256:06650a164e63e94dc8a291cc9d415b4027cb1cce125bc9b02dac0f34d535ed47 \ - --hash=sha256:0cb75e8a410166fd677d55095e505bf6a4773c066f51efbda72d302ebc56e79b \ - --hash=sha256:0dbb4bbae212cca5bcf6e522fe8f572aff7d62544557734c2f810ded844d9eea \ - --hash=sha256:0f86e447e94ae78db7d56e7da2124c435eaee4425c87d3d92aea271317811112 \ - --hash=sha256:11c51579e01f768446a7e13a0059fea1530936a707abcbeaad9467a55cb16073 \ - --hash=sha256:1395e236c71f11267860b53293a33b19b991b06e0f4ac61045b892e6a99d96f2 \ - --hash=sha256:17572944e6d8fb616d111fc702c759da2bf7cedab85a3e4fa2af0c9eb95ed438 \ - --hash=sha256:19737d217088ef27014f98eac1827c5913e6fb1dea96332ed84ede61791070d9 \ - --hash=sha256:1ba28642928d1c8fdb18b0632fe931f156e888c646326a3ad8eb3e55ee904951 \ - --hash=sha256:1c061207212cd1db27bf6140b96dcd0536246f1e13e99bb5d03f4632f8e2ad7f \ - --hash=sha256:1c5fb99f774748de283fadf915106f130b74be1bade934b7f73a7a8488b95da1 \ - --hash=sha256:1dd0a5ec0d8710905cebb4c9e5018aa8464395a33cb32a3a6c2a951bf1984fe5 \ - --hash=sha256:24388c77cb00b8aa0f9c84beb7e3e523a3dac4f786ece64a1d8175a07b24da72 \ - --hash=sha256:24a4a268289bbe80ad7da3064d7325f1571173859e8ad75d2f99075d5278b02b \ - --hash=sha256:24afff65c581a5d6f658a9ec027d6719d19a1d8a4401000fdb22d2eeb677b8e3 \ - --hash=sha256:257d6dd0e07221f1dc8720fa61158471f5aae30d5f89837c38a026386151c250 \ - --hash=sha256:26a8fe0d532b966708fc5f8aea0602107fde4745a8a5ae961edd3cf02e807d07 \ - --hash=sha256:2a93b0394cc684d64356b0475858c116f1e335ffbaba388db93bf47307deadfa \ - --hash=sha256:2d28e2bdcadf5b6161bb4ee9313ce41eac746ba57e744168bf723a415a11af05 \ - --hash=sha256:349b89c3110bd25aa56d79418239ca4785d4bcc7a596e63bb996a9696fc6a907 \ - --hash=sha256:3a85275dfc24a96629da058c4c2fc93af6390aefe2f7cdde1500b6ac3fd40ca0 \ - --hash=sha256:3b63d19f3f56ff7f99bce5ca9ef8c811dbf0f509d8e84c1bc06105ed26a49528 \ - --hash=sha256:3b96744e4709f4445788a3645cea7ef8d7520ccd4fa8bbbfb3b650702e12c1e6 \ - --hash=sha256:414004fe9cba33d288ff4a04e1c9afe6a737f440595d01b5bbed00d750296bbd \ - --hash=sha256:4283f8b517411cc81b3c92d11998981fe54ac0d2300f4c58d803e0c071aba1ba \ - --hash=sha256:4636d572b357ab9f313c5340915c1cf51e3e54dd069351e02b6b76577fd1a854 \ - --hash=sha256:47deaada8949af3a790f2cd73b613f9bfa153b4c9450f91c44a60c3109a81f73 \ - --hash=sha256:49639743f1230648fd4fb47547f8a48ada9c5ca1426b17ac08e3be607c65394c \ - --hash=sha256:4c73cd980d45bb967799c7f0fc98ea93ae3d65b21ef2ba6abef6a057720bf483 \ - --hash=sha256:4d84e70923392f8c9611f0fb6b341577346ef6224f3809b05f0ae1fbf8f17578 \ - --hash=sha256:4ea928c31c7364098f853f122868f6f2155d6840661f7ea8b2ccfdf6084eb9f4 \ - --hash=sha256:5013ba963e9da606c4c03958cc737ebd5f8b9b8404bd71ab0d580048c746f875 \ - --hash=sha256:5debaab33562fdfc79ffdbd8d9c51cf07b8529de0e889d8cd145d78137aab21e \ - --hash=sha256:5ebc19f24e65a1f5c472e26d88e78b9d316e293bc6f205f32de4c4e99276336e \ - --hash=sha256:630cee960ba9e3016f95a8e6f725a621ddeff6fd287839f5693ccfab3f3a9b5c \ - --hash=sha256:6323e943c7672b271ad9575a2232508f17e87e81a78d7d10d6e93040e210eddf \ - --hash=sha256:6c051f2d28ca542092d01da8b5fe110fb6191ff58d298a54a93dc183bece63bf \ - --hash=sha256:6c19ab378fefb1f09623f583fcfa12ed42369a998ddfbd39c40908397243c56b \ - --hash=sha256:6df7be07af867ec1d121c92ea827efad4d77b25457c06eeab477b601e82b2340 \ - --hash=sha256:6f9fa1257e075eeeed67d21f95e411036b7ca2b5c78f757d4ac66485c191720a \ - --hash=sha256:7336a3c4ba4fc9e6741fbe60c6483266fe39e1f24830724dfce453471d11fa40 \ - --hash=sha256:73a88dc333efc42281bd800d5182c8625c6e11d109fc183fe3d7a11d48ab1150 \ - --hash=sha256:766d5f5a686eb99b53168a7bdfb338035931a609bdbbcb537cef9e050a86f359 \ - --hash=sha256:77bb4cbadf4121db395189065c58c9dd5d1950257cc1983004e6df4a3e2f97ad \ - --hash=sha256:77fea54c2379b93def4ed16db6390e1232e7b235679587295a23dd8b1925475f \ - --hash=sha256:8047c33b85f7790474a1f488bef95689f049976a4e1c6f213a8d075d180a93e4 \ - --hash=sha256:80e6fd06f6e4074d183cea73962c89cf76cb4f70c0ee403689f57a429ebde488 \ - --hash=sha256:849a57d39feaf897955d0b19bbf4796bea53d1bcdf83b82e0a7b059167eb2049 \ - --hash=sha256:8678c2272e7bd60a75f781409e900c9ddb9f01f55c625d83ae0d49dfc6a2674f \ - --hash=sha256:8814db38fa317bebec8eb74b826bae7d0cb978a7eca30dfe4ecf60e61f06ee0b \ - --hash=sha256:8860d67dc04dc530b8b4f588f38b7341a76f2ec44a45685a2d54e9dcffa5d15a \ - --hash=sha256:898db0ea3e4aaa95b7fecba02a7560dfbf368f9d85053f2875f6d610c4d4ec2c \ - --hash=sha256:8a17631e3e691eec4ae6a370f7b035cf0a5767f4457bd615d11728c23df72e43 \ - --hash=sha256:8a18c61817f3210ba74ad5792c8a5048d9550ba233233a0a8fe35800350988f4 \ - --hash=sha256:8d4e621caadfdbc73d36eabdb2f392da850d28c58b020738411d09dda6208509 \ - --hash=sha256:94dbfd6a6ec0ae64b5262290bf014d6063f9ac8688bda9ec668dc175378d2c80 \ - --hash=sha256:95867a07c5dee0ea2340fe1d0e4f6d9f5c5687d473193b6ee6f86fa44aac45d1 \ - --hash=sha256:95c9de7ebc55ffb777548f2ecaf4b96b0fa0c92f42bf4d897b9f4cd164ec7394 \ - --hash=sha256:9adeec7cab0f2c2c291bd7faf9fa3fa233365fd0bf1c1c27a6ddd6cc563d4b32 \ - --hash=sha256:9c463ae15e94b1c6a8a50bd671d6166b0b0d779fd1e56cbf46d8a4a84c9aa2d0 \ - --hash=sha256:9d9de35eb5987da27dd81e371c52142dd8e924bd61c1006003071ea05a735587 \ - --hash=sha256:a2eb8fca918c7381531035c3aae31c29a1c1300ab8a63cad1ec3a71331096c78 \ - --hash=sha256:a4319f478ab1b90bbbe9921606ecb7baa0ebf0b332e821d41c3abdf1a30f0c35 \ - --hash=sha256:a507fe6928a27a308e04ebf2065719b7850d1bf9ff1924f4e601ef77758812bd \ - --hash=sha256:a8892a7da0f617135fe9c92dc7070d13a0f96ab3081f9db7ff5b172a3905bd78 \ - --hash=sha256:a99d898ad1a399d9c8cab5561b3667fd24f4385820ac90c3340aa637aa5adfc9 \ - --hash=sha256:aa4136f8ccb9a8cd32befd1b3882c2597e6791e64e8b3cf3129c55549b5de62f \ - --hash=sha256:ab2a5177522b62426db897b655a02f574e27d9735bbeb6da41bc981b771df636 \ - --hash=sha256:ab806fd026bfd48bade5e21e06d0d799cbfad32f236989ff6f37db03a5fbe34f \ - --hash=sha256:ad5f0847da00687f52d2b81828e8d887bdea9eb8686a9841024ea7a0e153028e \ - --hash=sha256:b0bee27fb596a0f518369c275a965d0448c39a0730e53a030b311bb10562d4d5 \ - --hash=sha256:b31d66b62736b8514982a24a7dedcf8c062b27a8e9b51e52d7a5899045a45fe1 \ - --hash=sha256:b38ddfab41d10e780edb431edc30aec89bee4ce43d718e3896e99f33dae5c1d3 \ - --hash=sha256:be1bdbd52145dfe46880d8bb56eacc25aa75c3bb075fa103de7974295eb2811f \ - --hash=sha256:c10065081c0e137975de5d9ba2ff2306286dbf5e0c586d4d5aec87c856239b41 \ - --hash=sha256:c11c62a3cdb9d1426b1536de9e3446cb09c7d025bd4df125275cae221f214899 \ - --hash=sha256:c3777ae3e088e94df854fbcbd8d59f9239b74aac036cb6bbd19f8035c8e42478 \ - --hash=sha256:c3d93171dd65b36eca5367acf19eef82c79b4df557cb4bd0daf323b7a27f2d3b \ - --hash=sha256:c9a679b24f5c6f366a0dec75745e1abeae2f597f033d0d54c74cbe62e7e6ae28 \ - --hash=sha256:caa71c723f512f8d859fa239573086e16f38ffc426b5b2f7dab5d40fdb356c80 \ - --hash=sha256:ce86d9dfc6b409ad16556384244572bb3cbefa2ca0f0eab7fba0ff2112b2f068 \ - --hash=sha256:d4cd82e65b5aeb31bd73534e61ece1cab625f4bcbdc13bc4ddc5f8cbfb37c24a \ - --hash=sha256:d524a4ba765bae9b950706472a77a887a525ed21144fe4b41f6190f6e57caa2c \ - --hash=sha256:d7310312a68fdb1a8249cf114acb5435aa6b6a958b15810f053c1df5f98476e4 \ - --hash=sha256:d8274ff02d447cca026ba00f56070ba15f95e184b2d028ee0e4b6c9813d2aaf9 \ - --hash=sha256:d879be7fb5296409e18731c7ba666d56ecd45b816b2c9eb35138aa1d7777aeb5 \ - --hash=sha256:d87ed09e5c9b6d2648e8856a4e556147b9d3cd4d63905fa664dd6706bc414256 \ - --hash=sha256:dde1c3f3edb1f0095dcbf79cf8a0bb768f9539e809d0ad010d78200eea97d42a \ - --hash=sha256:df5e9db9539d70426f5d20c7ebb6f7b33da5fbd40620e11261fe3fba7e177145 \ - --hash=sha256:e7cad66317f12f0fd755fe41ee7c6b06531d2189a9048a8f37addb5109f7e3e3 \ - --hash=sha256:ec1694134961b71ac05241ac989b49ccf08e232b5834d5fc46f8a7c3bb1c13a9 \ - --hash=sha256:ec985386bc3cd54155f2ef0434fccbfd743617ed6fc1a84dae2ab1de6062e0c6 \ - --hash=sha256:ef9d103706560c15fecaf7d3cff939e0f68ce5763cf0e64d0e4e5d37f9bdd2d1 \ - --hash=sha256:f1350033431d75be749273236dcfc808e54404cd6ece6204cdb1bc4ccc163455 \ - --hash=sha256:f1fe71c203f66bc169a393964d5702f9251cfd4d70279cb6453fdd42bd2e675f \ - --hash=sha256:f24189dc3aea3a0a94391a047076e1014306b39ba17d7a38ebab510553cd1a97 \ - --hash=sha256:f57726b5a90d818625e6996f5116971b7a4ceb888832337d0e2cf43d1c362a90 \ - --hash=sha256:f7c055a50d068b3a924bd33a327646346839f55bcb762a26ec3fde8ea5d40564 \ - --hash=sha256:f7e5072269c34a1b719910ee4decf13b288159fb320f18aba3885f6b6aab7753 \ - --hash=sha256:f7e507e1e798ebca77ddc9774fd405107833315ad802cfdaa1ab07b6d9154fc8 \ - --hash=sha256:fbbffb948a32f9783d1a28bc0c53616f0a76736ed1e7c1d62e3e99a8dfaab869 \ - --hash=sha256:fd87d112eda1f0528074e1f7c0312881816cb75854133021124269a27c6c48dc \ - --hash=sha256:ff06e4aa781aa4f68fbfaf1e727fe221fa1c552fef8ae70b6d2a0178e1f229ad +python-bidi==0.6.10 \ + --hash=sha256:00e8f3504e63a7713bdc1367b3de46270ddc76551f1cf04510039d65a123fd53 \ + --hash=sha256:038d29ba39a638a5aa904e3f86547f6f883ca16b3ea1db98fbc861e9644762fe \ + --hash=sha256:0533a900b9b9fa94e1c906e8cdb15b579389ce3fa959af228a12e8527aaba8cc \ + --hash=sha256:0675bdaceac9e2bd8ea99729d064435d1d1502e1875b87ed72ad93a8da153ff0 \ + --hash=sha256:07de0d6b998184233e8f753cbff5e828e0204b38daa3deaa458af6cb53c0960d \ + --hash=sha256:099b82f05557c1588973cceab0ebd2535800990850b4cbf8eae57682ef746a16 \ + --hash=sha256:099c3c29d813e263e999205ec9d59658c519c3bc51256e8ab3761ff3dc46a1b3 \ + --hash=sha256:09c90aca4713ed86422acfbaf90d8c5c9f64cbae02e737e7f82f13cd2ff4f34c \ + --hash=sha256:09d70ad127cbcb9cc5e90c4f2f427d998450374870f305345a8c23338a0bca55 \ + --hash=sha256:0c63bf9de0646eb7cf8d520e258701e5086c010e18cbc32e8ab884e29d5ff12f \ + --hash=sha256:0e404d7e027bd47553e48d9e3f207f3ee255698cac1fa80380d4703d4397ffe5 \ + --hash=sha256:0ef816ef2a04ce92108cdcc61c7710860e0f2b11906d493e14c6e5b403b09a01 \ + --hash=sha256:0f1c310774819302fba49b0608126033ba4b2bd0fb01d23b2c232df6d31003a4 \ + --hash=sha256:0f6a5c7b00ce285a3389e261db3f0477c2c3e893b352e65889410d995ff5ee13 \ + --hash=sha256:15298befde960a80885729c3603a95058f611b7d71de645cfbdd875f98146e14 \ + --hash=sha256:153a2f75648ceb583a09e66b4da99ec54b82e3226e5c0992f79e05d2d00d5a6e \ + --hash=sha256:1552aad47e65e8458346307e8b3fe7ae8eb0fcf3ea4ce3aba5cf44c50117e30b \ + --hash=sha256:15f0deadc4e8bf4d5458d62c4c94f7716c1d29f106751f2d9f5a478698465df0 \ + --hash=sha256:19c06c20f47f4a3daad14b5e7c2b4e23e76f4277883ef43616ecd9a8eff73203 \ + --hash=sha256:1a156226a8723942b50ffa210d1840688da158c185e3d0840743345003249875 \ + --hash=sha256:1d7714b96ab30df31337f5d100bf71ebe637976e2464761c81ab05787c4bacff \ + --hash=sha256:22f51e0e5c64e18f5f9b6ac2d01fcbbecdfa6a2d571ae71323d3051d0635b9c6 \ + --hash=sha256:2371afc3f50da896212b2d1ea7f461134ef292e1737c87d7547dd0384c092388 \ + --hash=sha256:2598937e05401111ade68cd6e2212fa556fe8cc401b541d19dcd039496a0cfdd \ + --hash=sha256:27fc502f2e368ffcedb97b674956f8306573f43cd0204e2ed9fbe7f41d116a7b \ + --hash=sha256:29a476af5efbe7fedfb53c8d05d1447e4f4149da8d88fa0643716a374b6abf27 \ + --hash=sha256:2a2013623ea8713e4bc712922d37449a4a86a504275b42447e1d2f22eb565f9d \ + --hash=sha256:322bea01cd3f9c1cc153ea4ca3b8f82d27efe5ae8c4bd81cc981420e25490bd4 \ + --hash=sha256:327e570f10443995d3697e8096bc337970dfc32cd5339759fa4e87093cf5cdf9 \ + --hash=sha256:32c6075f2b44c1b3d01e7d0c8a5bb519bdbbc832bee2d4b01a06908117d3b050 \ + --hash=sha256:32eb932af02b2dec7d3043daed84a80e34a3f46327a7cacf6a813773369fceb8 \ + --hash=sha256:341d75c8b0e107bd5188e30a8a340ec5e1a26066f21de3c761b53fde54e6cd7d \ + --hash=sha256:3a2fcfc6be1917695cd6f7c9626481aa81ade7e3ef3f79c0f7a286edf68e4463 \ + --hash=sha256:3a485820e499c74332929eb9fe9246cec92fd4e6b8c2abde03e8d8f0fea00728 \ + --hash=sha256:3d0c48305c58a5ed0017500dbeedbfc62fc8b9cd552d582ea578a10f77eed1c1 \ + --hash=sha256:3ebbf3915c39ed8d0095e3672ed4f824dfe9544e950a273513956b147528a18b \ + --hash=sha256:3ff3bc2221d8c32427cf90999b60ee9bd5e31e2e0b7f54b63ad54a05912725b8 \ + --hash=sha256:441d931609adfb2d213892e2da0326a5c5048f05e36497d5e37087b97a3287dd \ + --hash=sha256:446f1cd15783b14a280fc6c8e8931afa3f4ec1edc0b341b82cfca1537886cf28 \ + --hash=sha256:44caa945d27b7634bb4fdfe8fbeaa27b33fb12b66418e326e5a491d235b5c61b \ + --hash=sha256:44e21c6dc51b88ede76aafe730a208ef5a23cf7275d30d7870ff46e3a6ad4314 \ + --hash=sha256:44e6566093397def4e72f85e47d246d442838c497e6be3b14be0bca7d9761a50 \ + --hash=sha256:452a7ff78909edef965d1f2dc87e8cf04e6d4234771eef9b876688fdd821ab1d \ + --hash=sha256:473e718a86e5a9290ee240cf0cf49093ec0ca841d709f0fef191b7f5ea4e8b3b \ + --hash=sha256:48af3fc3bee49c3be03bbd47b503dc794474c52db249c57d230a4616cf13cf52 \ + --hash=sha256:4ed6794f07fcb4374e74a1a973350c5997c2088ba6143a8fedb533010f379502 \ + --hash=sha256:5040b6595e6a9d1cbca5fc2298684994cc5f1036ff2015eaf30063f015f31540 \ + --hash=sha256:5899a244bc0b60d71ae80dcf0dfad16c72e742857c13c0d040d1c975bb758983 \ + --hash=sha256:5d11a3eb283fbde362c4b1faa32a4053413a83aa6abc2274827e1f03c89f53f4 \ + --hash=sha256:5e4752fc7228a2d70b69dc81fe4bbe602eca44a520b3d7ff46b50fb2b68d435e \ + --hash=sha256:5f3febf9b547b3b237429fb8c214ff8faa50972c6de0fc0fbaf060fc29e4696d \ + --hash=sha256:5fdea42e1356d428cdc1771e3468327cf776da51c44a8ced855b67b02809ea56 \ + --hash=sha256:6054e1b9920a917749fb4e7547b378e0647c25095c012a2a7c184493b9204ef1 \ + --hash=sha256:644d068e01071c7af565a70269f8c93f6434c031df2b1428625ed8f6040b94b4 \ + --hash=sha256:64d4adc41eb79de0561874bbbe74e8f7974b3bb947070d0edd73d388c98e1234 \ + --hash=sha256:6a75d9ab145003094475bc955120b4577d70f34ee02f0b69696d7f216b513479 \ + --hash=sha256:6c5be3141bf22d2908d6269e613c2bc3824db0f31560a61b95be75d224812c67 \ + --hash=sha256:6e2b535558cad96805b58695353a628471e455f4f30e346d1d0a10468c991d0e \ + --hash=sha256:704c76e64aa0f7c0d4b8dff04ce9e8fb38314bddd1426985856e2533e66d7d21 \ + --hash=sha256:732ad1ebff85d4669152ec8c0bbeebdf945a3460e26ae852a30d39d93765765c \ + --hash=sha256:73bc12f9599cf1dbc39e3792abaa8fc62656cff30340308c3341583631ea5fcc \ + --hash=sha256:78248580e38051ba799076bffa5d0498d2550a4fa6d2ec733c38e4ec5a2d8039 \ + --hash=sha256:7965b1c468b986a1bbb9fd3ba8641b51f4f93352cefc83eec851fdf15850019f \ + --hash=sha256:79ba6f914436c674cb0a25d4e1356e54b3b788ccd1498e1b130edd6ba1ad2f8e \ + --hash=sha256:7a3f20dca786d493c1383273992ca87ff78942456898b136e2973a682dad73ae \ + --hash=sha256:7a5452fda554628660eb4c1c4da6187986c5497f34fbeb07f920c867b6daa943 \ + --hash=sha256:7ae97eed360514e229b0c407095a4184d8a0e6383bc87962972ae27f6ecb96e6 \ + --hash=sha256:8012aed843d01a96fbd5c2fe4d8062696f8720d38990d68eaf871aa692652e98 \ + --hash=sha256:81b27ffd3e40e2d8f274e1acbf5967873e53d6f32bf677899e0d8421170703da \ + --hash=sha256:82897bacfd8fc2fb1157b1828a011af954c24b1dc25adb2aec33fdbcacd3935f \ + --hash=sha256:84f6975f51d2af2e9b474669f26673486899138ea985f9967db4f6ab9a431b95 \ + --hash=sha256:86dea78bc3953853afb701b7bf3531f062e7aa7d0a4bdb1a59f496200967bbf7 \ + --hash=sha256:8af0d7059829d43e5b9e4072103f09d3869d3da9fc6db66b51e93da0ed0b1161 \ + --hash=sha256:8f95878c574eb603942561ad76d09ed8b05e2ffd46917b32f15bb83878f7f40e \ + --hash=sha256:903b8e4ea0fed7d453e7e437d41ba0357be55572a108f8d6110ab74cbe3b2bb0 \ + --hash=sha256:916688bcee55ce613879751a27b25977f75403c681e6d110cdf301edb48027a1 \ + --hash=sha256:929c705687f506fed02aa1fbd6781fb310203d7a20420dd7f106cd87fe1d01c5 \ + --hash=sha256:9545c3cd8238a79ab7e0ff7b27326bef3439001207984ea47fa3be31551d364e \ + --hash=sha256:97692e9fb3271a637f18d728d5db4ff729c82ae25356e35d371fada2fe0ff006 \ + --hash=sha256:9c2ae7649b77a4354b6db6423c495bd57ac5727d62266dfe98254896eb573b25 \ + --hash=sha256:a06a6e54a95b5c5864e117af2479113bb367660b0d95295b4adf314b3dff77af \ + --hash=sha256:a0df4cb0fe94de7565c3fc875888431ef774d643f00b030bd041fdebbdcd189b \ + --hash=sha256:a2e1da56d841ae506c49df41e16893428b96d3c8c255f096b1aa83c512302c94 \ + --hash=sha256:a50b1ce6c5a2aaa4febbd72cf030ec7d9bd63a063977850e484fb4a7983f7eaf \ + --hash=sha256:a51922e22ab237431c3d5505b2511732748f936349ab65d0c1a4a13e224144fc \ + --hash=sha256:a5aac3c9648872dcf11543751e2a8970ab0e8e3192fdf83ed507838917f50d70 \ + --hash=sha256:a7853e894f723675489ac49aa4b52dc8eac87d7a67b5940631c8c9d2aab46f90 \ + --hash=sha256:a7871f1226a062c641c500f81f05c2c00274c23de26707d747ce16ede43a6fdb \ + --hash=sha256:a84f26e55770a9326cedf79c005c2e7f9c13da9e0cbb65bc36890382a793bda9 \ + --hash=sha256:a9b83026c2907ad207eff37d5d302ecdd20441ba87d89401a79fa4b9af11f24d \ + --hash=sha256:afd28c86da0968996595b3dcc1166b24367954d69242c186c0916721fe36274d \ + --hash=sha256:b048ba7ec56dfd0eb37bee34d395771d1ce444fd7a32c6e8ddd3bfc92090a1d8 \ + --hash=sha256:b0c77d935abdd7e3bee0f9b8a7d0ae8a7c230e5aca3a7b9948576b2e151c9985 \ + --hash=sha256:b223d1f5493530777475fc40e4a47b6854a5ac56ea3211196d7a91809fa565f3 \ + --hash=sha256:b35b3c7e2c91f67dbf49de4513adf80ee052b06f15dcb9e7e5c6cd6f37373114 \ + --hash=sha256:b35ff4e825c4ad912a30909f2922eddd684c84bffc48e713c8bf22a4f3d7794f \ + --hash=sha256:b45368872b3770b20d101a87364ffeec5c0cf02d8aaee1834c30167fe29ddaaa \ + --hash=sha256:b47233bf36749ab63561ece99b8b32684043558415f1e4ca6c540f1793fa12f3 \ + --hash=sha256:b497a46082c3b0e0f9a2571d573e745686ed1a6f7a9c631ebe2b9d6f55ecc87a \ + --hash=sha256:b528e71c3f4b867e207418ea4ed465a111306ac6c2838bf75ff1e465c74ea933 \ + --hash=sha256:b5c66316296044bcdda0fa37296322973c73b708eac737565d5bbc2f6fd51037 \ + --hash=sha256:b6bbca74b7d39d4f259c0eebb6d62fd970999c0beae553db7232319d151fa533 \ + --hash=sha256:b6ff61cd6e3a60ae9bd559aa5ab5a7018e8d26067e7f80ca0ac30e08c76bf983 \ + --hash=sha256:b97376c559d90d80976a2b3c2d1f7699b6e3ae69ffd2bfdefaacf1eb4bc45f8e \ + --hash=sha256:bca06cdbd6d90a939af253ddeed232e7e122a1e027942c2ebd431307e6471be6 \ + --hash=sha256:bd1247b5138e23824b62f96aa03f1d45084dee6c76c46019784546cc432a85ee \ + --hash=sha256:c1726465626bcad9518ff878be9edb6897b42d57c1bfb9e4a00ffd4000980c48 \ + --hash=sha256:c267e531392cbdd900e46796d410dda380c7b311434bf5090ee261bb05650bcc \ + --hash=sha256:c2960742693ee19663bc448328b6b7035f6ae4ad28f57379568d22180911c7d5 \ + --hash=sha256:c55787b0274b1e06530817fe6d375a5443a0e32d5ee55071244fe5af3483fcbc \ + --hash=sha256:c5fb03df1d641d19cec53ee9eb5b89f659d0087d03ae94f06e78e2663824d013 \ + --hash=sha256:c7aa354a62e727b592cfa181a5d435d9a946aba4dd2349bb18fc52c869d470f1 \ + --hash=sha256:c7b849fa2ed07cb59ed5e76d3cf0e3527b7d7bfa2e70d4fcb6df048a9c9177ee \ + --hash=sha256:cac7477518b8cfd53e78527a873be7de5a69183397124f7ebcae295cc39187c1 \ + --hash=sha256:cdc2933960f9b1b160551ff4a0cc543ec3866550ad13f35f1881c22f08b5ad82 \ + --hash=sha256:ce576c6e9a548e09c853e47cb88a95bb29363586c6ec7778ead517e61449b275 \ + --hash=sha256:d698d1354d7e30d3a3fbfb91b7b6c904e13875b4ed2dc40c726ca23d82b5089a \ + --hash=sha256:d6ec69bd053def14e4538b15dcd28bc9528c820b644687c0d38afc38e81fe8e8 \ + --hash=sha256:d717dc455632ab75284969106c4f40cc1533709f852c50d6db643b20e903b23d \ + --hash=sha256:d7d9b2602cccbb92fc6a8b8ab2b1f0f03c77c126e089f22f7747b19499cb3e1d \ + --hash=sha256:de06759a2b223599a98a200b01b9fdafec7e346b513ce6a31632f7089234eca3 \ + --hash=sha256:de7f4782b4381ae5b0dfa36ce1e4b0a925ccecd4f52330fcc50bcd73430b99fd \ + --hash=sha256:df0a3aa46c78e56ebed8c5be33da34c0408d4114c6b782103208fecbd3b6cac0 \ + --hash=sha256:e0fe5c41dac834dfbf1f93f29438393fef13ce250e699d67d2c066da6a0eb8af \ + --hash=sha256:e13dc08bcf7ef257d0635400e3377d3a776ec57ea25e985e903b00bf5ea06911 \ + --hash=sha256:e2e81871fa3353376a35260bf0313e631624eac6997d8fa4d60f38beee3f633f \ + --hash=sha256:e4871a8955ba6c4d80eaffc0f44af6ab724a99f4ec2ad6499243fe542027494f \ + --hash=sha256:e65f8b3029e64af05323cc630550b27649d8b1b612387c2e88411ae32c6a5b59 \ + --hash=sha256:e75704f210e8fbcfbe9546f33d4ef86ff9932830d74726108b45dad72d5c1b55 \ + --hash=sha256:e7f1fa876d3b7c09c1c6be627338502e78d3cc6e9b21ea94f8eeec6ad4157afa \ + --hash=sha256:edec736cfe6b5421e6c0fbf3e4fc70b5db30263d22e070526c7c540f5895f9fb \ + --hash=sha256:f3386c4370515f7acb3372ca49b4bd6652b65c381f50e772b5de96da7df2dbad \ + --hash=sha256:f53dbcc5b1ab75ee593f9ccdd474f9091e21b2051ade79db9930540188f3c9e3 \ + --hash=sha256:f6dad7fe7f004900a45b04ab2ef51dd11a46c7be4b182c2e533810435e197249 \ + --hash=sha256:f6e8fca537eb348409549b75f8721fe911cc001124cc7cbfa1a4722e641584c3 \ + --hash=sha256:f6fb6b3fef1b611841f50688c46d722ad5bd9bb5b9beec9d7c51885519f6026c \ + --hash=sha256:fc012f8738e21462b8b173278ef9278a822373a64f558ac1bfa36eceb56296df \ + --hash=sha256:fedf838627e262a5a3b9312a144582e7c81ff3be986a3b0ecd51b9d904747c0b \ + --hash=sha256:ff693056db843b5e4de6d8e50b4847c116481406492d10517dfe4d7c573c8f82 # via easyocr python-dateutil==2.9.0 \ --hash=sha256:78e73e19c63f5b20ffa567001531680d939dc042bf7850431877645523c66709 \ @@ -4284,10 +4887,12 @@ python-dateutil==2.9.0 \ # botocore # elasticsearch # google-cloud-bigquery + # graphene # great-expectations # ibis-framework # jupyter-client # kubernetes + # matplotlib # moto # openlineage-python # pandas @@ -4300,31 +4905,31 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via + # mlflow-skinny # pydantic-settings # pymilvus # testcontainers # uvicorn -python-json-logger==4.0.0 \ - --hash=sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2 \ - --hash=sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f +python-json-logger==4.1.0 \ + --hash=sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2 \ + --hash=sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195 # via jupyter-events python-keycloak==4.2.2 \ --hash=sha256:1d43a1accd4a038ed39317fcb3eb78211df6c75bbcbc4c482c99ee76327136f2 \ --hash=sha256:5137fd87c69031a372a578df96bae96b9aead2c9dad976613bc978e9e0246a1e # via feast (pyproject.toml) -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ --hash=sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095 # via docling -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via - # clickhouse-connect # great-expectations # pandas # snowflake-connector-python @@ -4413,6 +5018,7 @@ pyyaml==6.0.3 \ # huggingface-hub # jupyter-events # kubernetes + # mlflow-skinny # openlineage-python # pre-commit # ray @@ -4517,30 +5123,33 @@ pyzmq==27.1.0 \ # ipykernel # jupyter-client # jupyter-server -qdrant-client==1.17.0 \ - --hash=sha256:47eb033edb9be33a4babb4d87b0d8d5eaf03d52112dca0218db7f2030bf41ba9 \ - --hash=sha256:f5b452c68c42b3580d3d266446fb00d3c6e3aae89c916e16585b3c704e108438 +qdrant-client==1.18.0 \ + --hash=sha256:093aa8cf8a420ee3ad2a68b007e1378d7992b2600e0b53c193fc172674f659cd \ + --hash=sha256:52e8ece1a7d40519801bf0b70713bfa0f6b7ae28c7275bbe0b0286fbed7f6db4 # via feast (pyproject.toml) -ray==2.54.0 \ - --hash=sha256:1e63e491155695d527513ffe9d33a6aeb3f3cdccb6309adadfd6f8dd7c0300f7 \ - --hash=sha256:1e786330de55b3ba2228e36ec305381a9b86f0b01a8b6072c5811c3bc4dd9a3d \ - --hash=sha256:2d140409e4ca06d8d6a06f71d441b53f6edcd930ebe67a6988f652915db81070 \ - --hash=sha256:2ee074ede491d0aacfa339c003f5d7a15826e1e2a72ce873234ccbc0446e19b3 \ - --hash=sha256:491ae56ab80d8822c4eaf4d5bb96dcf32a6231d8d7b76eb8034400eb9be1bb18 \ - --hash=sha256:5ad77961fea16c697a0fb0e51216dd39c0bec28868cde54ac668edd58d12b8ae \ - --hash=sha256:795ae21d6b764245d3f521bc5833446d58569e7dfde9c5777417eb285d87450f \ - --hash=sha256:86da6ff60b57394aa47158b2f3fc2616a87492e828983451f04e676b192b49ce \ - --hash=sha256:8952c23a8aa94f10728c2d16e0dc3732d09aa0e6254801757ff494984a214f45 \ - --hash=sha256:8e39dd56b47a0a1820d5a5a54385bbe54d1d67e1093736d12d8ed4e99d0fa455 \ - --hash=sha256:928bb09245a3c6f7c3c113ba8eafc69f948da9602d7f33e8251ecdf97c157615 \ - --hash=sha256:a22937f09ee74a43171df338d84b45ef882c1c05748947ca9d5343a44d4b9379 \ - --hash=sha256:a972afd5aa3dda99d0b2f369b5f62e5dd95865ab7d37bf2e0a0e0d2cfbd9b325 \ - --hash=sha256:ab89e6089abb6e46fb98fdd96d399b31a852d79127cd8ac00746c61d93defa2c \ - --hash=sha256:cf5c33b4b13850ec24a5bd5f9d9e0a8161f8e586bfd297e52913d170dec447fe +ray==2.55.1 \ + --hash=sha256:0053fd5b400f7ac56263aa1bbd3d68fb79341b08b8dc697c88782d5aca7b3ed4 \ + --hash=sha256:0ea2f670a7725833ad2333a8c46ab69865ad06c8e5de9f65695e0f8f35331cec \ + --hash=sha256:137f9006eee28caab8260803cca314f37bbda3fc94fdfa31c770b5d019626ad8 \ + --hash=sha256:1380e043eb57cde69b7e9199c6f2558ceeb8f0fc41c97d1d5e50ea042115f302 \ + --hash=sha256:156ed3e72ad95b645d2006cd71a8dddbcc89b56bfc00027f6225adf78bd9cb74 \ + --hash=sha256:263705f6bab29e7622a94f82da25fd7f9cead76cdf89a07aab28f79cdf8f9d95 \ + --hash=sha256:26541f69bb55607ef8335baac75b2ed12ff2ce02d56313219b29eda003039221 \ + --hash=sha256:2d5786661e192148719accc959def6cdcabd7a24cd9008005bf3d0e3c8cfd529 \ + --hash=sha256:4e618d61e1b14b6fde9a586151f3fd9d435b0b85048b997bcaa7f4a533747b2b \ + --hash=sha256:5e56d2e8f304cafe990c198a2b894f5b813de018998cd7212869201f6dc17cff \ + --hash=sha256:86e618e9ad8c6a24331c788eb599cee9838a62d2e10dfca0227743be06cf551c \ + --hash=sha256:9ad56704c8bd7e92130162f9c58e4ef473609515637673d5a36e761f95335206 \ + --hash=sha256:b062045c64c2bce39a51661624f7292c7bbf30f2a9d878627aae31d46da5712d \ + --hash=sha256:b415d590e062f248907e0fe42994943f11726b7178fcf4b1cf5546721fb1a5f8 \ + --hash=sha256:baf2ec89df7838cabdef493ff9bdbec1e6a6452f8bc696ad0c1b8a6198721745 \ + --hash=sha256:bb49fbbe53a1d931e1f92d17f9271338f0b738885f8f70b7f531aa33f019d8af \ + --hash=sha256:d5382da181c03ee2f502ef46cf0ae4bbc30157b5bd9a67d7651f6a272528a85a \ + --hash=sha256:f9844a9272ef2e6eb5771025866072cf4234cf4c7cc1a31e235b7de7111864be # via feast (pyproject.toml) -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4549,131 +5158,132 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.2.28 \ - --hash=sha256:00945d007fd74a9084d2ab79b695b595c6b7ba3698972fadd43e23230c6979c1 \ - --hash=sha256:00f2b8d9615aa165fdff0a13f1a92049bfad555ee91e20d246a51aa0b556c60a \ - --hash=sha256:01d65fd24206c8e1e97e2e31b286c59009636c022eb5d003f52760b0f42155d4 \ - --hash=sha256:02473c954af35dd2defeb07e44182f5705b30ea3f351a7cbffa9177beb14da5d \ - --hash=sha256:03a83cc26aa2acda6b8b9dfe748cf9e84cbd390c424a1de34fdcef58961a297a \ - --hash=sha256:09500be324f49b470d907b3ef8af9afe857f5cca486f853853f7945ddbf75911 \ - --hash=sha256:0b1d2b07614d95fa2bf8a63fd1e98bd8fa2b4848dc91b1efbc8ba219fdd73952 \ - --hash=sha256:0d25a10811de831c2baa6aef3c0be91622f44dd8d31dd12e69f6398efb15e48b \ - --hash=sha256:0d5bef2031cbf38757a0b0bc4298bb4824b6332d28edc16b39247228fbdbad97 \ - --hash=sha256:10d28e19bd4888e4abf43bd3925f3c134c52fdf7259219003588a42e24c2aa25 \ - --hash=sha256:180e08a435a0319e6a4821c3468da18dc7001987e1c17ae1335488dfe7518dd8 \ - --hash=sha256:195237dc327858a7721bf8b0bbbef797554bc13563c3591e91cd0767bacbe359 \ - --hash=sha256:19a9c9e0a8f24f39d575a6a854d516b48ffe4cbdcb9de55cb0570a032556ecff \ - --hash=sha256:1c2c95e1a2b0f89d01e821ff4de1be4b5d73d1f4b0bf679fa27c1ad8d2327f1a \ - --hash=sha256:1d367257cd86c1cbb97ea94e77b373a0bbc2224976e247f173d19e8f18b4afa7 \ - --hash=sha256:1e496956106fd59ba6322a8ea17141a27c5040e5ee8f9433ae92d4e5204462a0 \ - --hash=sha256:1f8b17be5c27a684ea6759983c13506bd77bfc7c0347dff41b18ce5ddd2ee09a \ - --hash=sha256:2234059cfe33d9813a3677ef7667999caea9eeaa83fef98eb6ce15c6cf9e0215 \ - --hash=sha256:25b6eb660c5cf4b8c3407a1ed462abba26a926cc9965e164268a3267bcc06a43 \ - --hash=sha256:2954379dd20752e82d22accf3ff465311cbb2bac6c1f92c4afd400e1757f7451 \ - --hash=sha256:2afa673660928d0b63d84353c6c08a8a476ddfc4a47e11742949d182e6863ce8 \ - --hash=sha256:2b2b23587b26496ff5fd40df4278becdf386813ec00dc3533fa43a4cf0e2ad3c \ - --hash=sha256:2fb950ac1d88e6b6a9414381f403797b236f9fa17e1eee07683af72b1634207b \ - --hash=sha256:3935174fa4d9f70525a4367aaff3cb8bc0548129d114260c29d9dfa4a5b41692 \ - --hash=sha256:39bb5727650b9a0275c6a6690f9bb3fe693a7e6cc5c3155b1240aedf8926423e \ - --hash=sha256:3b24bd7e9d85dc7c6a8bd2aa14ecd234274a0248335a02adeb25448aecdd420d \ - --hash=sha256:4390c365fd2d45278f45afd4673cb90f7285f5701607e3ad4274df08e36140ae \ - --hash=sha256:481df4623fa4969c8b11f3433ed7d5e3dc9cec0f008356c3212b3933fb77e3d8 \ - --hash=sha256:4f5c0b182ad4269e7381b7c27fdb0408399881f7a92a4624fd5487f2971dfc11 \ - --hash=sha256:50c2fc924749543e0eacc93ada6aeeb3ea5f6715825624baa0dccaec771668ae \ - --hash=sha256:511f7419f7afab475fd4d639d4aedfc54205bcb0800066753ef68a59f0f330b5 \ - --hash=sha256:516604edd17b1c2c3e579cf4e9b25a53bf8fa6e7cedddf1127804d3e0140ca64 \ - --hash=sha256:52b017b35ac2214d0db5f4f90e303634dc44e4aba4bd6235a27f97ecbe5b0472 \ - --hash=sha256:5a932ea8ad5d0430351ff9c76c8db34db0d9f53c1d78f06022a21f4e290c5c18 \ - --hash=sha256:5cdcc17d935c8f9d3f4db5c2ebe2640c332e3822ad5d23c2f8e0228e6947943a \ - --hash=sha256:5d10303dd18cedfd4d095543998404df656088240bcfd3cd20a8f95b861f74bd \ - --hash=sha256:5e68192bb3a1d6fb2836da24aa494e413ea65853a21505e142e5b1064a595f3d \ - --hash=sha256:64e7c6ad614573e0640f271e811a408d79a9e1fe62a46adb602f598df42a818d \ - --hash=sha256:6591f281cb44dc13de9585b552cec6fc6cf47fb2fe7a48892295ee9bc4a612f9 \ - --hash=sha256:69fc560ccbf08a09dc9b52ab69cacfae51e0ed80dc5693078bdc97db2f91ae96 \ - --hash=sha256:6d63a07e5ec8ce7184452cb00c41c37b49e67dc4f73b2955b5b8e782ea970784 \ - --hash=sha256:6db7bfae0f8a2793ff1f7021468ea55e2699d0790eb58ee6ab36ae43aa00bc5b \ - --hash=sha256:71a911098be38c859ceb3f9a9ce43f4ed9f4c6720ad8684a066ea246b76ad9ff \ - --hash=sha256:73cdcdbba8028167ea81490c7f45280113e41db2c7afb65a276f4711fa3bcbff \ - --hash=sha256:78454178c7df31372ea737996fb7f36b3c2c92cccc641d251e072478afb4babc \ - --hash=sha256:7900157786428a79615a8264dac1f12c9b02957c473c8110c6b1f972dcecaddf \ - --hash=sha256:7ab218076eb0944549e7fe74cf0e2b83a82edb27e81cc87411f76240865e04d5 \ - --hash=sha256:7c1b34dfa72f826f535b20712afa9bb3ba580020e834f3c69866c5bddbf10098 \ - --hash=sha256:851fa70df44325e1e4cdb79c5e676e91a78147b1b543db2aec8734d2add30ec2 \ - --hash=sha256:864cdd1a2ef5716b0ab468af40139e62ede1b3a53386b375ec0786bb6783fc05 \ - --hash=sha256:8710d61737b0c0ce6836b1da7109f20d495e49b3809f30e27e9560be67a257bf \ - --hash=sha256:9036b400b20e4858d56d117108d7813ed07bb7803e3eed766675862131135ca6 \ - --hash=sha256:9185cc63359862a6e80fe97f696e04b0ad9a11c4ac0a4a927f979f611bfe3768 \ - --hash=sha256:948c12ef30ecedb128903c2c2678b339746eb7c689c5c21957c4a23950c96d15 \ - --hash=sha256:94d63db12e45a9b9f064bfe4800cefefc7e5f182052e4c1b774d46a40ab1d9bb \ - --hash=sha256:96f6269a2882fbb0ee76967116b83679dc628e68eaea44e90884b8d53d833881 \ - --hash=sha256:97054c55db06ab020342cc0d35d6f62a465fa7662871190175f1ad6c655c028f \ - --hash=sha256:98adf340100cbe6fbaf8e6dc75e28f2c191b1be50ffefe292fb0e6f6eefdb0d8 \ - --hash=sha256:99985a2c277dcb9ccb63f937451af5d65177af1efdeb8173ac55b61095a0a05c \ - --hash=sha256:9b65d33a17101569f86d9c5966a8b1d7fbf8afdda5a8aa219301b0a80f58cf7d \ - --hash=sha256:9dd450db6458387167e033cfa80887a34c99c81d26da1bf8b0b41bf8c9cac88e \ - --hash=sha256:a25c7701e4f7a70021db9aaf4a4a0a67033c6318752146e03d1b94d32006217e \ - --hash=sha256:a448af01e3d8031c89c5d902040b124a5e921a25c4e5e07a861ca591ce429341 \ - --hash=sha256:a5dac14d0872eeb35260a8e30bac07ddf22adc1e3a0635b52b02e180d17c9c7e \ - --hash=sha256:a729e47d418ea11d03469f321aaf67cdee8954cde3ff2cf8403ab87951ad10f2 \ - --hash=sha256:aaffaecffcd2479ce87aa1e74076c221700b7c804e48e98e62500ee748f0f550 \ - --hash=sha256:b059e71ec363968671693a78c5053bd9cb2fe410f9b8e4657e88377ebd603a2e \ - --hash=sha256:b387a0d092dac157fb026d737dde35ff3e49ef27f285343e7c6401851239df27 \ - --hash=sha256:b389c61aa28a79c2e0527ac36da579869c2e235a5b208a12c5b5318cda2501d8 \ - --hash=sha256:b42f7466e32bf15a961cf09f35fa6323cc72e64d3d2c990b10de1274a5da0a59 \ - --hash=sha256:b49eb78048c6354f49e91e4b77da21257fecb92256b6d599ae44403cab30b05b \ - --hash=sha256:b5acd4b6a95f37c3c3828e5d053a7d4edaedb85de551db0153754924cb7c83e3 \ - --hash=sha256:b8b3f1be1738feadc69f62daa250c933e85c6f34fa378f54a7ff43807c1b9117 \ - --hash=sha256:b8cf76f1a29f0e99dcfd7aef1551a9827588aae5a737fe31442021165f1920dc \ - --hash=sha256:ba55c50f408fb5c346a3a02d2ce0ebc839784e24f7c9684fde328ff063c3cdea \ - --hash=sha256:bba2b18d70eeb7b79950f12f633beeecd923f7c9ad6f6bae28e59b4cb3ab046b \ - --hash=sha256:bbb882061f742eb5d46f2f1bd5304055be0a66b783576de3d7eef1bed4778a6e \ - --hash=sha256:bcb399ed84eabf4282587ba151f2732ad8168e66f1d3f85b1d038868fe547703 \ - --hash=sha256:bd477d5f79920338107f04aa645f094032d9e3030cc55be581df3d1ef61aa318 \ - --hash=sha256:bec23c11cbbf09a4df32fe50d57cbdd777bc442269b6e39a1775654f1c95dee2 \ - --hash=sha256:c0b5ccbb8ffb433939d248707d4a8b31993cb76ab1a0187ca886bf50e96df952 \ - --hash=sha256:c15af43c72a7fb0c97cbc66fa36a43546eddc5c06a662b64a0cbf30d6ac40944 \ - --hash=sha256:c7815afb0ca45456613fdaf60ea9c993715511c8d53a83bc468305cbc0ee23c7 \ - --hash=sha256:cb3b1db8ff6c7b8bf838ab05583ea15230cb2f678e569ab0e3a24d1e8320940b \ - --hash=sha256:d0b02e8b7e5874b48ae0f077ecca61c1a6a9f9895e9c6dfb191b55b242862033 \ - --hash=sha256:d6b08a06976ff4fb0d83077022fde3eca06c55432bb997d8c0495b9a4e9872f4 \ - --hash=sha256:d6cfe798d8da41bb1862ed6e0cba14003d387c3c0c4a5d45591076ae9f0ce2f8 \ - --hash=sha256:d8511a01d0e4ee1992eb3ba19e09bc1866fe03f05129c3aec3fdc4cbc77aad3f \ - --hash=sha256:dc8ed8c3f41c27acb83f7b6a9eb727a73fc6663441890c5cb3426a5f6a91ce7d \ - --hash=sha256:dd8847c4978bc3c7e6c826fb745f5570e518b8459ac2892151ce6627c7bc00d5 \ - --hash=sha256:de0cf053139f96219ccfabb4a8dd2d217c8c82cb206c91d9f109f3f552d6b43d \ - --hash=sha256:dee50f1be42222f89767b64b283283ef963189da0dda4a515aa54a5563c62dec \ - --hash=sha256:e1e7b24cb3ae9953a560c563045d1ba56ee4749fbd05cf21ba571069bd7be81b \ - --hash=sha256:e59bc8f30414d283ae8ee1617b13d8112e7135cb92830f0ec3688cb29152585a \ - --hash=sha256:e61eea47230eba62a31f3e8a0e3164d0f37ef9f40529fb2c79361bc6b53d2a92 \ - --hash=sha256:e621fb7c8dc147419b28e1702f58a0177ff8308a76fa295c71f3e7827849f5d9 \ - --hash=sha256:e71dcecaa113eebcc96622c17692672c2d104b1d71ddf7adeda90da7ddeb26fc \ - --hash=sha256:e7ce83654d1ab701cb619285a18a8e5a889c1216d746ddc710c914ca5fd71022 \ - --hash=sha256:e8c8cb2deba42f5ec1ede46374e990f8adc5e6456a57ac1a261b19be6f28e4e6 \ - --hash=sha256:ec0c608b7a7465ffadb344ed7c987ff2f11ee03f6a130b569aa74d8a70e8333c \ - --hash=sha256:ec6f5674c5dc836994f50f1186dd1fafde4be0666aae201ae2fcc3d29d8adf27 \ - --hash=sha256:edb1b1b3a5576c56f08ac46f108c40333f222ebfd5cf63afdfa3aab0791ebe5b \ - --hash=sha256:ef77bdde9c9eba3f7fa5b58084b29bbcc74bcf55fdbeaa67c102a35b5bd7e7cc \ - --hash=sha256:f2791948f7c70bb9335a9102df45e93d428f4b8128020d85920223925d73b9e1 \ - --hash=sha256:f467cb602f03fbd1ab1908f68b53c649ce393fde056628dc8c7e634dab6bfc07 \ - --hash=sha256:f8ed9a5d4612df9d4de15878f0bc6aa7a268afbe5af21a3fdd97fa19516e978c \ - --hash=sha256:fa539be029844c0ce1114762d2952ab6cfdd7c7c9bd72e0db26b94c3c36dcc5a \ - --hash=sha256:fb1c4ff62277d87a7335f2c1ea4e0387b8f2b3ad88a64efd9943906aafad4f33 \ - --hash=sha256:fb4db2f17e6484904f986c5a657cec85574c76b5c5e61c7aae9ffa1bc6224f95 \ - --hash=sha256:fb66e5245db9652abd7196ace599b04d9c0e4aa7c8f0e2803938377835780081 \ - --hash=sha256:fc48c500838be6882b32748f60a15229d2dea96e59ef341eaa96ec83538f498d \ - --hash=sha256:fcf26c3c6d0da98fada8ae4ef0aa1c3405a431c0a77eb17306d38a89b02adcd7 \ - --hash=sha256:fd0ce43e71d825b7c0661f9c54d4d74bd97c56c3fd102a8985bcfea48236bacb \ - --hash=sha256:fd63453f10d29097cc3dc62d070746523973fb5aa1c66d25f8558bebd47fed61 +regex==2026.5.9 \ + --hash=sha256:002205cafd2a9e78c6290c7d1df277bf3277b3b7a30e0b4bb0dac2e2e3f7cb2d \ + --hash=sha256:01f0f5f55f4b64dacec85dc116d3c05fd23ad3ff037bbc73a2085775953c2611 \ + --hash=sha256:01f28d868834624c934b8d2e0aa1c8341337e37831f4a012f18a5afcba4cbaf3 \ + --hash=sha256:075160bf16658e16d35233300b8453aac25de4cbea808d22348b6979668e924d \ + --hash=sha256:0de5cf193997384ed2ca6f1cd4f78055b255d93d82d5a8cd6ba0d11c10b167e4 \ + --hash=sha256:0e1b1b4e496afbb24f4a62aba855ee4f88f25578927697b340702e48c9ee6bc2 \ + --hash=sha256:0f03aa6898aaaac4592479821df16e68e8d0e29e903e65d8f2dfb2f19028a989 \ + --hash=sha256:0f9eede6a5cbdc02d4978090186390936e1776a7d1359b21e41014c609880bcf \ + --hash=sha256:1268eddd8486dc561d08eee1156e40aa3a8fe10f4bdec8fa653b455fcbffd12c \ + --hash=sha256:15ee42209947f4ca045412eae98416317238163618ace2a8e54f99586a466733 \ + --hash=sha256:164eba9b755ea6f244b0d881196fbc1fac09714e9782c9e2732b813142033c8e \ + --hash=sha256:19c16ceb4a267a8789e25733e583983eeab9f0f8664e66b0bd1c5d21f14c2d4b \ + --hash=sha256:1bd7587a2948b4085195d5a3374eaf4a425dc3e55784c038175355ecf3bbbf8a \ + --hash=sha256:1e6da47d679b7010ef27556b6e0f99771b744936db1792a10ceac6547ae1503e \ + --hash=sha256:205109e96b3cf5adf8f4cd62bedde9487feb282b9497a3535451e5a24cd706a0 \ + --hash=sha256:2099f7e7ff7b6aa3192312650a56e91cc091e49d50b04e4f6f8b6e28b3b27f1c \ + --hash=sha256:246de9d60aa3f8538b519834dd95cbf276ea263d6a7bd5a3666dc3fa0230505b \ + --hash=sha256:24b2355ef5cc9aa5b8f07d17704face1c166fdcc2290fa7bd6e6c925655a8346 \ + --hash=sha256:2a661a7d270a61f7cf460caee8b9fa2d5ef9e5c681234bcb9e0fe14f488e7dfc \ + --hash=sha256:2acfb48634f64996b57f90f39afa692ff362162722581921fe92239a59960f3c \ + --hash=sha256:2efa205e6d98b24d1f3ab395c11aa15cdf10935bca283d0285e0499c284fba21 \ + --hash=sha256:31037c82eccb44b7ea2e9e221d7c01429430e989a1f4b91ea5a855f6017b509a \ + --hash=sha256:3527bb4942d2c14552155406cdedd906567456821848aed1cb4933a391bf5eca \ + --hash=sha256:39617fb0cde9c0e6306dc70e3bfc096f3da793219879f7ae7aa341a69fbdcf6d \ + --hash=sha256:398c521292f4c7fb807001dcd54694d3a1fcafc179a36ad9cc56f98df85930b6 \ + --hash=sha256:3b1e39888c5e0c7d92cea4fc777396c4a90363b05de75d02eb459a4752200808 \ + --hash=sha256:3dd4a3ff360dfb836fecdb93a4598f9d6e2ac81e3e397125145c6221bf58cf4c \ + --hash=sha256:3ddd90103f9e5c471c49c7852ecc1fe27c7e45eb99e977aefe7caa4e779f4f58 \ + --hash=sha256:446ddd671e43ab535810c4b21cff7104945c701d4a14d1e6d1cd6f4e445a8bea \ + --hash=sha256:45375819235558a4ff1c4971dc32881f022613abdb180128f5cb4768c1765a1c \ + --hash=sha256:46f1326ca6e65b0879d23ca302c0f2415aad42ff0309b9c818e7949fe19a41d8 \ + --hash=sha256:48036f6374aaa79eb3b754ec29c61d1c6b1606749d705a13f8854fa2539671f6 \ + --hash=sha256:4ebe8f0b5ec5a5024dc4a4c59f444c4e9afc5f2abdbb8962065b75d27fb971f9 \ + --hash=sha256:4eeb011098fcb77af513dcef521a3dbecbf8849b1e38940759d293b7a93f5026 \ + --hash=sha256:508f56a89ba9cb26e4168cbc37dbd60a28d82430a9e18ad1d25fe0883c314ca2 \ + --hash=sha256:5604dfd046dc37eca90250fc3be938b076c8059fa772ac0ed6f499b0f0fb0415 \ + --hash=sha256:56a33f191f17d8c417f99945ebdc1e691d3af9605d86ec68c7e54a57e3e17af6 \ + --hash=sha256:57e8915c7986aa33d25e4d3629cef711cd2863f2961b10409f0c04cb8b7d9020 \ + --hash=sha256:57eeeb05db7979413dec5438f2db21d7ecbba787cde7a711df1a6f6df672aa06 \ + --hash=sha256:5b73ab8afcf66c622db143d1c6fda4e58e4d537ee4f125229ad47b1ab80f34c0 \ + --hash=sha256:5e41809d2683fcde7d5a8c87a6567ba1fb1ce0de9f31bff578de00a4b2d76daa \ + --hash=sha256:6351571c8a42b505eb555c0dc47d740d0fb66977dc142919eea6f4325b7c56a0 \ + --hash=sha256:6441cc660d76107934a09c22167200839a0e89604a6297f78a974e66e931d2c0 \ + --hash=sha256:65c8c8c37377794bd5b2f3ebe51919042bf17aec802e23c833d89782ed0c78af \ + --hash=sha256:6ba42b2e7e7f46cf68cc6a5ca36fa07959f9bbd9c6bdcc47b6ee76549a590248 \ + --hash=sha256:71b61c5bfe1c806332defc42ad6c780b3c55f661986d7f40283a3a88274b4c00 \ + --hash=sha256:728d8bfd28a8845c8b6bc5dc7ce010453d206396786c0765c2740cb65f37791e \ + --hash=sha256:7b92817338591505f282cf3864c145244b1edcf5381d237038df955001091538 \ + --hash=sha256:7e30b874d341fac767d7df5a0870540541c2c054b80cfaac116e8d367a8a7ff2 \ + --hash=sha256:7e87577720152d2caae19fe2baaf1f8d5ca12091e9e229f03915c37d1e4b9178 \ + --hash=sha256:83d0ee4a57d1c87cb549e195ec300b8f0ec3a82eba66d835e4e2ed8634fe4499 \ + --hash=sha256:8676474c07469d6f33dd1085ca2cd45f65785f32518f2b20e36d9953ca07f994 \ + --hash=sha256:86f40a5d6444db30a125c9c9177e6b25dad981cbc37451fd838f145e6edac92e \ + --hash=sha256:872acc074bd29ffc9913ecdfedf6ea77502312ca44a4aa0d3779089c6069d8de \ + --hash=sha256:8abd33fef90b2a9efac5557d6033ca82d1195ed3a15fea5af15ba7b463c6a63b \ + --hash=sha256:8c6e4218fbdfbcd4f6c19efca40930d24a621bf4b48cb76bc6640543bd28ef20 \ + --hash=sha256:8e76e8161ad00694cfce6767d5dea860c6391ac5b83e5c3a39661e696f11fc7e \ + --hash=sha256:8f3af7a4903c5c04a11a196a5aa75cdd7dd3f8508132f9fb3259d9f5908e3b88 \ + --hash=sha256:91328f1c23d47595ca3ef0a7557fa129c5a23404b775c770697d2f35b33e0107 \ + --hash=sha256:916714069da19329ef7de197dcbc77bb3104145c7c2c864dbfbe318f46b88b14 \ + --hash=sha256:93a7860539414dddaefba2b40f8771765ae17949d4c7182b876ce429e11a8309 \ + --hash=sha256:954cc214c04663ee6d266fc61739cad83054683048de65c5bd1d640ad28098ac \ + --hash=sha256:96f5f58b54a063d7ea9dca08e1cf57bfe10499c4d579ee672da284f57f5f0070 \ + --hash=sha256:97cf3bc1b7d7d2306772ec07366c80d9df00ff79e79cea32898883a646d2fae2 \ + --hash=sha256:98bd73080e8756255137e1bd3f3f00295bbc5aa383c0e0f973920e9134d7c4ad \ + --hash=sha256:992604d02e6d9c6d786c24a706a71ecffe1020fc1ef264044474cd81fa2c3919 \ + --hash=sha256:a24852d3c29ad9e47593593d8a247c44ccc3d0548ef12c822d6ed0810affe676 \ + --hash=sha256:a6a563446a41adc451393dc6b8e6ad87979efaee3c8738690a8d1b08ebead1b4 \ + --hash=sha256:a8234aa23ec39894bfe4a3f1b85616a7032481964a13ac6fc9f10de4f6fca270 \ + --hash=sha256:a8820737949116ffff55fe18f9fc644530063ba6ebfcb8314239416e78f1347c \ + --hash=sha256:a9e1328e17c84c1a5d22ec9f785ecef4a967fab9a42b6a8dc3bcbebd0a0c9e44 \ + --hash=sha256:aa0fbdbac82cb3e4450d0ccde7d7a35607f4cb2dd9fba4b8b69bfaf8c9fa6aed \ + --hash=sha256:b310768746dd314ea6e2ff4cc89ef215426813396ff4e94ee8e6f7096c8b6e03 \ + --hash=sha256:b46b0f094dc1d3b90356c85a0bd2c9bafc4a6a190b9d6f8ddd5a033b6e088ed4 \ + --hash=sha256:b4bb445ff3f725f59df8f6014edb547ee928ec7023a774f6a39a3f953038cbb2 \ + --hash=sha256:b6d189041f15691cfa2b6c4290448ec221244d225b3f5fe9e7771b34ffcdf6e2 \ + --hash=sha256:b96350aa424e79d4fd6b567b344dcbe2b2d6bfc48dfe7717587e1fa6d43da6ff \ + --hash=sha256:be3372b9df6ddecff6486d37e19095a7b4973137caf5512407a89f4455361f41 \ + --hash=sha256:bfe1ce50cbfb569d74e1e4337da6468961f31dbea55fd85aa5de59c0947a805a \ + --hash=sha256:c010eb8caca74bdb40c07498d7ece26b4428fd3f04aa8a72c9ac6f79e8faaac6 \ + --hash=sha256:c8b9b9d294cfea3cd19c718ade7cc93492b2c4991abd9a68d0b3477ae6d8e100 \ + --hash=sha256:c9411dd64ca95477225734a93dfc8583b51916b8d5942f99d6cac21e09965451 \ + --hash=sha256:ca518ed29c46eecba6010b15f1b9a479314d2de409536e71b6a13aa04e3b8a77 \ + --hash=sha256:ccf5249114cc3e772ecdd88a98a86eca0fd74c61ce32a94743758c083fc05d48 \ + --hash=sha256:cd2846168eb9ee3c513902bc8225409cb1caab31d04728b145171fa1625d9621 \ + --hash=sha256:d29eebfc9525db68cad3c97eedd7f754fa265aa5cd0cf4f863b2421e1b48fc9f \ + --hash=sha256:d3d7eb5c9a7f6df82ed3cfac9beb93882a5cbcb5b8b157b56cb2b3b276574ac1 \ + --hash=sha256:d626b84406444b165fc0ba981604edea39f0588ff1f92baa23fe50799ea9afdb \ + --hash=sha256:d641a8c9a61618047796d572a39a79b26167b0411d2c3031937b2fe2d081e2cf \ + --hash=sha256:d659eee77986549c9ea45b861c7567e44d6287c3dc9a4565478853f7b9fe2ff6 \ + --hash=sha256:d6b8a143aca6c39b446ea8092cde25cc8fe9304d4f5fecfbc1a9dbb0282703c2 \ + --hash=sha256:d726ca3f0d76969bf1e8e477d160d3d666bbf999f6860bd314889e5345782046 \ + --hash=sha256:d7bdc0ab8f3dd7e1b4f9ab88634e13374669db86bb3c72e8292f07ae313f539f \ + --hash=sha256:daff2bdbaf1d23e52fdff7c0b7bc2048b68f978df6a4d107ac981f94caef2e66 \ + --hash=sha256:dd2810d22146b6d838acc5ec15602cb6b47920aa4e33015df3868eedfd20bab8 \ + --hash=sha256:ddda5340e6c01a293027dd46232fa79eaff1b48058ce7a98f572b6445b088041 \ + --hash=sha256:dea2e88e1cce4522496cce630e11e67b98b7076620bc4336c3f674bc21a375f4 \ + --hash=sha256:debb893095e944091c16e641a6e33c1b0f4cb61ab945ec5afbf53ce7068834d8 \ + --hash=sha256:dfbe4579b9f08036aa7d101d1835437a20783574ac66327e6b29b4018a138081 \ + --hash=sha256:e1d93bf647916292e8edcec150c07ddf3dc50179ccaf770c04a7f9e452155372 \ + --hash=sha256:e82db382b44d0111b22601c509c89f64434816c9e0eef9d1989cda8cc6ff1c04 \ + --hash=sha256:ea9c8ecfa1b73c73b626534d6626e5340d429630943672b8480724f44e84b962 \ + --hash=sha256:ead4b163ac30a29574510cd4b3e2e985ac5290c05fc7095557d6a5f403fc31b5 \ + --hash=sha256:ecd353045824e4477562a2ac718c25799cdaaa41f7aa925a806a8a3e6848a5b9 \ + --hash=sha256:ed2c9e8068b614c574d8d30e543d617cf5379b0535d46f97ef00e904745a08b5 \ + --hash=sha256:ed457d8e98ae812ed7732bef7bf78de78e834eae0372a74e23ca90ef21d910f9 \ + --hash=sha256:ef31cbfe458e21c6122ba8150ff060e0c7789ed0d26eb423f25472584920b555 \ + --hash=sha256:f079e50a0d3cc3cd5091fa9ff45869a2e6b2cd35895731edafb0327901a8d86d \ + --hash=sha256:f3844f134e834076677dd369976e9f5068679fcb8e50102fdf6b7ac96a3ec127 \ + --hash=sha256:f7a7c26137296beba7784de6eba69c6a93a63ccebc385e4962fe67e267a91225 \ + --hash=sha256:fa411799ca8da32a8d38d020a88faa5b6f91657d284761352940ecf9f7c3bbdd \ + --hash=sha256:fd03c4f0e33280d15cae17159b899245d6b7c53d21def19b263b39655061f5ce \ + --hash=sha256:fd190e88a895a8901325fad284a3f74ea52b1da8525b76cc811fa9b1edf0ce2b \ + --hash=sha256:ff8d372ac2acdc048d1c19916f27ee61bc5722728458ba6ca5052f2c72d51763 # via # feast (pyproject.toml) # parsimonious # transformers -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # azure-core + # databricks-sdk # datasets # docker # docling @@ -4685,9 +5295,11 @@ requests==2.32.5 \ # huggingface-hub # jupyterlab-server # kubernetes + # mlflow-skinny # moto # msal # openlineage-python + # pymilvus # python-keycloak # ray # requests-oauthlib @@ -4708,9 +5320,9 @@ requests-toolbelt==1.0.0 \ --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \ --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 # via python-keycloak -responses==0.26.0 \ - --hash=sha256:03ec4409088cd5c66b71ecbbbd27fe2c58ddfad801c66203457b3e6a04868c37 \ - --hash=sha256:c7f6923e6343ef3682816ba421c006626777893cb0d5e1434f674b649bac9eb4 +responses==0.26.1 \ + --hash=sha256:2eb3218553cc8f79b57d257bac23af5e1bf381f5b9390b1767816f0843e01dc2 \ + --hash=sha256:8aacc4586eb08fb2208ef64a9eb4258d9b0c6e6f4260845f2f018ab847495345 # via moto rfc3339-validator==0.1.4 \ --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ @@ -4728,9 +5340,9 @@ rfc3987-syntax==1.1.0 \ --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d # via jsonschema -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework @@ -4854,10 +5466,6 @@ rpds-py==0.30.0 \ # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth rtree==1.4.1 \ --hash=sha256:12de4578f1b3381a93a655846900be4e3d5f4cd5e306b8b00aa77c1121dc7e8c \ --hash=sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0 \ @@ -4875,29 +5483,29 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.5 \ - --hash=sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752 \ - --hash=sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681 \ - --hash=sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204 \ - --hash=sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c \ - --hash=sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd \ - --hash=sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080 \ - --hash=sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74 \ - --hash=sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2 \ - --hash=sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe \ - --hash=sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010 \ - --hash=sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8 \ - --hash=sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca \ - --hash=sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2 \ - --hash=sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b \ - --hash=sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65 \ - --hash=sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a \ - --hash=sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d \ - --hash=sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440 +ruff==0.15.16 \ + --hash=sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a \ + --hash=sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3 \ + --hash=sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071 \ + --hash=sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec \ + --hash=sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628 \ + --hash=sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8 \ + --hash=sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e \ + --hash=sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2 \ + --hash=sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb \ + --hash=sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123 \ + --hash=sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121 \ + --hash=sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951 \ + --hash=sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf \ + --hash=sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb \ + --hash=sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d \ + --hash=sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78 \ + --hash=sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a \ + --hash=sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4 # via feast (pyproject.toml) -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 safetensors[torch]==0.7.0 \ --hash=sha256:0071bffba4150c2f46cae1432d31995d77acfd9f8db598b5d1a2ce67e8440ad2 \ @@ -4984,7 +5592,11 @@ scikit-learn==1.7.2 \ --hash=sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b \ --hash=sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615 \ --hash=sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33 - # via feast (pyproject.toml) + # via + # feast (pyproject.toml) + # mlflow + # sentence-transformers + # skops scipy==1.15.3 \ --hash=sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477 \ --hash=sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c \ @@ -5036,8 +5648,11 @@ scipy==1.15.3 \ # docling # easyocr # great-expectations + # mlflow # scikit-image # scikit-learn + # sentence-transformers + # skops semchunk==3.2.5 \ --hash=sha256:ee15e9a06a69a411937dd8fcf0a25d7ef389c5195863140436872a02c95b0218 \ --hash=sha256:fd09cc5f380bd010b8ca773bd81893f7eaf11d37dd8362a83d46cedaf5dae076 @@ -5046,6 +5661,10 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server +sentence-transformers==5.5.1 \ + --hash=sha256:02b7740dfc60bdbbcb6061625f5d97a5c1a4e2d3baac5f9391b912bb5eae2290 \ + --hash=sha256:4fe11d433badc5282d32f7fc08bc714216b7a5aca426f9df77a45a554756deb7 + # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ --hash=sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173 @@ -5057,8 +5676,8 @@ setuptools==80.10.2 \ # pbr # pip-tools # pydata-google-auth - # pymilvus # singlestoredb + # torch shapely==2.1.2 \ --hash=sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9 \ --hash=sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b \ @@ -5141,6 +5760,14 @@ six==1.17.0 \ # python-dateutil # rfc3339-validator # thriftpy2 +skops==0.14.0 \ + --hash=sha256:60a5db78a9db46ccee2139a0ba13ab5afb1c96f4749b382e75a371291bbe3e36 \ + --hash=sha256:6c8c0e047f691a3a582c3258943eecafcbfd79c8c7eef66260f3703e363254f0 + # via mlflow +smmap==5.0.3 \ + --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ + --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f + # via gitdb sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc @@ -5148,45 +5775,45 @@ sniffio==1.3.1 \ # elastic-transport # elasticsearch # httpx -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.0.0 \ - --hash=sha256:0c0204f639fddc58452b0362ba8821cd5153bd7aaa89434d59104bc39f4fa176 \ - --hash=sha256:1ca2503f705627f7e045da6254d97c37210a3b0a18b43d0f1b29616d0c7aaa01 \ - --hash=sha256:1fea301e3d1e8022b9f2ff87dc3be139d5ed7be5e85fab8a6c59d400a02e6d58 \ - --hash=sha256:2c3e0f6d103fe67c975550ed424f579d3e7ae503d56467e5549f3a1a1e0e8f24 \ - --hash=sha256:4106a66e770e564b3037457b7b01b15ca28aee61afb88560b664aa8af439b533 \ - --hash=sha256:4b10a865c4a5e1fa60c365c7fe41e0433605e6e5edc824e8730a9038f330b3a6 \ - --hash=sha256:4e8c3d2ea4055dd4aecc93514030341e300f557f2e86ca21eb47568c461a6f56 \ - --hash=sha256:54e648bbd506a0f2f8076f9eafe231b2d4284b1a884528c3a0690391ab2bb54e \ - --hash=sha256:5ad5d0f1ebcb2c6b7a7859ee3d4e02203087e40faae539a336bbcb45a3660777 \ - --hash=sha256:65e4e36dd1b0c7235d84cddef8a3c97c5ea0dc8fea85e31e45fc485000b77a83 \ - --hash=sha256:7789df78f7c7abfb351f2709258d05a94652cfe3c2c617fb15f15a11fc1b7b25 \ - --hash=sha256:79b4e7a58e600419f083a63f99e5da89d438faddae1d344e9f9b003754fa231b \ - --hash=sha256:835161dd46ef8f5fc9d2f135ca654c2f3fbdf57b035d3e1980506aa8eac671dc \ - --hash=sha256:985cd2f8b6b2e663ef30dc59f1ba8c1becff7683ebc51bd7f14b962407a9fa88 \ - --hash=sha256:a790f06808e4481c23cfed1396d2c9a786060ddd62408b1fda1a63e1e6bc4b07 \ - --hash=sha256:af89a9e1355ea4dac7927d2f9bc15b2c81e381ad8bcdf8954ba3dd457a4d51d6 \ - --hash=sha256:b95b29589293ad14d0367428518141995524cfc7dc47d8f3d0c47010f5d974da \ - --hash=sha256:bfd3b8523d7adc830f99c5c4c635689ceca61700a05368d5bbb34c6811f2ec54 \ - --hash=sha256:cd23bff2abc74e34c6123a181c004ead9e6cc8ef2661250892afd64bad24533c \ - --hash=sha256:e376bad497c7932448cc29058e75737f02b3f0e25569de9e4ff0616944b4ceba \ - --hash=sha256:e6132986d6965e4005b0167270612fbc7fa4bc4ef42726a40b85a8f57475a78d \ - --hash=sha256:e8d5b66f283967c700fff2303ac5e52d1a3cf41990a634f121ac8b1f1cd9af10 \ - --hash=sha256:eb1bb9729fd3bfaae22364491cec4816dda380376ac3be4559a6f6949c6d2833 \ - --hash=sha256:ebbdeec0d65c2e3f648c8b05839001c062984959417902717f7fc6eed983211d \ - --hash=sha256:f67d844241a6fed764a8f04d32c0273aedf9159d5162b764748526277c7f8831 \ - --hash=sha256:fd0d2d2c5cfd15f041e8522f5f8bdad0be4de7d805dd1646377fccd6bd404fa8 +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -soupsieve==2.8.3 \ - --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ - --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 +soupsieve==2.8.4 \ + --hash=sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e \ + --hash=sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65 # via beautifulsoup4 sphinx==6.2.1 \ --hash=sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b \ @@ -5216,77 +5843,98 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb - # via feast (pyproject.toml) -sqlglot[rs]==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb + # via + # feast (pyproject.toml) + # alembic + # mlflow +sqlglot[rs]==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via # feast (pyproject.toml) # ibis-framework +sqlglotc==30.9.0 \ + --hash=sha256:197f30830a4c40d39655e9d97c91b179dcd1c88635d34d5281a15536cb04030e \ + --hash=sha256:3f132418f0facde6319611dbaf4d47b6f8a7ca37527cda5337f7253ddbd0f62d \ + --hash=sha256:45e65c77a2a3887934d16421db019a1081403ddc4d2ec359d61971d0ace8f48a \ + --hash=sha256:46f004fda92af8676577171e2172892aced1ec7baa1388b26b25be37e980164f \ + --hash=sha256:54788de9eac748135afc322e0385a040296fb6e35fabd213f3387e09821eab50 \ + --hash=sha256:65a84bc3cca32acef23f3b7366cd85eece18536eac41bd364a87d64fcee97470 \ + --hash=sha256:7848eb58afdf74e056cf3fbbc8ea4c70b94e6a106d967c7abc628ed8f2acefc8 \ + --hash=sha256:8060a9446768b810d4f89e1263b04ffdacc67a2c1711aa4af9e7d22be4ac59ed \ + --hash=sha256:88c98db55e0f673f4bd80f2662a07bc234e9a37d321a1044ca6ff2f3598d42db \ + --hash=sha256:955c58c5fe0b555304fed58c5bf960a27211cfba2fb0ff0ead6a8253a35b6e17 \ + --hash=sha256:ab1763090f60581bdabf304c86ef465d3b019244c0b7610db15562bb52688d70 \ + --hash=sha256:b7d8aff3f33f2930dbdc6b7de875d3c22414528755631f3183d1e982fd7ae255 \ + --hash=sha256:c4879678e5bca435245951669ce8790651e9806760fbbbe48772440c9f392b43 \ + --hash=sha256:d57133358daec2003a86f533ca5c38306680cdc60d71e3d25174b182da667b45 \ + --hash=sha256:d98f26796bc4ab5f0fc2c9ac5eae9dc6ca2d8793abcdffab0a3f8937f9d27ff0 \ + --hash=sha256:e1829f6d77b1de1c7481ea289ee1615c1ca9e37149cbd20663742bd42f1cfe2a \ + --hash=sha256:e1c79d46e1733a53c97a78fea76cad6e45e922058afa948e60b796b3546182a3 \ + --hash=sha256:ee104e4781b4ee656c7461056e8a1ca34dcd0256ade5db5bb8d5eaf4b470ac12 \ + --hash=sha256:f932992dea9fbdf797cc40da1752e2df423867d0e5de98663f0136822224293e \ + --hash=sha256:faa3ec4c15894d70341390db2a0b890c92f57c79a0398f7f954f345aea59060a \ + --hash=sha256:fcea2b7d0dca702f2c0f0af41da8552c39a749f2e63d66757c947f97344ab11f + # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ --hash=sha256:ad1ad158234af0f8ba5054ca51bd17a7c1e3f81b4798c7970ebf7953fe08ddcb @@ -5302,20 +5950,26 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sqlparse==0.5.5 \ + --hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \ + --hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e + # via mlflow-skinny +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 # via ipython -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp + # mlflow-skinny # sse-starlette sympy==1.14.0 \ --hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \ @@ -5338,9 +5992,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc3 \ + --hash=sha256:2a9dad9a10ef1aff91c3df43b7387768ed16616d83bc591b92cefd54d3426faf \ + --hash=sha256:9e8a1ca7b15d3cbd907dec45d5823f512a01b67cc22d9db6af86fa41b47e561b # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -5355,14 +6009,18 @@ thriftpy2==0.6.0 \ --hash=sha256:1245c36b82f34aa26f049e6529f40ad34d9be8d12bd0131559847c8476b98ce0 \ --hash=sha256:151d299e8e3694a6cc0f2f2cda01d5744080742649de958c5cdcbebb4306205f \ --hash=sha256:16eecfd34bd541b75172ba0d69ea90b874611a7361d18906fb6d95955089cc30 \ + --hash=sha256:182f54a7248c8ecf1320cf26d1fc9115765df6b1f2589c1d2d0df7049a5b27d4 \ --hash=sha256:210345281d41b3a76d263b555d3e3cc482103738441bdb92a73033a4e9a042e1 \ --hash=sha256:265588b8cdb3fe1097db43bf35fb208edc69d9350a2bec3a737d6357d0a5650d \ --hash=sha256:28fd55960a6d42207060536109928a4615fbbd6874c0ddd8a705b47075f1d2d0 \ --hash=sha256:29ff125e40c8016b4d3bf48e6d727bd93d2892451b47bfe57ba896944ecbdb0c \ --hash=sha256:2ae866adf9b112c7ab30c1a90d878a5d6f2d40244fbc46ec8477425d802f4ac5 \ --hash=sha256:2bf891c2d441b1edddfc62f16ab3031ac7506cba5b77680654179dbe93d8b7ec \ + --hash=sha256:2c88b0d356ea18ce026a52aa7c2110693db77fd52d5ac7553616635a7f165bbd \ --hash=sha256:3090d9cabc2c31c92ae943f36d539a20adfd82697f50e996ce94f0b279e9e1e4 \ + --hash=sha256:3359a7c4eb4c281bf54bd760dcc03c43299f0d529dd2a5018be2f1fbebf0cbbd \ --hash=sha256:375cca06f36f54339838c7f8251b64a777d5ff1277f8b91999487fad1a8e2d73 \ + --hash=sha256:386d8c4a5677fd94fd16c1af2adf39f59698af1e4ef0c3c026083f278540e352 \ --hash=sha256:44365bb5098d0a91c44382e7df0ad44d5b9a588d29d9071aca4a2867f704aaf1 \ --hash=sha256:443e502b428d325c57aec0947991857e8dc0589d0464181f35bd48f870cd5d18 \ --hash=sha256:4550cbb6629c9f6186ab22cb497f262408e1a90ae10b8653599f2717f518f0df \ @@ -5379,6 +6037,7 @@ thriftpy2==0.6.0 \ --hash=sha256:851981ded8bb42da66213cf95d1dd5eaf06c5d6b3a95725a18eddd58ec992b6b \ --hash=sha256:852e538b4866ed776126349161d9fdc37387b1e15ab46805f98dcdee25fee4b5 \ --hash=sha256:8b19d19661fc9a71f19b7c432c413ab65025e5dd11fbd192bd9169afb13b9ce0 \ + --hash=sha256:8e62d9c36bcfe6b85bec7b754accb97e2fa7b6a7c9a0c37f824d85eba699e7b8 \ --hash=sha256:8eb0566b4501c27ea51f2e593531122703946969564fe526a5ff1b18be0ad49a \ --hash=sha256:8f393607d54091e8976e297f8fd7399606d12cd8c2b8852353f07ad5ddac4224 \ --hash=sha256:91df1fa70a99ac08dc449d6fda24a14992a1836d571928f217c40c66fd63fcc8 \ @@ -5393,14 +6052,17 @@ thriftpy2==0.6.0 \ --hash=sha256:b361152c24fd5c791220de9966b00696578c9884a2bb67e4759d4dfe05fd7049 \ --hash=sha256:b51b5259dc344482ab21b768dfc7f54d51d9133665e72890831725068f69f24a \ --hash=sha256:b57f367d7b0e1bc9e5c9b0ff34febdb3fe440f1fe8d75903ae71301bc06072c0 \ + --hash=sha256:b8dc65d2e7951b7e81c17b92857db7c19d6b3dd442d2d8600b5bd5040aa43ce6 \ --hash=sha256:bc320e960347e5f9d27e8b4a9fc7044b2b26bfe4522bb4957e741fc1d1ebd2f0 \ --hash=sha256:bdf77ba7a8987a239eb57cf840d62669741f8b92b61a617e63898caed31da898 \ --hash=sha256:bf96b64400da2f411b43c4c81c2e20b09e3300d86766a52f42393696c8962f11 \ --hash=sha256:c37f5dbfe95579549485c33167854784358f559feda703ccc058719ca0efd8aa \ --hash=sha256:c41312c6edad5e875613719236f1ca6bba9310df40b1adc9308248e1bdb7a1ea \ + --hash=sha256:cafa1d43bcc69129a4855fd3973ab7983bb2274c407e5ff572af5dc196e00313 \ --hash=sha256:cb98556e919be3e6ba9bca629dbddccfaa33b95a0fe7503052849b124e4f88cd \ --hash=sha256:cd2e2c4dcc30c373e317d39b044afa6d9a090bec11d186f25841f70bc520bbb5 \ --hash=sha256:e6c4fb1e7f51f8858f348ed9c31bb408b61274942d18b549ec163bb480c987a0 \ + --hash=sha256:eccab0281667caab0c055882b3bbb8e346bb0181e55f37477e3e5e3f5b7a96dd \ --hash=sha256:f59f74c3779aa47223ba0a9e23ef10d2af5a873ed3624c78303f62a679d1b63e \ --hash=sha256:f6b86112cca7bd04151ce248d781763ea5f74cc18d148476c6d16cee32db81ac \ --hash=sha256:f837ab85ae93b118766b8b28a1cec47a1daddee303e1f986a595c56379062a5c @@ -5409,13 +6071,13 @@ tifffile==2025.5.10 \ --hash=sha256:018335d34283aa3fd8c263bae5c3c2b661ebc45548fde31504016fcae7bf1103 \ --hash=sha256:e37147123c0542d67bc37ba5cdd67e12ea6fbe6e86c52bee037a9eb6a064e5ad # via scikit-image -timm==1.0.25 \ - --hash=sha256:47f59fc2754725735cc81bb83bcbfce5bec4ebd5d4bb9e69da57daa92fcfa768 \ - --hash=sha256:bef7f61dd717cb2dbbb7e326f143e13d660a47ecbd84116e6fe33732bed5c484 +timm==1.0.27 \ + --hash=sha256:315dfe63186ca9fb7ff941268941231fd5be259f2b4bb4afa28560ae1015cb9a \ + --hash=sha256:5ff07c9ddf53cbada88eab1c93ff175c64cab683b5a2fddf863bcee985926f89 # via feast (pyproject.toml) -tinycss2==1.4.0 \ - --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ - --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 +tinycss2==1.5.1 \ + --hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \ + --hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957 # via bleach tokenizers==0.22.2 \ --hash=sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113 \ @@ -5447,55 +6109,56 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 - # via +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 + # via + # alembic # build # coverage # fastapi-mcp @@ -5505,9 +6168,9 @@ tomli==2.4.0 \ # pytest # pytest-env # singlestoredb -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -5517,94 +6180,89 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -torch==2.10.0 \ - --hash=sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574 \ - --hash=sha256:233aed0659a2503b831d8a67e9da66a62c996204c0bba4f4c442ccc0c68a3f60 \ - --hash=sha256:29b7009dba4b7a1c960260fc8ac85022c784250af43af9fb0ebafc9883782ebd \ - --hash=sha256:2b980edd8d7c0a68c4e951ee1856334a43193f98730d97408fbd148c1a933313 \ - --hash=sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547 \ - --hash=sha256:3202429f58309b9fa96a614885eace4b7995729f44beb54d3e4a47773649d382 \ - --hash=sha256:3282d9febd1e4e476630a099692b44fdc214ee9bf8ee5377732d9d9dfe5712e4 \ - --hash=sha256:35e407430795c8d3edb07a1d711c41cc1f9eaddc8b2f1cc0a165a6767a8fb73d \ - --hash=sha256:418997cb02d0a0f1497cf6a09f63166f9f5df9f3e16c8a716ab76a72127c714f \ - --hash=sha256:5276fa790a666ee8becaffff8acb711922252521b28fbce5db7db5cf9cb2026d \ - --hash=sha256:5c4d217b14741e40776dd7074d9006fd28b8a97ef5654db959d8635b2fe5f29b \ - --hash=sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf \ - --hash=sha256:6021db85958db2f07ec94e1bc77212721ba4920c12a18dc552d2ae36a3eb163f \ - --hash=sha256:6528f13d2a8593a1a412ea07a99812495bec07e9224c28b2a25c0a30c7da025c \ - --hash=sha256:682497e16bdfa6efeec8cde66531bc8d1fbbbb4d8788ec6173c089ed3cc2bfe5 \ - --hash=sha256:6b71486353fce0f9714ca0c9ef1c850a2ae766b409808acd58e9678a3edb7738 \ - --hash=sha256:6d3707a61863d1c4d6ebba7be4ca320f42b869ee657e9b2c21c736bf17000294 \ - --hash=sha256:71283a373f0ee2c89e0f0d5f446039bdabe8dbc3c9ccf35f0f784908b0acd185 \ - --hash=sha256:716b01a176c2a5659c98f6b01bf868244abdd896526f1c692712ab36dbaf9b63 \ - --hash=sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb \ - --hash=sha256:a2f9edd8dbc99f62bc4dfb78af7bf89499bca3d753423ac1b4e06592e467b763 \ - --hash=sha256:a4be6a2a190b32ff5c8002a0977a25ea60e64f7ba46b1be37093c141d9c49aeb \ - --hash=sha256:aae1b29cd68e50a9397f5ee897b9c24742e9e306f88a807a27d617f07adb3bd8 \ - --hash=sha256:aaf663927bcd490ae971469a624c322202a2a1e68936eb952535ca4cd3b90444 \ - --hash=sha256:b7bd80f3477b830dd166c707c5b0b82a898e7b16f59a7d9d42778dd058272e8b \ - --hash=sha256:bf0d9ff448b0218e0433aeb198805192346c4fd659c852370d5cc245f602a06a \ - --hash=sha256:c2ee399c644dc92ef7bc0d4f7e74b5360c37cdbe7c5ba11318dda49ffac2bc57 \ - --hash=sha256:cdf2a523d699b70d613243211ecaac14fe9c5df8a0b0a9c02add60fb2a413e0f \ - --hash=sha256:d8f5912ba938233f86361e891789595ff35ca4b4e2ac8fe3670895e5976731d6 \ - --hash=sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e \ - --hash=sha256:f5ab4ba32383061be0fb74bda772d470140a12c1c3b58a0cfbf3dae94d164c28 \ - --hash=sha256:ff43db38af76fda183156153983c9a096fc4c78d0cd1e07b14a2314c7f01c2c8 +torch==2.12.0 \ + --hash=sha256:10802fd383bbfed646212e765a72c37d2185205d4f26eb197a254e8ac7ddcb25 \ + --hash=sha256:10ee1448a9f304d3b987eb4656f664ba6e4d7b410ca7a5a7c642199777a2cf88 \ + --hash=sha256:1834bd984f8a2f4f16bdfbeecca9146184b220aa46276bf5756735b5dae12812 \ + --hash=sha256:2140e373e9a51a3e22ef62e8d14366d0b470d18f0adf19fdc757368077133a34 \ + --hash=sha256:3fee918902090ade827643e758e98363278815de583c75d111fdd665ebffde9f \ + --hash=sha256:415c1b8d0412f67551c8e89a2daca0fb3e56694af0281ba155eaa9da481f58b4 \ + --hash=sha256:4b4f64c2c2b11f7510d93dd6412b87025ff6eddd6bb61c3b5a3d892ea20c4756 \ + --hash=sha256:5d6b560dfa7d56291c07d615c3bb73e8d9943d9b6d87f76cd0d9d570c4797fa6 \ + --hash=sha256:5f96b63f8287f66a005dd1b5a6abba2920f11156c5e5c4d815f3e2050fd1aa16 \ + --hash=sha256:6a7512adfdd7f6732e40de1c620831e3c75b39b98cef60b11d0c5f0a76473ec5 \ + --hash=sha256:864392c73b7654f4d2b3ae712f607937d0dbb1101c4555fbb41848106b297f39 \ + --hash=sha256:891c769072637c74e9a5a77a3bc782894696d8ffec83b938df8536dee7f0ba78 \ + --hash=sha256:8b958caff4a14d3a3b0b2dfc6a378f64dda9728a9dad28c08a0db9ce4dafb549 \ + --hash=sha256:8fbef9f108a863e7722a73740998967e3b074742a834fc5be3a535a2befa7057 \ + --hash=sha256:90dd587a5f61bfe1307148b581e2084fc5bc4a06e2b90a20e9a36b81087ff16b \ + --hash=sha256:a43ac605a5e13116c72b64c359644cce0229f213dde48d2ae0ae5eb5becf7feb \ + --hash=sha256:a6a2eebb237d3b1d9ad3b378e86d9b9e0782afdea8b1e0eba6a13646b9b49c07 \ + --hash=sha256:af68dbf403439cae9ceaeaaf92f8352b460787dcd27b92aa05c40dd4a19c0f1e \ + --hash=sha256:b41339df93d491435e790ff8bcbae1c0ce777175889bfd1281d119862793e6a2 \ + --hash=sha256:b4556715c8572758625d62b6e0ae3b1f76c440221913a6fb5e100f321fb4fb02 \ + --hash=sha256:c12592630aef72feaf18bd3f197ef587bbfa21131b31c38b23ab2e55fce92e36 \ + --hash=sha256:c66696857e987efb8bc1777a37357ec4f60ab5e8af6250b83d6034437fa2d8f3 \ + --hash=sha256:cf9839790285dd472e7a16aafcb4a4e6bf58ec1b494045044b0eefb0eb4bd1f2 \ + --hash=sha256:d47e7dee68ac4cd7a068b26bcd6b989935427709fae1c8f7bd0019978f829e15 \ + --hash=sha256:d4d029801cb7b6df858804a2a21b00cc2aa0bf0ee5d2ab18d343c9e9e5681f35 \ + --hash=sha256:dd37188ea325042cb1f6cafa56822b11ada2520c04791a52629b0af25bdfbfd9 \ + --hash=sha256:e2ad3eb85d39c3cab62dfa93ed5a73516e6a53c6713cb97d004004fe089f0f1f \ + --hash=sha256:f7dfae4a519197dfa050e98d8e36378a0fb5899625a875c2b54445005a2e404e # via # feast (pyproject.toml) # accelerate # docling-ibm-models # easyocr # safetensors + # sentence-transformers # timm # torchvision -torchvision==0.25.0 \ - --hash=sha256:0b5e7f50002a8145a98c5694a018e738c50e2972608310c7e88e1bd4c058f6ce \ - --hash=sha256:0d9a3f925a081dd2ebb0b791249b687c2ef2c2717d027946654607494b9b64b6 \ - --hash=sha256:146d02c9876858420adf41f3189fe90e3d6a409cbfa65454c09f25fb33bf7266 \ - --hash=sha256:153c0d2cbc34b7cf2da19d73450f24ba36d2b75ec9211b9962b5022fb9e4ecee \ - --hash=sha256:24e11199e4d84ba9c5ee7825ebdf1cd37ce8deec225117f10243cae984ced3ec \ - --hash=sha256:40a122c3cf4d14b651f095e0f672b688dde78632783fc5cd3d4d5e4f6a828563 \ - --hash=sha256:5e6b449e9fa7d642142c0e27c41e5a43b508d57ed8e79b7c0a0c28652da8678c \ - --hash=sha256:5f271136d2d2c0b7a24c5671795c6e4fd8da4e0ea98aeb1041f62bc04c4370ef \ - --hash=sha256:620a236288d594dcec7634c754484542dc0a5c1b0e0b83a34bda5e91e9b7c3a1 \ - --hash=sha256:632db02300e83793812eee4f61ae6a2686dab10b4cfd628b620dc47747aa9d03 \ - --hash=sha256:846890161b825b38aa85fc37fb3ba5eea74e7091ff28bab378287111483b6443 \ - --hash=sha256:855c0dc6d37f462482da7531c6788518baedca1e0847f3df42a911713acdfe52 \ - --hash=sha256:a8f8061284395ce31bcd460f2169013382ccf411148ceb2ee38e718e9860f5a7 \ - --hash=sha256:a95c47abb817d4e90ea1a8e57bd0d728e3e6b533b3495ae77d84d883c4d11f56 \ - --hash=sha256:acc339aba4a858192998c2b91f635827e40d9c469d9cf1455bafdda6e4c28ea4 \ - --hash=sha256:ad9a8a5877782944d99186e4502a614770fe906626d76e9cd32446a0ac3075f2 \ - --hash=sha256:b57430fbe9e9b697418a395041bb615124d9c007710a2712fda6e35fb310f264 \ - --hash=sha256:b75deafa2dfea3e2c2a525559b04783515e3463f6e830cb71de0fb7ea36fe233 \ - --hash=sha256:c2abe430c90b1d5e552680037d68da4eb80a5852ebb1c811b2b89d299b10573b \ - --hash=sha256:c4d395cb2c4a2712f6eb93a34476cdf7aae74bb6ea2ea1917f858e96344b00aa \ - --hash=sha256:cef0196be31be421f6f462d1e9da1101be7332d91984caa6f8022e6c78a5877f \ - --hash=sha256:d1abd5ed030c708f5dbf4812ad5f6fbe9384b63c40d6bd79f8df41a4a759a917 \ - --hash=sha256:db74a551946b75d19f9996c419a799ffdf6a223ecf17c656f90da011f1d75b20 \ - --hash=sha256:ea580ffd6094cc01914ad32f8c8118174f18974629af905cea08cb6d5d48c7b7 \ - --hash=sha256:f07f01d27375ad89d72aa2b3f2180f07da95dd9d2e4c758e015c0acb2da72977 \ - --hash=sha256:f25aa9e380865b11ea6e9d99d84df86b9cc959f1a007cd966fc6f1ab2ed0e248 \ - --hash=sha256:f49964f96644dbac2506dffe1a0a7ec0f2bf8cf7a588c3319fed26e6329ffdf3 \ - --hash=sha256:f9c55ae8d673ab493325d1267cbd285bb94d56f99626c00ac4644de32a59ede3 +torchvision==0.27.0 \ + --hash=sha256:0822b58d2c5d325cd0c7152b744acbd15f898c07572e2cfb70b075a865a4f6f9 \ + --hash=sha256:1a6dd742a150645126df9e0b2e449874c1d635897c773b322c2e067e98382dfe \ + --hash=sha256:1c01f0d1091ae22b9dfc082b0a0fe5faaf053686a29b4fb082ba7691375c73cf \ + --hash=sha256:1c2db4bde82bc48ebff73436a6adf34d4f809448268a70d9a1285f5c8f92313d \ + --hash=sha256:2664d06acd64d328aa7689b0d0c81ee31e240e9977d8768816b4be7c66c03211 \ + --hash=sha256:2c037709072ca9b19750c0cbe9e8bb6f91c9a1be1befa26df33e281deccbd8c7 \ + --hash=sha256:2c4099a15150143b9b034730b404a56d572efe0b79489b4c765d929cb4eac7f3 \ + --hash=sha256:419c98a9275b27660cdce6d09080fd5974d1ec1d4a225f71439ebacb3b0c4e64 \ + --hash=sha256:41d6dae73e1af09fa82ded597ae57f2a2314285acde54b25890a8f8e51b999d7 \ + --hash=sha256:5bb82fc3c55daf1788621e504310b0a286f1069627a8742f692aebb075ef25a7 \ + --hash=sha256:65772ff3ec4f4f5d680e30019835555dd239e7fefee4b0a846375fe1cb1592ef \ + --hash=sha256:70f071c6f74b60d5fe8851636d8d4cd5f4fa29d57fd9348a87a6f17b990b95ba \ + --hash=sha256:72bf547e58ddb948689734eed6f4b6a2031f979dba4fb08e3690688b392e929f \ + --hash=sha256:7a9966a088d06b4cf6c610e03be62de469efa6f2cd2e7c7eed8e925ed6af59ac \ + --hash=sha256:91f61b9865423037c327eb56afa207cc72de874e458c361840db9dcf5ce0c0eb \ + --hash=sha256:9bb9251f64b854124efed95d02953a89f7e2726c3ca662d7ea0151129157297f \ + --hash=sha256:a49e55055a39a8506fe7e59850522cab004efb2c3839f6057658889c1d69c815 \ + --hash=sha256:aaafa6962c9d91f42503de1957d6fa349907d028c06f335bd95da7a5bc57147d \ + --hash=sha256:aee384a2782c89517c4ab9061d2720ba59fd2ffe5ef89d0a149cc2d43abdf521 \ + --hash=sha256:b4aacff70ea4b7377f996f9048989c850d221fef33658ddbcae42aa5bd4ca11a \ + --hash=sha256:b4c6bb0a670dcba017b3643e21902c9b8a1cc1c127d602f1488fa29ec3c6e865 \ + --hash=sha256:c1fac0fc2a7adf29481fc1938a0e7845c57ba1147a986784109c4d98f434ea8c \ + --hash=sha256:c5121f1b9ab09a7f73e837871deb8321551f7eaeb19d87aa00de9191968eae44 \ + --hash=sha256:c9f44e35e6ec01caedacce9e941a5bf21fe424403321efac2507a201273653c5 \ + --hash=sha256:cbf89764fc76f3f17fbf80c12d5a89c691e91cb9d82c38412aaf0568655ffb19 \ + --hash=sha256:dadea3c5ecfd05bbb2a3312ab0374f213c58bf6459cb059122e2f4dfe13d10ed \ + --hash=sha256:df0c166b6bdf7c47f88e81e8b43bc085451d5c50d0c5d1691bc474c1227d6fed \ + --hash=sha256:f44453f107c296d5446a79f7ac59733ad8bf5ddfa04c53805dfbae298a42a798 # via # feast (pyproject.toml) # docling-ibm-models # easyocr # timm -tornado==6.5.4 \ - --hash=sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1 \ - --hash=sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1 \ - --hash=sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 \ - --hash=sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335 \ - --hash=sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8 \ - --hash=sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f \ - --hash=sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84 \ - --hash=sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7 \ - --hash=sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17 \ - --hash=sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 \ - --hash=sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f \ - --hash=sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc +tornado==6.5.6 \ + --hash=sha256:1c34cfab7ad6d104f052f55de06d39bbafc5885cfeb4da688803308dbcfa90b7 \ + --hash=sha256:2543597b24a695d72338a9a77818362d72387c03ae173f1f169eadc5c91466ac \ + --hash=sha256:385f35e4e22fb52551dfcda4cdc8c30c61c2c001aef5ddad99cdfe116952efd3 \ + --hash=sha256:38bc01b4acacded2de63ae78023548e41ebe6fbed3ec05a796d7ae3ad893887e \ + --hash=sha256:65fcfaafb079435c2c19dc9e07c0f1cf0fa9051759ed0a7d0a3ba7ea7f64919c \ + --hash=sha256:6739bf1e8eb09230f1280ddbd3236f0309db70f2c551a8dbc40f62babdf82f79 \ + --hash=sha256:8666946e70171b8c3f1fc9b7876fac492e84822c4c7f3746f4e8f8bc9ac92a79 \ + --hash=sha256:9a365179fe8ff6b8766f602c0f67c185d778193e9bdd828b19f0b6ed7764177d \ + --hash=sha256:b942e6a137fda31ff54bf8e6e2c8d1c37f1f50583f3ed53fb840b53b9601d104 \ + --hash=sha256:db475f1b67b2809b10bb16264829087724ca8d24fe4ed47f7b8675cae453ef86 # via # ipykernel # jupyter-client @@ -5612,9 +6270,9 @@ tornado==6.5.4 \ # jupyterlab # notebook # terminado -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # datasets @@ -5625,10 +6283,11 @@ tqdm==4.67.3 \ # milvus-lite # mpire # semchunk + # sentence-transformers # transformers -traitlets==5.14.3 \ - --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ - --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f +traitlets==5.15.1 \ + --hash=sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92 \ + --hash=sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722 # via # ipykernel # ipython @@ -5649,6 +6308,7 @@ transformers==4.57.6 \ # feast (pyproject.toml) # docling-core # docling-ibm-models + # sentence-transformers tree-sitter==0.25.2 \ --hash=sha256:0628671f0de69bb279558ef6b640bcfc97864fe0026d840f872728a86cd6b6cd \ --hash=sha256:0c8b6682cac77e37cfe5cf7ec388844957f48b7bd8d6321d0ca2d852994e10d5 \ @@ -5687,15 +6347,16 @@ tree-sitter==0.25.2 \ --hash=sha256:fbb1706407c0e451c4f8cc016fec27d72d4b211fdd3173320b1ada7a6c74c3ac \ --hash=sha256:fe43c158555da46723b28b52e058ad444195afd1db3ca7720c59a254544e9c20 # via docling-core -tree-sitter-c==0.24.1 \ - --hash=sha256:290bff0f9c79c966496ebae45042f77543e6e4aea725f40587a8611d566231a8 \ - --hash=sha256:789781afcb710df34144f7e2a20cd80e325114b9119e3956c6bd1dd2d365df98 \ - --hash=sha256:7d2d0cda0b8dda428c81440c1e94367f9f13548eedca3f49768bde66b1422ad6 \ - --hash=sha256:942bcd7cbecd810dcf7ca6f8f834391ebf0771a89479646d891ba4ca2fdfdc88 \ - --hash=sha256:9a74cfd7a11ca5a961fafd4d751892ee65acae667d2818968a6f079397d8d28c \ - --hash=sha256:9c06ac26a1efdcc8b26a8a6970fbc6997c4071857359e5837d4c42892d45fe1e \ - --hash=sha256:a6a807705a3978911dc7ee26a7ad36dcfacb6adfc13c190d496660ec9bd66707 \ - --hash=sha256:d46bbda06f838c2dcb91daf767813671fd366b49ad84ff37db702129267b46e1 +tree-sitter-c==0.24.2 \ + --hash=sha256:1628584df0299b5a340aa63f8e67b6c97c91517f52fa7e7a4c557e40adb330a9 \ + --hash=sha256:4a2f4371cd816cc3153458f69062135ebb2ea5f275ddd90494e5c823d778204a \ + --hash=sha256:4d4579a8b54f0a442f903d88d3304cab77cd5c2031d4015baa4f2f8e15d6dcb7 \ + --hash=sha256:5041ef67eb68ce6bc8bb0b1f8ef3a5585ce523dae0c7eec109ab0627dd75aede \ + --hash=sha256:82842c5a5f2acd93f4de10038c33ac179c8979defc39376f990348d6289e933b \ + --hash=sha256:97bc80a224d48215d4e6e6376bf30d114f4c317b8145ff1b02afe785d4ba7bdd \ + --hash=sha256:abb549225091f7b25df2dd3a0143ece6e208f7055d8bcb4700b41ee79b9ef1e1 \ + --hash=sha256:c098bedcd5ac86ff93fa734d51d1dd86aed40fd5ed7d634c7af11380a0469969 \ + --hash=sha256:e2b42e8e22202c251f8629306f9321233542e07a6e01611b5fe83489272143eb # via docling-core tree-sitter-javascript==0.25.0 \ --hash=sha256:199d09985190852e0912da2b8d26c932159be314bc04952cf917ed0e4c633e6b \ @@ -5733,9 +6394,9 @@ trino==0.337.0 \ --hash=sha256:3a0bd03a09b7ea5dccd41ca6e58abfb127c6303f3a48a258ff794d411dd83a3c \ --hash=sha256:868f2b8137d4d1baa84c9bc341f2cdf29039462aa69d7c089a0b821b5a91f29c # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typer==0.12.5 \ --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ @@ -5744,9 +6405,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==1.17.0.20260307 \ - --hash=sha256:1a4f1168d43ed8cd2b0ed40a3eb870cda685a154d98478b0a65862084f190a02 \ - --hash=sha256:89b5b2c798d32fc6e3304903ed99af93fd608b741483ce7d57fa69eda40430e5 +types-cffi==2.0.0.20260518 \ + --hash=sha256:5b68a215a95d0eac4203b58e766ff7fe40c2e091b1fa1a9e54111f04cc560084 \ + --hash=sha256:f9707e66c13454789a58f8843d1ded4a66f1e9c8b10bd24d5eb5e0f25c0c5472 # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -5754,25 +6415,25 @@ types-protobuf==3.19.22 \ # via # feast (pyproject.toml) # mypy-protobuf -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) types-pyopenssl==24.1.0.20240722 \ --hash=sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39 \ --hash=sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54 # via types-redis -types-python-dateutil==2.9.0.20260305 \ - --hash=sha256:389717c9f64d8f769f36d55a01873915b37e97e52ce21928198d210fbd393c8b \ - --hash=sha256:a3be9ca444d38cadabd756cfbb29780d8b338ae2a3020e73c266a83cc3025dd7 +types-python-dateutil==2.9.0.20260518 \ + --hash=sha256:51f02dc03b61c7f6a07df45797d4dfe8a1aa47f0b7db9ad89f6fd3a1a70e1b51 \ + --hash=sha256:d6a9c5bd0de61460c8fdef8ab2b400f956a1a1075cce08d4e2b4434e478c50b8 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260304 \ - --hash=sha256:0c3542d8e9b0160b424233440c52b83d6f58cae4b85333d54e4f961cf013e117 \ - --hash=sha256:175332c1cf7bd6b1cc56b877f70bf02def1a3f75e5adcc05385ce2c3c70e6500 +types-pytz==2026.2.0.20260518 \ + --hash=sha256:3a12eaa38f476bd650902a9c9bb442f03f3c7dee2be5c5848bce61bd708d205a \ + --hash=sha256:e5d254329e9c4e91f0781b22c43a4bb2d10bb044d97b24c4b05d45567b0eae16 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260518 \ + --hash=sha256:d2150f75a231c9fe9c7463bd29487d93e60bac90400287351384bc2284eba7cd \ + --hash=sha256:d917f83fb38462550338c1297faedd860b3ec83912b96b1e3d73255f7473e466 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -5782,15 +6443,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260508 \ + --hash=sha256:8e51f159e8b24976849706ae2ed1dc9adba8ebbd080b17e494ebb66a8cc92c74 \ + --hash=sha256:b1e1a2d0456fbd655a71690b09a7aaeffdf2978d32049184ea436492aa51d20a # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -5800,7 +6461,10 @@ typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiobotocore + # aiohttp # aiosignal + # alembic # anyio # async-lru # azure-core @@ -5808,29 +6472,39 @@ typing-extensions==4.15.0 \ # azure-storage-blob # beautifulsoup4 # couchbase-columnar + # cryptography # docling-core # elasticsearch # exceptiongroup # fastapi + # graphene # great-expectations + # grpcio # huggingface-hub # ibis-framework # ipython + # jupyter-client # jwcrypto # mcp # minio # mistune + # mlflow-skinny # multidict # mypy + # opentelemetry-api + # opentelemetry-sdk + # opentelemetry-semantic-conventions # oracledb # psycopg # psycopg-pool # pydantic # pydantic-core + # pyjwt # pyopenssl # python-docx # python-pptx # referencing + # sentence-transformers # snowflake-connector-python # sqlalchemy # starlette @@ -5848,9 +6522,9 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # arrow # ibis-framework @@ -5861,99 +6535,13 @@ tzlocal==5.3.1 \ # via # great-expectations # trino -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus uri-template==1.3.0 \ --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # via jsonschema -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # feast (pyproject.toml) # botocore @@ -5974,6 +6562,7 @@ uvicorn[standard]==0.34.0 \ # feast (pyproject.toml) # fastapi-mcp # mcp + # mlflow-skinny # uvicorn-worker uvicorn-worker==0.3.0 \ --hash=sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b \ @@ -6036,121 +6625,121 @@ virtualenv==20.23.0 \ # via # feast (pyproject.toml) # pre-commit -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn -wcwidth==0.6.0 \ - --hash=sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad \ - --hash=sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159 - # via prompt-toolkit +wcwidth==0.7.0 \ + --hash=sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2 \ + --hash=sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0 + # via + # prettytable + # prompt-toolkit webcolors==25.10.0 \ --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf @@ -6230,13 +6819,16 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -werkzeug==3.1.6 \ - --hash=sha256:210c6bede5a420a913956b4791a7f4d6843a43b6fcee4dfa08a65e93007d0d25 \ - --hash=sha256:7ddf3357bb9564e407607f988f683d72038551200c704012bb9a4c523d42f131 - # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +werkzeug==3.1.8 \ + --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ + --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 + # via + # flask + # flask-cors + # moto +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6244,90 +6836,100 @@ widgetsnbextension==4.0.15 \ --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 # via ipywidgets -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via # aiobotocore + # deprecated # testcontainers xlsxwriter==3.2.9 \ --hash=sha256:254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c \ @@ -6337,281 +6939,304 @@ xmltodict==1.0.4 \ --hash=sha256:6d94c9f834dd9e44514162799d344d815a3a4faec913717a9ecbfa5be1bb8e61 \ --hash=sha256:a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a # via moto -xxhash==3.6.0 \ - --hash=sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad \ - --hash=sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c \ - --hash=sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3 \ - --hash=sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004 \ - --hash=sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b \ - --hash=sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796 \ - --hash=sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f \ - --hash=sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c \ - --hash=sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1 \ - --hash=sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1 \ - --hash=sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0 \ - --hash=sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec \ - --hash=sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d \ - --hash=sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919 \ - --hash=sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67 \ - --hash=sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360 \ - --hash=sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799 \ - --hash=sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679 \ - --hash=sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef \ - --hash=sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d \ - --hash=sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7 \ - --hash=sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8 \ - --hash=sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa \ - --hash=sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e \ - --hash=sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa \ - --hash=sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec \ - --hash=sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4 \ - --hash=sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad \ - --hash=sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7 \ - --hash=sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5 \ - --hash=sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11 \ - --hash=sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae \ - --hash=sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d \ - --hash=sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4 \ - --hash=sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6 \ - --hash=sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df \ - --hash=sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058 \ - --hash=sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850 \ - --hash=sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2 \ - --hash=sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d \ - --hash=sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89 \ - --hash=sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e \ - --hash=sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa \ - --hash=sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6 \ - --hash=sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb \ - --hash=sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3 \ - --hash=sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b \ - --hash=sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4 \ - --hash=sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db \ - --hash=sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119 \ - --hash=sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec \ - --hash=sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518 \ - --hash=sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296 \ - --hash=sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033 \ - --hash=sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729 \ - --hash=sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca \ - --hash=sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063 \ - --hash=sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5 \ - --hash=sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d \ - --hash=sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f \ - --hash=sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8 \ - --hash=sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42 \ - --hash=sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e \ - --hash=sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392 \ - --hash=sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222 \ - --hash=sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f \ - --hash=sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd \ - --hash=sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77 \ - --hash=sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802 \ - --hash=sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d \ - --hash=sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1 \ - --hash=sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41 \ - --hash=sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374 \ - --hash=sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263 \ - --hash=sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71 \ - --hash=sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13 \ - --hash=sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8 \ - --hash=sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc \ - --hash=sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62 \ - --hash=sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11 \ - --hash=sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65 \ - --hash=sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0 \ - --hash=sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b \ - --hash=sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2 \ - --hash=sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788 \ - --hash=sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6 \ - --hash=sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f \ - --hash=sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc \ - --hash=sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e \ - --hash=sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702 \ - --hash=sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 \ - --hash=sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f \ - --hash=sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6 \ - --hash=sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87 \ - --hash=sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3 \ - --hash=sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a \ - --hash=sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b \ - --hash=sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b \ - --hash=sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b \ - --hash=sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8 \ - --hash=sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db \ - --hash=sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99 \ - --hash=sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a \ - --hash=sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2 \ - --hash=sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204 \ - --hash=sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b \ - --hash=sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546 \ - --hash=sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95 \ - --hash=sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9 \ - --hash=sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54 \ - --hash=sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06 \ - --hash=sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c \ - --hash=sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152 \ - --hash=sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86 \ - --hash=sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4 \ - --hash=sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93 \ - --hash=sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd \ - --hash=sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd \ - --hash=sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a \ - --hash=sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2 \ - --hash=sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248 \ - --hash=sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd \ - --hash=sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6 \ - --hash=sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf \ - --hash=sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7 \ - --hash=sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490 \ - --hash=sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0 \ - --hash=sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536 \ - --hash=sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb \ - --hash=sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829 \ - --hash=sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746 \ - --hash=sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07 \ - --hash=sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292 \ - --hash=sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6 \ - --hash=sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd \ - --hash=sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7 \ - --hash=sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d \ - --hash=sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0 \ - --hash=sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee \ - --hash=sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6 +xxhash==3.7.0 \ + --hash=sha256:01cf5c5333aed26cc8d5eea33b8d6398e085e365a704b7372fabdf7ab06441a9 \ + --hash=sha256:030c0fd688fce3569fbb49a2feefd4110cbb0b650186fb4610759ecfac677548 \ + --hash=sha256:03f8ff4474ee61c845758ce00711d7087a770d77efb36f7e74a6e867301000b8 \ + --hash=sha256:040ea63668f9185b92bc74942df09c7e65703deed71431333678fc6e739a9955 \ + --hash=sha256:05ece0fe4d9c9c2728912d1981ae1566cfc83a011571b24732cbf76e1fb70dca \ + --hash=sha256:05fd1254268c59b5cb2a029dfc204275e9fc52de2913f1e53aa8d01442c96b4d \ + --hash=sha256:073c23900a9fbf3d26616c17c830db28af9803677cd5b33aea3224d824111514 \ + --hash=sha256:082c87bfdd2b9f457606c7a4a53457f4c4b48b0cdc48de0277f4349d79bb3d7a \ + --hash=sha256:0c36f89ba026ccc6fde8f48479a2fd9fc450a736cc7c0d5650acfcff8636282e \ + --hash=sha256:0c72fe9c7e3d6dfd7f1e21e224a877917fa09c465694ba4e06464b9511b65544 \ + --hash=sha256:0d23fd49fdc5c8af61fb7104f1ad247954499140f6cb6045b3aa5c99dadbbf28 \ + --hash=sha256:0ff71596bd79816975b3de7130ab1ff4541410285a3c084584eeb1c8239996fd \ + --hash=sha256:1061bc6cec00adf75347b064ee62b220d66d9bc506acaad1418c79eec45a318c \ + --hash=sha256:11dd69b1a34b7b9af29012f390825b0cdb0617c0966560e227ca74daa7478ba9 \ + --hash=sha256:1295325c5a98d552333fa53dc2b026b0ef0ec9c8e73ca3a952990b4c7d65d459 \ + --hash=sha256:12c249621af6d50a05d9f10af894b404157b15819878e18f75fcbb0213a77d07 \ + --hash=sha256:12eca820a5d558633d423bf8bb78ce72a55394823f64089247f788a7e0ae691e \ + --hash=sha256:13805f0461cba0a857924e70ff91ae6d52d2598f79a884e788db80532614a4a1 \ + --hash=sha256:14bf7a54e43825ec131ee7fe3c60e142e7c2c1e676ad0f93fc893432d15414af \ + --hash=sha256:151d7520838d4465461a0b7f4ae488b3b00de16183dd3214c1a6b14bf89d7fb6 \ + --hash=sha256:153c3a4f73563101d4c8102cbff6a5b46f7aa9dbe374eedf1cd3b15fda750566 \ + --hash=sha256:157c49475b34ecea8809e51123d9769a534e139d1247942f7a4bc67710bb2533 \ + --hash=sha256:178959906cb1716a1ce08e0d69c82886c70a15a6f2790fc084fdd146ca30cd49 \ + --hash=sha256:17f8ae90c8e00f225be4899c3023704f23ee6d5638a00c54d6cbe9980068e6f9 \ + --hash=sha256:1910df4756a5ab58cfad8744fc2d0f23926e3efcc346ee76e87b974abab922f4 \ + --hash=sha256:1ad86695c19b1d46fe106925db3c7a37f16be37669dcf58dcc70a9dd6e324676 \ + --hash=sha256:1cc07c639e3a77ef1d32987464d3e408565b8a3be57b545d3542b191054d9923 \ + --hash=sha256:1d398f372496152f1c6933a33566373f8d1b37b98b8c9d608fa6edc0976f23b2 \ + --hash=sha256:2220af08163baf5fa36c2b8af079dc2cbe6e66ae061385267f9472362dfd53c6 \ + --hash=sha256:24cc22070880cc57b830a65cde4e65fa884c6d9b28ae4803b5ee05911e7bafba \ + --hash=sha256:2524a1e20d4c231d13b50f7cf39e44265b055669a64a7a4b9a2a44faa03f19b6 \ + --hash=sha256:2a61e2a3fb23c892496d587b470dee7fa1b58b248a187719c65ea8e94ec13257 \ + --hash=sha256:2d415f18becf6f153046ab6adc97da77e3643a0ee205dae61c4012604113a020 \ + --hash=sha256:31ab1461c77a11461d703c88eb949e132a1c6515933cf675d97ec680f4bd18de \ + --hash=sha256:31e3516a0f829d06ded4a2c0f3c7c5561993256bfa1c493975fb9dc7bfa828a1 \ + --hash=sha256:322b2f0622230f526aeb1738149948a7ae357a9e2ceb1383c6fd1fdaecdafa16 \ + --hash=sha256:3281ba1d1e60ee7a382a7b958513ba03c2c0d5fcbd9a6f7517c0a81251a23422 \ + --hash=sha256:3409b50ddbc76377d938f40a7a4662cd449f743f2c6178fd6162b875bf9b0d4f \ + --hash=sha256:347a93f2b4ce67ce61959665e32a7447c380f8347e55e100daa23766baacf0e5 \ + --hash=sha256:3573a651d146912da9daa9e29e5fbc45994420daaa9ef1e2fa5823e1dc485513 \ + --hash=sha256:363c139bf15e1ac5f136b981d3c077eb551299b1effede7f12faa010b8590a60 \ + --hash=sha256:37d994d0ffe81ef087bb330d392caa809bb5853c77e22ea3f71db024a0543dba \ + --hash=sha256:3afec3a336a2286601a437cb07562ab0227685e6fbb9ec17e8c18457ff348ecf \ + --hash=sha256:3b6b3d28228af044ebcded71c4a3dd86e1dbd7e2f4645bf40f7b5da65bb5fb5a \ + --hash=sha256:3bb5fd680c038fd5229e44e9c493782f90df9bef632fd0499d442374688ff70b \ + --hash=sha256:3beb1de3b1e9694fcdd853e570ee64c631c7062435d2f8c69c1adf809bc086f0 \ + --hash=sha256:3e1860f1e43d40e9d904cf22d93e587ea42e010ebce4160877e46bcab4bc232a \ + --hash=sha256:418a463c3e6a590c0cdc890f8be19adb44a8c8acd175ca5b2a6de77e61d0b386 \ + --hash=sha256:421da671f43a0189b57a4b8be694576308395f92f55ed3badcde67ab95acef81 \ + --hash=sha256:43475925a766d01ca8cd9a857fd87f3d50406983c8506a4c07c4df12adcc867f \ + --hash=sha256:44909f79fb7a4950ec7d96059398f46f634534cd95be9330a3827210af5aaebe \ + --hash=sha256:44fba4a5f1d179b7ddc7b3dc40f56f9209046421679b57025d4d8821b376fd8d \ + --hash=sha256:468f0fc114faaa4b36699f8e328bbc3bb11dc418ba94ac52c26dd736d4b6c637 \ + --hash=sha256:48b542c347c2089f43dc5a6db31d2a6f3cdb04ee33505ec6e9f653834dbb0bde \ + --hash=sha256:496736f86a9bedaf64b0dc70e3539d0766df01c71ea22032698e88f3f04a1ce9 \ + --hash=sha256:49a88183a3e5ab0b69d9bbfc0180cbdb247e8bada19fd9403c538b3aa3c24176 \ + --hash=sha256:49e556558eee5c8c9b2d5da03fd36cfa6c99cae95b3c3887ec64ee1a49ed517a \ + --hash=sha256:4b6d6b33f141158692bd4eafbb96edbc5aa0dabdb593a962db01a91983d4f8fa \ + --hash=sha256:4c2454448ce847c72635827bb75c15c5a3434b03ee1afd28cb6dc6fb2597d830 \ + --hash=sha256:4e15cc9e2817f6481160f930c62842b3ff419e20e13072bcbab12230943092bc \ + --hash=sha256:503722d52a615f2604f5e7611de7d43878df010dc0053094ef91cb9a9ac3d987 \ + --hash=sha256:506a0b488f190f0a06769575e30caf71615c898ed93ab18b0dbcb6dec5c3713c \ + --hash=sha256:50846b9b01f461ee0250d7a701a3d881e9c52ebce335d6e38e0224adc3369f50 \ + --hash=sha256:50e879ebbac351c81565ca108db766d7832f5b8b6a5b14b8c0151f7190028e3d \ + --hash=sha256:54876a4e45101cec2bf8f31a973cda073a23e2e108538dad224ba07f85f22487 \ + --hash=sha256:54a675cb300dda83d71daae2a599389d22db8021a0f8db0dd659e14626eb3ecc \ + --hash=sha256:565df64437a9390f84465dcca33e7377114c7ede8d05cd2cf20081f831ea788e \ + --hash=sha256:5886ad85e9e347911783760a1d16cb6b393e8f9e3b52c982568226cb56927bdc \ + --hash=sha256:5a6ddec83325685e729ca119d1f5c518ec39294212ecd770e60693cdc5f7eb79 \ + --hash=sha256:5b1bde10324f4c31812ae0d0502e92d916ae8917cad7209353f122b8b8f610c3 \ + --hash=sha256:5bf2f1940499839b39fef1561b5ecb6ede9ac34ef4457474e1337fc7ef07c2f3 \ + --hash=sha256:5de686e73690cdaf72b96d4fa083c230ec9020bcc2627ce6316138e2cf2fe2d1 \ + --hash=sha256:5e7ce913b61f35b0c1c839a49ac9c8e75dd8d860150688aed353b0ce1bf409d8 \ + --hash=sha256:5ec1e080a3d02d94ea9335bfab0e3374b877e25411422c18f51a943fa4b46381 \ + --hash=sha256:6318d8b6f6c6c21058928c23289686fc74f37d794170f14b35fecceb515d5e37 \ + --hash=sha256:646a69b56d8145d85f7fd2289d14fba07880c8a5bda406aa256b407481a61f35 \ + --hash=sha256:646b8aa66cf0cec9295dfc4e3ac823ee52e338bada9547f5cf2d674212d04b58 \ + --hash=sha256:6741564a923f082f3c2941c8bb920462ed5b25eaebdd1e161f162233c9a10bc5 \ + --hash=sha256:693d02c6dc7d1aa0a45921d54cd8c1ff629e09dfdc2238471507af1f7a1c6f04 \ + --hash=sha256:6be4d70d9ab76c9f324ead9c01af6ff52c324745ea0c3731682a0cf99720f1fe \ + --hash=sha256:6cc4eefbb542a5d6ffd6d70ea9c502957c925e800f998c5630ecc809d6702bae \ + --hash=sha256:6e83179bbb208fb72774c06ba227d6e410fa3797de33d0d4c00e3935f81da7d2 \ + --hash=sha256:6e934bbae1e0ec74e27d5f0d7f37ef547ce5ff9f0a7e63fb39e559fc99526734 \ + --hash=sha256:6f31143e18e6db136455b16f0e4e6eba943e1889127dd7c649b46a50d54dd836 \ + --hash=sha256:7426ff0dfa76eb47efc2cc59d4a717bfa9dc9938bff5e49e748bca749f6aa616 \ + --hash=sha256:74bbd92f8c7fcc397ba0a11bfdc106bc72ad7f11e3a60277753f87e7532b4d81 \ + --hash=sha256:7553816512c0abb75329c163a1eee77b0802c3757054b910d6e547bd0dbd16b7 \ + --hash=sha256:79f9efdbc828b02c681a7cefc6d4108d63811b20a8fb8518a40cb2c13ed15452 \ + --hash=sha256:7ab9a49c410d8c6c786ab99e79c529938d894c01433130353dd0fe999111077a \ + --hash=sha256:7bd7bc82dd4f185f28f35193c2e968ef46131628e3cac62f639dadf321cba4d1 \ + --hash=sha256:7c4d596b7676f811172687ec567cbafb9e4dea2f9be1bbb4f622410cb7f40f40 \ + --hash=sha256:7c76f18d1268d3dc1c8b8facef5b48a9c6172d4a49113afa2d91745f555c75ff \ + --hash=sha256:7d7148180ec99ba36585b42c8c5de25e9b40191613bc4be68909b4d25a77a852 \ + --hash=sha256:7fbec49f5341bbdea0c471f7d1e2fb41ae8925af9b6f28025c28defd8eb94274 \ + --hash=sha256:84415265192072d8638a3afc3c1bc5995e310570cd9acb54dc46d3939e364fe0 \ + --hash=sha256:845d347df254d6c619f616afa921331bada8614b8d373d58725c663ba97c3605 \ + --hash=sha256:84710b4e449596a6565ab67293858d2d93a54eeec55722d55c8f0a08b6e6de24 \ + --hash=sha256:85f5c0e26d945b5bb475e0a3d95193117498130baa7619357bdc7869c2391b5a \ + --hash=sha256:8653dd7c2eda020545bb2c71c7f7039b53fe7434d0fc1a0a9deb79ab3f1a4fc1 \ + --hash=sha256:875811ba23c543b1a1c3143c926e43996eb27ebb8f52d3500744aa608c275aed \ + --hash=sha256:8c5fcfd806c335bfa2adf1cd0b3110a44fc7b6995c3a648c27489bae85801465 \ + --hash=sha256:8d09dfd2ab135b985daf868b594315ebe11ad86cd9fea46e6c69f19b28f7d25a \ + --hash=sha256:8d4dea659b57443989ef32f4295104fd6912c73d0bf26d1d148bb88a9f159b02 \ + --hash=sha256:8e7edb98dd4721a2694542a35a0bdb989b42892086fd0216f7c48762dfe20844 \ + --hash=sha256:8f4608a06e4d61b7a3425665a46d00e0579122e1a2fae97a0c52953a3aad9aa3 \ + --hash=sha256:8ff00fcc3eb436617ed8556cf15daf76c2b501248361a065625a588af78a0a02 \ + --hash=sha256:90b9d1a8bd37d768ffc92a1f651ec69afc532a96fa1ac2ea7abbed5d630b3237 \ + --hash=sha256:9122ad6f867c4a0f5e655f5c3bdf89103852009dbb442a3d23e688b9e699e800 \ + --hash=sha256:91c3b07cf3362086d8f126c6aecd8e5e9396ad8b2f2219ea7e49a8250c318acd \ + --hash=sha256:921c14e93817842dd0dd9f372890a0f0c72e534650b6ab13c5be5cd0db11d47e \ + --hash=sha256:970f9f8c50961d639cbd0d988c96f80ddf66006de93641719282c4fe7a87c5e6 \ + --hash=sha256:9e6c0d843f1daf85ea23aeb053579135552bde575b7b98af20bfc667b6e4548d \ + --hash=sha256:9f1563fdc8abfc389748e6932c7e4e99c89a53e4ec37d4563c24fc06f5e5644b \ + --hash=sha256:9fd17f14ac0faa12126c2f9ca774a8cf342957265ec3c8669c144e5e6cdb478c \ + --hash=sha256:a04a6cab47e2166435aaf5b9e5ee41d1532cc8300efdef87f2a4d0acb7db19ed \ + --hash=sha256:a169a036bed0995e090d1493b283cc2cc8a6f5046821086b843abefff80643bc \ + --hash=sha256:a2eae53197c6276d5b317f75a1be226bbf440c20b58bf525f36b5d0e1f657ca6 \ + --hash=sha256:a3b19a42111c4057c1547a4a1396a53961dca576a0f6b82bfa88a2d1561764b2 \ + --hash=sha256:a6545e6b409e3d5cbafc850fb84c55a1ca26ed15a6b11e3bf07a0e0cd84517c8 \ + --hash=sha256:a6d73a830b17ef49bc04e00182bd839164c1b3c59c127cd7c54fcb10c7ed8ee8 \ + --hash=sha256:a778b25874cb0f862eaab5986bff4ca49ffb0def7c0a34c237b948b3c6c775b2 \ + --hash=sha256:a7f25baec4c5d851d40718d6fae52285b31683093d4ff5207e63ab306ccf14a5 \ + --hash=sha256:a845a59664d5c531525a467470220f8edc37959e0a6f8e734ffb6654da5c4bee \ + --hash=sha256:a999771ff97bec27d18341be4f3a36b163bb1ac41ec17bef6d2dabd84acd33c7 \ + --hash=sha256:ab9dd2c83c4bbd63e422181a76f13502d049d3ddcac9a1bdc29196263d692bb8 \ + --hash=sha256:abb65b4e947e958f7b3b0d71db3ce447d1bc5f37f5eab871ce7223bda8768a04 \ + --hash=sha256:acbb48679ddf3852c45280c10ff10d52ca2cd1da2e552fb81db1ff786c75d0e4 \ + --hash=sha256:ad37c7792479e49cf96c1ab25517d7003fe0d93687a772ba19a097d235bbe41e \ + --hash=sha256:ad3aa71e12ee634f22b39a0ff439357583706e50765f17f05550f92dbf128a23 \ + --hash=sha256:ae3a39a4d96bdb6f8d154fd7f490c4ad06f0532fcd2bb656052a9a7762cf5d31 \ + --hash=sha256:b081119a6115d2db49e24ab6316b7dcd74651271e9630c7b979999bd0c11973d \ + --hash=sha256:b4e6fe5c6f4e6ad67c1374a7c85c944ca1a8d9672f0a1628201ea5c58e0d4596 \ + --hash=sha256:b59ee2ac81de57771a09ecad09191e840a1d2fae1ef684208320591055768f83 \ + --hash=sha256:b5cd29840505631c6f7dbb8a5d34b742b5e6bbda38fe0b9f54e825f3ea6b61dc \ + --hash=sha256:b7ffeaada9f8699be63d639536b0b60dff73b7d3325b7475c5bc8fdbf4eed47f \ + --hash=sha256:bb16aa13ed175bc9be5c2491ba031b85a9b51c4ed90e0b3d4ebe63cf3fb54f8e \ + --hash=sha256:bfe6f92e3522dcbe8c4281efd74fa7542a336cb00b0e3272c4ec0edabeaeaf67 \ + --hash=sha256:c21625d710f971dd58ae92c5b0c2ca109d2ceba939becc937c5cff9268cd451b \ + --hash=sha256:c3c0059e642b2e7e15c77341a8946f670a403fcd57feecc9e47d68555b9b1c08 \ + --hash=sha256:c40a8ad7d42fe779ac429fe245ed44c54f30e2549173559d70b7167922431701 \ + --hash=sha256:c4fd8acc6e32596350619896feb372033c0920975992d29837c32853bb1feacd \ + --hash=sha256:c50269d0055ac1faecfd559886d2cbe4b730de236585aba0e873f9d9dadbe585 \ + --hash=sha256:c72500a3b6d6c30ebfc135035bcace9eb5884f2dc220804efcaaba43e9f611dd \ + --hash=sha256:c7741c7524961d8c0cb4d4c21b28957ff731a3fd5b5cd8b856dc80a40e9e5acc \ + --hash=sha256:c9b31ab1f28b078a6a1ac1a54eb35e7d5390deddd56870d0be3a0a733d1c321c \ + --hash=sha256:ca12a6d683957a651e3203c1458ff8ab4119aae7363e202e2e820cbfe02df244 \ + --hash=sha256:cb5a888a968b2434abf9ecda357b5d43f10d7b5a6da6fdbbe036208473aff0e2 \ + --hash=sha256:cce1e2782efaf0f595c17fe331cf295882a268c04d5887956e2fc0d262b0fb3a \ + --hash=sha256:cd8ab85c916a58d5c8656ea15e3ce9df836fe2f120a74c296e01d69fab2614b4 \ + --hash=sha256:cee88dfaa6b1b2bfadd3c031fa5f05584870e62fb05dc500942e9900c44fcfda \ + --hash=sha256:cf7424a11a81f59b6f0abdccfbe27c87d552f059ef761471f98245b46b71b5c9 \ + --hash=sha256:d006faf3b491957efcb433489be3c149efe4787b7063d5cddb8ddaefdc60e0c1 \ + --hash=sha256:d1442628c84afa453a9a06a10d74d890d3c1b1e4da313b48b16e1001895fdac4 \ + --hash=sha256:d33fcd60f5546e4b7538a8ae2b2027b51e9905b9a264c32df56de32202997155 \ + --hash=sha256:d41fcda2fa8ca682ebca134a2f2dc02575ba549267585597e73061565795f475 \ + --hash=sha256:d610aa62cdb7d4d497740741772a24a794903bf3e79eaa51d2e800082abe11e5 \ + --hash=sha256:d798c1e291bffb8e37b5bbe0dda77fc767cd19e89cadaf66e6ed5d0ff88c9fe6 \ + --hash=sha256:d7d9110d0c3fb02679972837a033251fd186c529aa62f19c132fc909c74052b8 \ + --hash=sha256:da5b373b1dfce210b8620bdb5d9dae668fe549de67948465dcc39e833d4bbe28 \ + --hash=sha256:dbcd969178d417c2bbd60076f8e407a0e2baf90976eed21c1b818ff8292b902f \ + --hash=sha256:dc026e3b89d98e30a8288c95cb696e77d150b3f0fb7a51f73dcd49ee6b5577fa \ + --hash=sha256:dea2fd4ae84b14aa883ac713faffbb5c26764ec623e00ed34737895be523d1fa \ + --hash=sha256:e64a7c9d7dfca3e0fafcbc5e455519090706a3e36e95d655cec3e04e79f95aaa \ + --hash=sha256:e8ff6ec73110f610425caef3ea875afbfc34caa542f01df3a80f45aadeb9f906 \ + --hash=sha256:ea6daa712f4e094a30830cf01e9b47d03b24d05cc9dab8609f0d9a9db8454712 \ + --hash=sha256:ea85a647fd33d5cf2840027c2e0b7da8868b220d3f05e3866efdda78c440d499 \ + --hash=sha256:ec101643395d7f21405b640f728f6f627e6986557027d740f2f9b220955edafe \ + --hash=sha256:ec68dbba21532c0173a9872298e65c89749f7c9d21538c3a78b5bb6105871568 \ + --hash=sha256:ed4a6efe2dee1655adb73e7ad40c6aa955a6892422b1e3b95de6a34de56e3cbb \ + --hash=sha256:f13319fb8e6ef636f71db3c254d01cbf1543786e10a945a3ff180144618e25b6 \ + --hash=sha256:f14bb8b22a4a91325813e3d553b8963c10cf8c756cff65ee50c194431296c655 \ + --hash=sha256:f1598916cb197681e03e601901e4ab96a9a963de398c59d0964f8a6f44a2b361 \ + --hash=sha256:f1e65d52c2d526734abecb98372c256b7eacce8fdc42e0df8570417fb39e2772 \ + --hash=sha256:f262b8f7599516567e070abf607b9af649052b2c4bd6f9be02b0cb41b7024805 \ + --hash=sha256:f3e7b689c3bce16699efcf736066f5c6cc4472c3840fe4b22bd8279daf4abdac \ + --hash=sha256:f420ad3d41e38194353a498bbc9561fd5a9973a27b536ce46d8583479cf44335 \ + --hash=sha256:f749e52b539e2934171a3718cbf061dc12d74719eddde2d0f025c99637ddbe01 \ + --hash=sha256:f99a15867cbf9fcf753ea72b82a1d6fe6552e6feea3b4842c86a951525685bbb \ + --hash=sha256:f9fd595f1e5941b3d7863e4774e4b30caa6731fc34b9277da032295aa5656ee5 \ + --hash=sha256:fa77e7ec1450d415d20129961814787c9abd9a07f98872f070b1fe96c5084611 \ + --hash=sha256:fc84bf7aa7592f31ec63a3e7b11d624f468a3f19f5238cec7282a42e838ab1d7 \ + --hash=sha256:fd880353cf1ffaf321bc18dd663e111976dbd0d3bbd8a66d58d2b470dfa7f396 \ + --hash=sha256:fdc7d06929ae28dda98297a18eef7b0fd38991a3b405d8d7b55c9ef24c296958 \ + --hash=sha256:fddbbb69a6fff4f421e7a0d1fa28f894b20112e9e3fab306af451e2dfd0e459b \ + --hash=sha256:fe14c356f8b23ad811dc026077a6d4abccdaa7bce5ca98579605550657b6fcfb \ + --hash=sha256:fe32736295ea38e43e7d9424053c8c47c9f64fecfc7c895fb3da9b30b131c9ee \ + --hash=sha256:fe820f104473d1516ecd628993690bc1f79b0e699f32711d42a5a70b3d0f8170 # via datasets -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata zstandard==0.25.0 \ --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ diff --git a/sdk/python/requirements/py3.10-minimal-requirements.txt b/sdk/python/requirements/py3.10-minimal-requirements.txt index 8e6b3cd4323..f8a055011b9 100644 --- a/sdk/python/requirements/py3.10-minimal-requirements.txt +++ b/sdk/python/requirements/py3.10-minimal-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.10 --no-strip-extras pyproject.toml --extra minimal --generate-hashes --output-file sdk/python/requirements/py3.10-minimal-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -148,9 +149,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -161,6 +162,41 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy async-timeout==5.0.1 \ --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 @@ -171,34 +207,38 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -293,130 +333,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -426,68 +481,68 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt # pyopenssl # snowflake-connector-python -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -495,42 +550,42 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -540,9 +595,9 @@ exceptiongroup==1.3.1 \ --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 # via anyio -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -550,9 +605,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -688,15 +743,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -706,9 +761,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -720,37 +775,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -794,84 +849,82 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -879,21 +932,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -903,150 +956,175 @@ h11==0.16.0 \ # via # httpcore # uvicorn -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1062,18 +1140,18 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx # requests # snowflake-connector-python # yarl -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1096,109 +1174,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1291,9 +1369,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1304,9 +1382,7 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -1567,45 +1643,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1678,85 +1760,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1830,9 +1912,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1842,163 +1924,162 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2037,68 +2118,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2111,12 +2192,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2125,141 +2204,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2267,30 +2345,30 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2309,13 +2387,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2398,9 +2476,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2408,9 +2486,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2418,6 +2496,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python requests-oauthlib==2.0.0 \ @@ -2426,9 +2505,9 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework @@ -2552,13 +2631,9 @@ rpds-py==0.30.0 \ # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -2567,7 +2642,6 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de @@ -2578,115 +2652,111 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2702,60 +2772,60 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via # fastapi-mcp # mypy -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -2764,33 +2834,36 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiobotocore + # aiohttp # aiosignal # anyio # cryptography # exceptiongroup # fastapi + # grpcio # ibis-framework # mcp # multidict @@ -2799,6 +2872,7 @@ typing-extensions==4.15.0 \ # psycopg-pool # pydantic # pydantic-core + # pyjwt # pyopenssl # referencing # snowflake-connector-python @@ -2815,101 +2889,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -2977,116 +2965,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3155,220 +3141,205 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata diff --git a/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt b/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt index 7bc13afccc1..2ba044416ea 100644 --- a/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt @@ -4,6 +4,41 @@ # # pybuild-deps compile --generate-hashes --output-file=sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt sdk/python/requirements/py3.10-minimal-sdist-requirements.txt # +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 @@ -171,52 +206,116 @@ cython==3.0.12 \ # pyyaml # snowflake-connector-python # sqlalchemy -cython==3.2.4 \ - --hash=sha256:02cb0cc0f23b9874ad262d7d2b9560aed9c7e2df07b49b920bda6f2cc9cb505e \ - --hash=sha256:03893c88299a2c868bb741ba6513357acd104e7c42265809fd58dce1456a36fc \ - --hash=sha256:14dae483ca2838b287085ff98bc206abd7a597b7bb16939a092f8e84d9062842 \ - --hash=sha256:1a64a112a34ec719b47c01395647e54fb4cf088a511613f9a3a5196694e8e382 \ - --hash=sha256:28b1e363b024c4b8dcf52ff68125e635cb9cb4b0ba997d628f25e32543a71103 \ - --hash=sha256:28e8075087a59756f2d059273184b8b639fe0f16cf17470bd91c39921bc154e0 \ - --hash=sha256:2b1f12c0e4798293d2754e73cd6f35fa5bbdf072bdc14bc6fc442c059ef2d290 \ - --hash=sha256:31a90b4a2c47bb6d56baeb926948348ec968e932c1ae2c53239164e3e8880ccf \ - --hash=sha256:35ab0632186057406ec729374c737c37051d2eacad9d515d94e5a3b3e58a9b02 \ - --hash=sha256:36bf3f5eb56d5281aafabecbaa6ed288bc11db87547bba4e1e52943ae6961ccf \ - --hash=sha256:3b6e58f73a69230218d5381817850ce6d0da5bb7e87eb7d528c7027cbba40b06 \ - --hash=sha256:3b8e62049afef9da931d55de82d8f46c9a147313b69d5ff6af6e9121d545ce7a \ - --hash=sha256:55b6c44cd30821f0b25220ceba6fe636ede48981d2a41b9bbfe3c7902ce44ea7 \ - --hash=sha256:55eb425c0baf1c8a46aa4424bc35b709db22f3c8a1de33adb3ecb8a3d54ea42a \ - --hash=sha256:64d7f71be3dd6d6d4a4c575bb3a4674ea06d1e1e5e4cd1b9882a2bc40ed3c4c9 \ - --hash=sha256:67922c9de058a0bfb72d2e75222c52d09395614108c68a76d9800f150296ddb3 \ - --hash=sha256:6d5267f22b6451eb1e2e1b88f6f78a2c9c8733a6ddefd4520d3968d26b824581 \ - --hash=sha256:72e6c0bbd978e2678b45351395f6825b9b8466095402eae293f4f7a73e9a3e85 \ - --hash=sha256:732fc93bc33ae4b14f6afaca663b916c2fdd5dcbfad7114e17fb2434eeaea45c \ - --hash=sha256:767b143704bdd08a563153448955935844e53b852e54afdc552b43902ed1e235 \ - --hash=sha256:83266c356c13c68ffe658b4905279c993d8a5337bb0160fa90c8a3e297ea9a2e \ - --hash=sha256:84226ecd313b233da27dc2eb3601b4f222b8209c3a7216d8733b031da1dc64e6 \ - --hash=sha256:869487ea41d004f8b92171f42271fbfadb1ec03bede3158705d16cd570d6b891 \ - --hash=sha256:90f43be4eaa6afd58ce20d970bb1657a3627c44e1760630b82aa256ba74b4acb \ - --hash=sha256:983f9d2bb8a896e16fa68f2b37866ded35fa980195eefe62f764ddc5f9f5ef8e \ - --hash=sha256:b362819d155fff1482575e804e43e3a8825332d32baa15245f4642022664a3f4 \ - --hash=sha256:b84d4e3c875915545f77c88dba65ad3741afd2431e5cdee6c9a20cefe6905647 \ - --hash=sha256:ca2399dc75796b785f74fb85c938254fa10c80272004d573c455f9123eceed86 \ - --hash=sha256:ca578c9cb872c7ecffbe14815dc4590a003bc13339e90b2633540c7e1a252839 \ - --hash=sha256:d4b4fd5332ab093131fa6172e8362f16adef3eac3179fd24bbdc392531cb82fa \ - --hash=sha256:e3b5ac54e95f034bc7fb07313996d27cbf71abc17b229b186c1540942d2dc28e \ - --hash=sha256:e65e4773021f8dc8532010b4fbebe782c77f9a0817e93886e518c93bd6a44e9d \ - --hash=sha256:e71efb20048358a6b8ec604a0532961c50c067b5e63e345e2e359fff72feaee8 \ - --hash=sha256:f136f379a4a54246facd0eb6f1ee15c3837cb314ce87b677582ec014db4c6845 \ - --hash=sha256:f583cad7a7eed109f0babb5035e92d0c1260598f53add626a8568b57246b62c3 \ - --hash=sha256:f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 \ - --hash=sha256:f8d685a70bce39acc1d62ec3916d9b724b5ef665b0ce25ae55e1c85ee09747fc \ - --hash=sha256:fdfdd753ad7e18e5092b413e9f542e8d28b8a08203126090e1c15f7783b7fe57 \ - --hash=sha256:ff9af2134c05e3734064808db95b4dd7341a39af06e8945d05ea358e1741aaed +cython==3.1.1 \ + --hash=sha256:011cdcbf7725f0cfc1abc55ec83d326e788050711272131daf3cc24a19c34bb2 \ + --hash=sha256:020089f9c9f10269181f17660a2cada7d4577bd8eea24b7d2b14e6b64b6996be \ + --hash=sha256:07621e044f332d18139df2ccfcc930151fd323c2f61a58c82f304cffc9eb5280 \ + --hash=sha256:0de7adff5b42d2556d073e9f321c2faa639a17fb195ec1de130327f60ec209d8 \ + --hash=sha256:0e3ccec55e2a534a712db14c6617b66f65ad149c014fad518fc3920f6edde770 \ + --hash=sha256:0f7954b0b4b3302655d3caa6924261de5907a4e129bc22ace52fe9ae0cd5a758 \ + --hash=sha256:10f0434916994fe213ea7749268b88d77e3ebcbd1b99542cf64bb7d180f45470 \ + --hash=sha256:12e00b88147b03c148a95365f89dc1c45a0fc52f9c35aa75ff770ef65b615839 \ + --hash=sha256:141ffd6279411c562f6b707adc56b63e965a4fd7f21db83f5d4fcbd8c50ac546 \ + --hash=sha256:16d9870654946375b28280371d370d541641d1071da123d0d64d2c7ebba0cc56 \ + --hash=sha256:23b886a6c8a50b1101ccef2f2f3dc9c699b77633ef5bb5007090226c2ad3f9c2 \ + --hash=sha256:24c640c0746d984789fe2787a098f06cda456ef2dd78b90164d17884b350839a \ + --hash=sha256:263cb0e497910fb5e0a361ad1393b6d728b092178afecc56e8a786f3739960c3 \ + --hash=sha256:268420b92307ae6c5a16e3cf0e2ba1ae3c861650e992893922a0ce08db07cfdb \ + --hash=sha256:28b174f41718a7041cfbe0f48913020875ff1aaa4793942b2451ac6d2baf3f07 \ + --hash=sha256:307f216ed319ea07644f2ef9974406c830f01bc8e677e2147e9bfcdf9e3ca8ad \ + --hash=sha256:3192a61c2a532d3faccdff508bc8427de9530b587888218bfc0226eb33a84e11 \ + --hash=sha256:3fa4bd840de63509c74867b4b092541720a01db1e07351206011c34e0777dc96 \ + --hash=sha256:402f86c00b08f875cd0990f0c4dc52eb3e0bc5d630066cdf3c798631976f1937 \ + --hash=sha256:40f50b07c479eaf33981d81cad274c68cf9fb81dbe79cbf991f59491c88a4705 \ + --hash=sha256:426d78565eb91d3366569b20e92b8f14bffef5f57b2acd05b60bbb9ce5c056a1 \ + --hash=sha256:505ccd413669d5132a53834d792c707974248088c4f60c497deb1b416e366397 \ + --hash=sha256:50ad80e2f438e9127a87c10927e6ac16a987df39c248b19ab2cd31330129be3c \ + --hash=sha256:54a8934cb3bf13b1f8f6cbdae8e382e25a26e67de08ea6ebfd0a467131b67227 \ + --hash=sha256:56c6768a6f601f93daab7c2487f9f110548a896a91e00a6e119445ada2575323 \ + --hash=sha256:64915259276482fa23417b284d1fdc7e3a618ee2f819bb6ea7f974c075633df6 \ + --hash=sha256:689c1aad373556bd2ab1aa1c2dad8939a2891465a1fbd2cbbdd42b488fb40ec8 \ + --hash=sha256:6ea77ad1e649cec38f8622ba28dcdfbe7bf519bc132abbcf5df759b3975b5a73 \ + --hash=sha256:7489559e6c5ecbba49d535c2e03cf77c2594a3190b6aca7da5b508ba1664a89a \ + --hash=sha256:755a991601b27dd3555310d0f95b19a05e622a80d7b4e7a91fa6f5f3ef3f3b80 \ + --hash=sha256:7da069ca769903c5dee56c5f7ab47b2b7b91030eee48912630db5f4f3ec5954a \ + --hash=sha256:7e5cad896af896482240979b996bf4136b0d18dc40c56c72c5641bf0ea085dfb \ + --hash=sha256:7fff6526bb6f4eea615663117b86de6ede0d17c477b600d3d8302be3502bd3c3 \ + --hash=sha256:83b2af5c327f7da4f08afc34fddfaf6d24fa0c000b6b70a527c8125e493b6080 \ + --hash=sha256:873aac4ac0b0fb197557c0ac15458b780b9221daa4a716881cbd1a9016c8459f \ + --hash=sha256:8aaa29e763adf3496ab9d371e3caed8da5d3ce5ff8fb57433e2a2f2b5036e5c8 \ + --hash=sha256:953046c190fa9ab9a09a546a909b847cdbb4c1fe34e9bfa4a15b6ee1585a86aa \ + --hash=sha256:9b61b99205308c96b1162de59bd67ecadcad3d166a4a1f03a3d9e826c39cd375 \ + --hash=sha256:9d7dc0e4d0cd491fac679a61e9ede348c64ca449f99a284f9a01851aa1dbc7f6 \ + --hash=sha256:a19188ecd385cdc649e3fec370f38d5fd7f1651aeed0b3fb403180f38fc88e8a \ + --hash=sha256:a585796939b09b3205b1980e4a55e745c0251e45a5c637afbcac3c6cc9ad6f90 \ + --hash=sha256:a92f6bd395eadea6eed722a8188d3bdd49db1c9fa3c38710456d6148ab71bad7 \ + --hash=sha256:ab644415458d782c16ba7252de9cec1e3125371641cafea2e53a8c1cf85dd58d \ + --hash=sha256:af8f62cc9339b75fe8434325083e6a7cae88c9c21efd74bbb6ba4e3623219469 \ + --hash=sha256:b181158b5761bdaf40f6854f016ab7ddff64d3db4fca55cb3ca0f73813dd76d6 \ + --hash=sha256:b194a65a0fd91f305d2d1e7010f44111774a28533e1e44dd2a76e7de81a219b9 \ + --hash=sha256:b68f1bc80387554eb43f2b62795c173bed9e37201f39dc5084ac437c90a79c9f \ + --hash=sha256:c360823e1063784efc2335617e0f28573d7a594c5a8a05d85e850a9621cccb1f \ + --hash=sha256:c5cb6c054daadaf01a88c8f49f3edd9e829c9b76a82cbb4269e3f9878254540b \ + --hash=sha256:c740a10cd0f50321d048c8ca318eefb4c42b8bffef982dcd89c946d374192702 \ + --hash=sha256:c8b8be01fd40b3e38a76c60a524f956548a3a7566e5530a833a48a695f3d6c12 \ + --hash=sha256:cb5661941707bd41ec7a9c273d698113ac50392444f785088e9d9706c6a5937b \ + --hash=sha256:cd748fab8e4426dbcb2e0fa2979558333934d24365e0de5672fbabfe337d880c \ + --hash=sha256:cdf53dc4b2a13bd072d6c2c18ac073dbf0f798555bc27ba4f7546a275eb16a0f \ + --hash=sha256:ce82070ccf92c3599d331b9eaaefd9d4562976fb86a8d6bccf05c4a0b8389f2a \ + --hash=sha256:d14186bd96783d13b8fd0e5b289f2e137a8a25479638b73a1c7e4a99a8d70753 \ + --hash=sha256:dee554f0a589377bdaea0eb70e212bf3f35dc6a51a2aa86c9351345e21fd2f07 \ + --hash=sha256:dfa500fd7ae95ca152a5f8062b870532fa3e27efcef6d00612e1f28b9f72615f \ + --hash=sha256:dff0e7dd53a0ca35b64cda843253d5cac944db26663dc097b3a1adf2c49514ad \ + --hash=sha256:e000f0533eedf3d6dfbe30bb3c58a054c58f0a7778390342fa577a0dc47adab3 \ + --hash=sha256:e851ab66a31794e40df1bc6f649cdc56c998c637f5a1b9410c97a90f6b6cb855 \ + --hash=sha256:fd689910002adfac8734f237cdea1573e38345f27ed7fd445482813b65a29457 + # via grpcio +cython==3.2.5 \ + --hash=sha256:05c22cd606ac8d14a9cf17e48668bb37734c803978bf4d793c7f11ef54c4451f \ + --hash=sha256:0a81220817ff954eddf4512a5b82089094a2f523eb1dc4ad555efd6f07b009b4 \ + --hash=sha256:0bc29c7f870b09efdb1f583fbec9592b33af81a7ce273b89c8f5163d7572d5c1 \ + --hash=sha256:220e8b160b2a4ddc362ad8a8c2ab885aa7156099702cdc48f6518a5de921b553 \ + --hash=sha256:224149d18d980e6ea5001b70fc7ce096c1891d59035dfa9cc5ede50f55804913 \ + --hash=sha256:268aecadcabcdad9f773b8a5694746e0b9ee7894b56b84e2e3a2ccb6c929ea79 \ + --hash=sha256:29243859d6824e2d33bae92fc83d591c3671b6d9ac1b757fa264b894ae906c2b \ + --hash=sha256:34d21aeb08477c9173e8be7a566b19e880a7c8109ec6bb47a4b20cb680141114 \ + --hash=sha256:3795237ab49753647e329181b140c424e8aa97543074f171f8d2c45e5014a06e \ + --hash=sha256:382122de8d6b6024fc374fabc3a2b14ba5860ed981c25055ed14fe44278b9dc7 \ + --hash=sha256:3864da4ca2ebe4660d8f672f2143b02840bf3045655222f6090486171c84298f \ + --hash=sha256:39acb30eba78ba6d995d5cf3d97d57d450663d93aac6f8b93753d2b89d768c60 \ + --hash=sha256:3dd42e4cf36ad15f265bdfec2337cc00c688c8eb6d374ffd13bb19437c27bba1 \ + --hash=sha256:3e5e519bad217a0b96fc281666720ed7d339da618acaa012bea712980b8fe6c9 \ + --hash=sha256:45baf00cb8b222a2ca7e9c48add5dac3ceb6e65be4f591150a6b6767ce1f86b0 \ + --hash=sha256:4d00e2c976ee96da4deff50506c7882ccebb4a932fc178ef27eb42bfde959839 \ + --hash=sha256:561613ddd1ee83088eb126e80a5a7d73ee6eb82e0b1aea09afbe170287e5e27f \ + --hash=sha256:56c97c5e43782ec9d9e66c465e253d2ccde0c578c364c46445efe484965524f0 \ + --hash=sha256:5887c24ebd19604b7a76d8ea57446cb562a590f7f2557e5954a69aae38b3195e \ + --hash=sha256:605c447188aecf2941709f53a2ce44862be256e54601c01b38ab710d83db8047 \ + --hash=sha256:677bb60fd8f5949e26c0a7898983967dbbb65f7628481d8480956b85ca766554 \ + --hash=sha256:69cd71b90d4e0f142fd15b2353982c3f9171fc5e613001f16bcb366ffb29004b \ + --hash=sha256:6e5d7a60835345a8bd29d3aa57070880cc3ce017ea0ade7b9f771ce4bf539b1f \ + --hash=sha256:75f5295dc1b32d084fec598f9507e6f264311d78c07da640bc9a05dc47f7ac2c \ + --hash=sha256:85b2944c3eddfc230f9082720195a2e9f869908e5a8b3185be1be832755ee7fc \ + --hash=sha256:8d7b81e6a52a84a02993f01aa5873786ba1dd593c892d93d5fe9866da0bad297 \ + --hash=sha256:91cb5b9ff599612737b3fd0dddcd401acdf904b78c2caf8cd1049501d0a53f2d \ + --hash=sha256:992a50e90d01813333752f374a4405863113059ec67102ab8d6a431a171ee328 \ + --hash=sha256:a3a423468ee77c3c5b26494f57d9c52e9318991fb7142f4c49fb01b99373e8d6 \ + --hash=sha256:a636c8b7824f3cb587eb2fdde59d8f4a14d433565508081cc290198e37567910 \ + --hash=sha256:b4bfb00baef07106a1e5e7252ace18de91225322f7fa29970995aea7c380fa21 \ + --hash=sha256:b8bc1325cf3e4394cc08a3c1ea7fa24f02f405eef0e8c156d5055f6f9a7a1565 \ + --hash=sha256:c4c79e697db55f082a2d3ba97702e71881d5bb1f56f0a80fa338e69101e4c59b \ + --hash=sha256:c80e1e5cba5b4b9890364e9360939fc298c474f25754bb4bb861270d24bda6d6 \ + --hash=sha256:cce98a9011ac6a2560b3587db22912bd0138267669ec567b0d57eddd2d741b8b \ + --hash=sha256:dc1c8cebb7df5bce37f5f8dc1e5bf04313272a5973d50a55c0ec76c83812911b \ + --hash=sha256:eb38b89e5a8eb2508a1a0832063826b0703dfb02be84e4aa34b8818ce0ca50fe \ + --hash=sha256:f4e722ceab6d795b4682d693656218671c873d4aa74119c54a2b62de0e7c48ce \ + --hash=sha256:f9b564f67b01bffa2521f475794b49f2787709cec1f91d5935a38eba37f2b359 # via # pyarrow # uvloop -dunamai==1.26.0 \ - --hash=sha256:5396ac43aa20ed059040034e9f9798c7464cf4334c6fc3da3732e29273a2f97d \ - --hash=sha256:f584edf0fda0d308cce0961f807bc90a8fe3d9ff4d62f94e72eca7b43f0ed5f6 +dunamai==1.26.1 \ + --hash=sha256:2727d939c5b4257cb01ea404372803b477f5176e5a347c43beaf89cd5072e853 \ + --hash=sha256:3b46007bd65b00b4824ead0a1aee365fd22d0ec2b9c219497d4fd48f52860c8b # via uv-dynamic-versioning exceptiongroup==1.3.1 \ --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ @@ -261,14 +360,6 @@ flit-scm==1.7.0 \ --hash=sha256:961bd6fb24f31bba75333c234145fff88e6de0a90fc0f7e5e7c79deca69f6bb2 \ --hash=sha256:9e864caa8a63f708f5bb2f1b5b53eedcd4da75ec2cc6221a64cea7aa5c9eae1a # via exceptiongroup -gitdb==4.0.12 \ - --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ - --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf - # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 - # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ --hash=sha256:ce0134c40d63d874ac48f48ccc678b8f3b62b8e50e9318520d2bffc752eedaf3 @@ -295,9 +386,13 @@ hatch-vcs==0.5.0 \ # via # filelock # platformdirs -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.27.0 \ + --hash=sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6 \ + --hash=sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b + # via pymilvus +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # annotated-types # atpublic @@ -322,6 +417,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -334,97 +430,164 @@ jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # via uv-dynamic-versioning -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +libcst==1.8.6 \ + --hash=sha256:04030ea4d39d69a65873b1d4d877def1c3951a7ada1824242539e399b8763d30 \ + --hash=sha256:06fc56335a45d61b7c1b856bfab4587b84cfe31e9d6368f60bb3c9129d900f58 \ + --hash=sha256:089c58e75cb142ec33738a1a4ea7760a28b40c078ab2fd26b270dac7d2633a4d \ + --hash=sha256:08bd63a8ce674be431260649e70fca1d43f1554f1591eac657f403ff8ef82c7a \ + --hash=sha256:0c13d5bd3d8414a129e9dccaf0e5785108a4441e9b266e1e5e9d1f82d1b943c9 \ + --hash=sha256:0cbe17067055829607c5ba4afa46bfa4d0dd554c0b5a583546e690b7367a29b6 \ + --hash=sha256:16cfe0cfca5fd840e1fb2c30afb628b023d3085b30c3484a79b61eae9d6fe7ba \ + --hash=sha256:1a3a5e4ee870907aa85a4076c914ae69066715a2741b821d9bf16f9579de1105 \ + --hash=sha256:1dc3b897c8b0f7323412da3f4ad12b16b909150efc42238e19cbf19b561cc330 \ + --hash=sha256:203ec2a83f259baf686b9526268cd23d048d38be5589594ef143aee50a4faf7e \ + --hash=sha256:207481197afd328aa91d02670c15b48d0256e676ce1ad4bafb6dc2b593cc58f1 \ + --hash=sha256:25eaeae6567091443b5374b4c7d33a33636a2d58f5eda02135e96fc6c8807786 \ + --hash=sha256:25fc7a1303cad7639ad45ec38c06789b4540b7258e9a108924aaa2c132af4aca \ + --hash=sha256:2f04d3672bde1704f383a19e8f8331521abdbc1ed13abb349325a02ac56e5012 \ + --hash=sha256:351ab879c2fd20d9cb2844ed1ea3e617ed72854d3d1e2b0880ede9c3eea43ba8 \ + --hash=sha256:36473e47cb199b7e6531d653ee6ffed057de1d179301e6c67f651f3af0b499d6 \ + --hash=sha256:3649a813660fbffd7bc24d3f810b1f75ac98bd40d9d6f56d1f0ee38579021073 \ + --hash=sha256:375965f34cc6f09f5f809244d3ff9bd4f6cb6699f571121cebce53622e7e0b86 \ + --hash=sha256:3a926a4b42015ee24ddfc8ae940c97bd99483d286b315b3ce82f3bafd9f53474 \ + --hash=sha256:3f4fbb7f569e69fd9e89d9d9caa57ca42c577c28ed05062f96a8c207594e75b8 \ + --hash=sha256:42a4f68121e2e9c29f49c97f6154e8527cd31021809cc4a941c7270aa64f41aa \ + --hash=sha256:44f38139fa95e488db0f8976f9c7ca39a64d6bc09f2eceef260aa1f6da6a2e42 \ + --hash=sha256:455f49a93aea4070132c30ebb6c07c2dea0ba6c1fde5ffde59fc45dbb9cfbe4b \ + --hash=sha256:4d7bbdd35f3abdfb5ac5d1a674923572dab892b126a58da81ff2726102d6ec2e \ + --hash=sha256:4fc3fef8a2c983e7abf5d633e1884c5dd6fa0dcb8f6e32035abd3d3803a3a196 \ + --hash=sha256:536567441182a62fb706e7aa954aca034827b19746832205953b2c725d254a93 \ + --hash=sha256:5432e785322aba3170352f6e72b32bea58d28abd141ac37cc9b0bf6b7c778f58 \ + --hash=sha256:55ec021a296960c92e5a33b8d93e8ad4182b0eab657021f45262510a58223de1 \ + --hash=sha256:59a7e388c57d21d63722018978a8ddba7b176e3a99bd34b9b84a576ed53f2978 \ + --hash=sha256:5dcaaebc835dfe5755bc85f9b186fb7e2895dda78e805e577fef1011d51d5a5c \ + --hash=sha256:6366ab2107425bf934b0c83311177f2a371bfc757ee8c6ad4a602d7cbcc2f363 \ + --hash=sha256:6421a930b028c5ef4a943b32a5a78b7f1bf15138214525a2088f11acbb7d3d64 \ + --hash=sha256:6609291c41f7ad0bac570bfca5af8fea1f4a27987d30a1fa8b67fe5e67e6c78d \ + --hash=sha256:6a65f844d813ab4ef351443badffa0ae358f98821561d19e18b3190f59e71996 \ + --hash=sha256:6aa11df6c58812f731172b593fcb485d7ba09ccc3b52fea6c7f26a43377dc748 \ + --hash=sha256:6b23d14a7fc0addd9795795763af26b185deb7c456b1e7cc4d5228e69dab5ce8 \ + --hash=sha256:6cad63e3a26556b020b634d25a8703b605c0e0b491426b3e6b9e12ed20f09100 \ + --hash=sha256:6d8b67874f2188399a71a71731e1ba2d1a2c3173b7565d1cc7ffb32e8fbaba5b \ + --hash=sha256:72cca15800ffc00ba25788e4626189fe0bc5fe2a0c1cb4294bce2e4df21cc073 \ + --hash=sha256:7445479ebe7d1aff0ee094ab5a1c7718e1ad78d33e3241e1a1ec65dcdbc22ffb \ + --hash=sha256:7f04febcd70e1e67917be7de513c8d4749d2e09206798558d7fe632134426ea4 \ + --hash=sha256:8066f1b70f21a2961e96bedf48649f27dfd5ea68be5cd1bed3742b047f14acde \ + --hash=sha256:819c8081e2948635cab60c603e1bbdceccdfe19104a242530ad38a36222cb88f \ + --hash=sha256:85b7025795b796dea5284d290ff69de5089fc8e989b25d6f6f15b6800be7167f \ + --hash=sha256:87e74f7d7dfcba9efa91127081e22331d7c42515f0a0ac6e81d4cf2c3ed14661 \ + --hash=sha256:8a434c521fadaf9680788b50d5c21f4048fa85ed19d7d70bd40549fbaeeecab1 \ + --hash=sha256:98fa1ca321c81fb1f02e5c43f956ca543968cc1a30b264fd8e0a2e1b0b0bf106 \ + --hash=sha256:a20c5182af04332cc94d8520792befda06d73daf2865e6dddc5161c72ea92cb9 \ + --hash=sha256:b0d8c364c44ae343937f474b2e492c1040df96d94530377c2f9263fb77096e4f \ + --hash=sha256:b188e626ce61de5ad1f95161b8557beb39253de4ec74fc9b1f25593324a0279c \ + --hash=sha256:b6c1248cc62952a3a005792b10cdef2a4e130847be9c74f33a7d617486f7e532 \ + --hash=sha256:ba9ab2b012fbd53b36cafd8f4440a6b60e7e487cd8b87428e57336b7f38409a4 \ + --hash=sha256:bb9b4077bdf8857b2483879cbbf70f1073bc255b057ec5aac8a70d901bb838e9 \ + --hash=sha256:bdb14bc4d4d83a57062fed2c5da93ecb426ff65b0dc02ddf3481040f5f074a82 \ + --hash=sha256:bff00e1c766658adbd09a175267f8b2f7616e5ee70ce45db3d7c4ce6d9f6bec7 \ + --hash=sha256:c0a0cc80aebd8aa15609dd4d330611cbc05e9b4216bcaeabba7189f99ef07c28 \ + --hash=sha256:c188d06b583900e662cd791a3f962a8c96d3dfc9b36ea315be39e0a4c4792ebf \ + --hash=sha256:c41c76e034a1094afed7057023b1d8967f968782433f7299cd170eaa01ec033e \ + --hash=sha256:c9d7aeafb1b07d25a964b148c0dda9451efb47bbbf67756e16eeae65004b0eb5 \ + --hash=sha256:cb2679ef532f9fa5be5c5a283b6357cb6e9888a8dd889c4bb2b01845a29d8c0b \ + --hash=sha256:da95b38693b989eaa8d32e452e8261cfa77fe5babfef1d8d2ac25af8c4aa7e6d \ + --hash=sha256:e00e275d4ba95d4963431ea3e409aa407566a74ee2bf309a402f84fc744abe47 \ + --hash=sha256:f1472eeafd67cdb22544e59cf3bfc25d23dc94058a68cf41f6654ff4fcb92e09 \ + --hash=sha256:f729c37c9317126da9475bdd06a7208eb52fcbd180a6341648b45a56b4ba708b \ + --hash=sha256:fea5c7fa26556eedf277d4f72779c5ede45ac3018650721edd77fd37ccd4a2d4 + # via pyarrow +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -517,22 +680,23 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -maturin==1.12.6 \ - --hash=sha256:06fc8d089f98623ce924c669b70911dfed30f9a29956c362945f727f9abc546b \ - --hash=sha256:2cb41139295eed6411d3cdafc7430738094c2721f34b7eeb44f33cac516115dc \ - --hash=sha256:351f3af1488a7cbdcff3b6d8482c17164273ac981378a13a4a9937a49aec7d71 \ - --hash=sha256:3f32e0a3720b81423c9d35c14e728cb1f954678124749776dc72d533ea1115e8 \ - --hash=sha256:6892b4176992fcc143f9d1c1c874a816e9a041248eef46433db87b0f0aff4278 \ - --hash=sha256:6dbddfe4dc7ddee60bbac854870bd7cfec660acb54d015d24597d59a1c828f61 \ - --hash=sha256:75133e56274d43b9227fd49dca9a86e32f1fd56a7b55544910c4ce978c2bb5aa \ - --hash=sha256:8fdb0f63e77ee3df0f027a120e9af78dbc31edf0eb0f263d55783c250c33b728 \ - --hash=sha256:977290159d252db946054a0555263c59b3d0c7957135c69e690f4b1558ee9983 \ - --hash=sha256:bae91976cdc8148038e13c881e1e844e5c63e58e026e8b9945aa2d19b3b4ae89 \ - --hash=sha256:c0c742beeeef7fb93b6a81bd53e75507887e396fd1003c45117658d063812dad \ - --hash=sha256:d37be3a811a7f2ee28a0fa0964187efa50e90f21da0c6135c27787fa0b6a89db \ - --hash=sha256:e90dc12bc6a38e9495692a36c9e231c4d7e0c9bfde60719468ab7d8673db3c45 \ - --hash=sha256:fa84b7493a2e80759cacc2e668fa5b444d55b9994e90707c42904f55d6322c1e +maturin==1.13.3 \ + --hash=sha256:0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b \ + --hash=sha256:1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3 \ + --hash=sha256:2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b \ + --hash=sha256:3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c \ + --hash=sha256:3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018 \ + --hash=sha256:4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f \ + --hash=sha256:49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff \ + --hash=sha256:4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0 \ + --hash=sha256:53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323 \ + --hash=sha256:771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079 \ + --hash=sha256:a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11 \ + --hash=sha256:b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273 \ + --hash=sha256:c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a \ + --hash=sha256:def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6 # via + # ast-serialize # cryptography # orjson # pydantic-core @@ -613,26 +777,27 @@ numpy==2.2.6 \ # via # pandas # pyarrow -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # hatchling # pyproject-metadata # scikit-build-core # setuptools-git-versioning # setuptools-scm + # vcs-versioning # wheel -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -pdm-backend==2.4.7 \ - --hash=sha256:1599e3afa6f229b30cb4d3bd9caeca42229c42eb5730abd13e0b5256ec93c9f7 \ - --hash=sha256:a509d083850378ce919d41e7a2faddfc57a1764d376913c66731125d6b14110f +pdm-backend==2.4.9 \ + --hash=sha256:8d1064751dadb0c40b1026b46826a448d85c8228a564985c62fb53d4aba538a1 \ + --hash=sha256:c41a852ccbf4b567b033db9b2ae78660d7a4ea49307719959ab88a01f0aabb2e # via # annotated-doc # fastapi @@ -645,23 +810,22 @@ pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -poetry-core==2.3.1 \ - --hash=sha256:96f791d5d7d4e040f3983d76779425cf9532690e2756a24fd5ca0f86af19ef82 \ - --hash=sha256:db1cf63b782570deb38bfba61e2304a553eef0740dc17959a50cc0f5115ee634 +poetry-core==2.4.1 \ + --hash=sha256:89dceb6c10e9c6d8650a16183400e3c9ff9ddee13b0a81023b5575334a2b3744 \ + --hash=sha256:acf06f9537cd2625bdaec926d95d90b557ba15353bc71d27a3a8a441042b5316 # via # aiohappyeyeballs # dunamai # pkgconfig # rich - # rsa # tomlkit -pybind11-global==3.0.2 \ - --hash=sha256:00a26be4cd65974133eaae7e7532e7141ccb7a88cd131995bc8d1f652852aaf9 \ - --hash=sha256:e183b4456459c35fbbbc8296eb29e241f6cf0774c0bbc3fc8349789611c6df4b +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.2 \ - --hash=sha256:432f01aeb68e361a3a7fc7575c2c7f497595bf640f747acd909ff238dd766e06 \ - --hash=sha256:f8a6500548919cc33bcd220d5f984688326f574fa97f1107f2f4fdb4c6fb019f +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -671,41 +835,117 @@ pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ --hash=sha256:c72fa49418bb7c5a10f25e050c418009898d1c051721d19f98a6fb6da59a66cf # via meson-python +pyyaml==6.0.3 \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ + --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ + --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ + --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ + --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ + --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ + --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ + --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ + --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ + --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ + --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ + --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ + --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ + --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ + --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ + --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ + --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via libcst scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ --hash=sha256:6ea4730da400f9a998ec3287bd3ebc1d751fe45ad0a93451bead8618adbc02b1 # via # duckdb # patchelf + # pyarrow # pybind11 # pybind11-global semantic-version==2.10.0 \ --hash=sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c \ --hash=sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177 # via setuptools-rust -setuptools-git-versioning==3.0.1 \ - --hash=sha256:737c4d17e848edd46e28764a19dc424d8537fcb2257022e5f4f5c0c8e9b64c80 \ - --hash=sha256:c8a599bacf163b5d215552b5701faf5480ffc4d65426a5711a010b802e1590eb +setuptools-git-versioning==3.1.0 \ + --hash=sha256:3a68f3fd58a2a5e86b0792435cfa9d8e569ab60ee5e4c29228c09da9b637bf18 \ + --hash=sha256:612dfcf184addac9e1c2216f4f229724b2390e5bf613fb925ae80b84f2529172 # via toolz -setuptools-rust==1.12.0 \ - --hash=sha256:7e7db90547f224a835b45f5ad90c983340828a345554a9a660bdb2de8605dcdd \ - --hash=sha256:d94a93f0c97751c17014565f07bdc324bee45d396cd1bba83d8e7af92b945f0c - # via maturin -setuptools-scm==7.1.0 \ - --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ - --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e - # via python-dateutil -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-rust==1.12.1 \ + --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ + --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 + # via + # libcst + # maturin +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via # anyio + # cachetools # dask # duckdb # flit-scm # hatch-vcs # httpx-sse # importlib-metadata + # libcst # pluggy # pyarrow # pybindgen @@ -716,65 +956,60 @@ setuptools-scm==9.2.2 \ # tenacity # tqdm # typeguard - # ujson # urllib3 # zipp -smmap==5.0.3 \ - --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ - --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f - # via gitdb -tomli==2.0.2 \ - --hash=sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38 \ - --hash=sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed - # via setuptools-scm -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +setuptools-scm==7.1.0 \ + --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ + --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e + # via python-dateutil +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via # fastapi-mcp # flit-scm @@ -789,49 +1024,59 @@ tomli==2.4.0 \ # scikit-build-core # setuptools-git-versioning # setuptools-scm + # vcs-versioning # versioneer # yarl -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via - # exceptiongroup # mypy # scikit-build-core # setuptools-scm -uv-dynamic-versioning==0.13.0 \ - --hash=sha256:3220cbf10987d862d78e9931957782a274fa438d33efb1fa26b8155353749e06 \ - --hash=sha256:86d37b89fa2b6836a515301f74ea2d56a1bc59a46a74d66a24c869d1fc8f7585 + # vcs-versioning +uv-dynamic-versioning==0.14.0 \ + --hash=sha256:574fbc07e87ace45c01d55967ad3b864871257b98ff5b8ac87c261227ac8db5b \ + --hash=sha256:e087c346a786e98d41292ac2315180fb700cedfb30565fc973d64ce11a112387 # via mcp +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm versioneer==0.29 \ --hash=sha256:0f1a137bb5d6811e96a79bb0486798aeae9b9c6efc24b389659cebb0ee396cb9 \ --hash=sha256:5ab283b9857211d61b53318b7c792cf68e798e765ee17c27ade9f6c924235731 # via # pandas # partd -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # async-timeout # google-crc32c + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # httpx-sse + # libcst # meson # mmh3 # pandas @@ -839,13 +1084,13 @@ wheel==0.46.3 \ # psycopg-c # psycopg-pool # pycparser - # pymilvus # python-dateutil # setuptools-git-versioning # shellingham # snowflake-connector-python # tzdata # uvloop + # wrapt # The following packages are considered to be unsafe in a requirements file: setuptools==80.10.2 \ @@ -857,6 +1102,7 @@ setuptools==80.10.2 \ # aiosignal # anyio # async-timeout + # cachetools # calver # certifi # cffi @@ -865,16 +1111,21 @@ setuptools==80.10.2 \ # dask # dill # frozenlist - # gitpython # google-api-core # google-cloud-bigquery # google-crc32c # googleapis-common-protos # greenlet # grpc-google-iam-v1 + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # gunicorn + # httptools # httpx-sse # importlib-metadata + # libcst # librt # markupsafe # maturin @@ -887,25 +1138,23 @@ setuptools==80.10.2 \ # pathspec # pluggy # prometheus-client - # propcache # proto-plus # psutil # psycopg - # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser # pyjwt - # pymilvus # pymysql # python-dotenv # pyyaml + # requests # setuptools-git-versioning # setuptools-rust # setuptools-scm # shellingham + # snowballstemmer # snowflake-connector-python # sqlalchemy # sqlglot @@ -916,23 +1165,23 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql - # types-setuptools # tzdata # uvloop + # vcs-versioning # versioneer # websockets # wrapt - # yarl # zipp -setuptools==80.9.0 \ - --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ - --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c - # via httptools +setuptools==80.3.1 \ + --hash=sha256:31e2c58dbb67c99c289f51c16d899afedae292b978f8051efaf6262d8212f927 \ + --hash=sha256:ea8e00d7992054c4c592aeb892f6ad51fe1b4d90cc6947cc45c45717c40ec537 + # via psycopg-c setuptools==82.0.1 \ --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via + # propcache # python-dateutil - # setuptools-scm - # ujson + # types-pymysql + # types-setuptools + # yarl diff --git a/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt index 6443657db82..e1218415516 100644 --- a/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.10 --no-strip-extras pyproject.toml --extra minimal-sdist-build --no-emit-package milvus-lite --generate-hashes --output-file sdk/python/requirements/py3.10-minimal-sdist-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -152,9 +153,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -165,6 +166,41 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy async-timeout==5.0.1 \ --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 @@ -175,9 +211,9 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema @@ -186,31 +222,35 @@ babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ --hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # via sphinx -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -305,130 +345,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -438,56 +493,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt @@ -559,13 +614,13 @@ cython==3.0.12 \ --hash=sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3 \ --hash=sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -577,42 +632,42 @@ docutils==0.21.2 \ --hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \ --hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -624,9 +679,9 @@ exceptiongroup==1.3.1 \ # via # anyio # scikit-build-core -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -634,9 +689,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -776,15 +831,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -794,9 +849,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -808,37 +863,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -882,139 +937,163 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -greenlet==3.3.2 \ - --hash=sha256:02b0a8682aecd4d3c6c18edf52bc8e51eacdd75c8eac52a790a210b06aa295fd \ - --hash=sha256:18cb1b7337bca281915b3c5d5ae19f4e76d35e1df80f4ad3c1a7be91fadf1082 \ - --hash=sha256:1a9172f5bf6bd88e6ba5a84e0a68afeac9dc7b6b412b245dd64f52d83c81e55b \ - --hash=sha256:1e692b2dae4cc7077cbb11b47d258533b48c8fde69a33d0d8a82e2fe8d8531d5 \ - --hash=sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f \ - --hash=sha256:1fb39a11ee2e4d94be9a76671482be9398560955c9e568550de0224e41104727 \ - --hash=sha256:20154044d9085151bc309e7689d6f7ba10027f8f5a8c0676ad398b951913d89e \ - --hash=sha256:2eaf067fc6d886931c7962e8c6bede15d2f01965560f3359b27c80bde2d151f2 \ - --hash=sha256:34308836d8370bddadb41f5a7ce96879b72e2fdfb4e87729330c6ab52376409f \ - --hash=sha256:394ead29063ee3515b4e775216cb756b2e3b4a7e55ae8fd884f17fa579e6b327 \ - --hash=sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd \ - --hash=sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2 \ - --hash=sha256:43e99d1749147ac21dde49b99c9abffcbc1e2d55c67501465ef0930d6e78e070 \ - --hash=sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99 \ - --hash=sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be \ - --hash=sha256:4c956a19350e2c37f2c48b336a3afb4bff120b36076d9d7fb68cb44e05d95b79 \ - --hash=sha256:508c7f01f1791fbc8e011bd508f6794cb95397fdb198a46cb6635eb5b78d85a7 \ - --hash=sha256:527fec58dc9f90efd594b9b700662ed3fb2493c2122067ac9c740d98080a620e \ - --hash=sha256:59b3e2c40f6706b05a9cd299c836c6aa2378cabe25d021acd80f13abf81181cf \ - --hash=sha256:5d0e35379f93a6d0222de929a25ab47b5eb35b5ef4721c2b9cbcc4036129ff1f \ - --hash=sha256:63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506 \ - --hash=sha256:64970c33a50551c7c50491671265d8954046cb6e8e2999aacdd60e439b70418a \ - --hash=sha256:6c6f8ba97d17a1e7d664151284cb3315fc5f8353e75221ed4324f84eb162b395 \ - --hash=sha256:8b466dff7a4ffda6ca975979bab80bdadde979e29fc947ac3be4451428d8b0e4 \ - --hash=sha256:8c1fdd7d1b309ff0da81d60a9688a8bd044ac4e18b250320a96fc68d31c209ca \ - --hash=sha256:8c4dd0f3997cf2512f7601563cc90dfb8957c0cff1e3a1b23991d4ea1776c492 \ - --hash=sha256:8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab \ - --hash=sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358 \ - --hash=sha256:8e4ab3cfb02993c8cc248ea73d7dae6cec0253e9afa311c9b37e603ca9fad2ce \ - --hash=sha256:94ad81f0fd3c0c0681a018a976e5c2bd2ca2d9d94895f23e7bb1af4e8af4e2d5 \ - --hash=sha256:97245cc10e5515dbc8c3104b2928f7f02b6813002770cfaffaf9a6e0fc2b94ef \ - --hash=sha256:9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d \ - --hash=sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac \ - --hash=sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55 \ - --hash=sha256:a7945dd0eab63ded0a48e4dcade82939783c172290a7903ebde9e184333ca124 \ - --hash=sha256:aa6ac98bdfd716a749b84d4034486863fd81c3abde9aa3cf8eff9127981a4ae4 \ - --hash=sha256:ab0c7e7901a00bc0a7284907273dc165b32e0d109a6713babd04471327ff7986 \ - --hash=sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd \ - --hash=sha256:ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f \ - --hash=sha256:ae9e21c84035c490506c17002f5c8ab25f980205c3e61ddb3a2a2a2e6c411fcb \ - --hash=sha256:b26b0f4428b871a751968285a1ac9648944cea09807177ac639b030bddebcea4 \ - --hash=sha256:b568183cf65b94919be4438dc28416b234b678c608cafac8874dfeeb2a9bbe13 \ - --hash=sha256:b6997d360a4e6a4e936c0f9625b1c20416b8a0ea18a8e19cabbefc712e7397ab \ - --hash=sha256:b8bddc5b73c9720bea487b3bffdb1840fe4e3656fba3bd40aa1489e9f37877ff \ - --hash=sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a \ - --hash=sha256:c2e47408e8ce1c6f1ceea0dffcdf6ebb85cc09e55c7af407c99f1112016e45e9 \ - --hash=sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86 \ - --hash=sha256:ccd21bb86944ca9be6d967cf7691e658e43417782bce90b5d2faeda0ff78a7dd \ - --hash=sha256:cd6f9e2bbd46321ba3bbb4c8a15794d32960e3b0ae2cc4d49a1a53d314805d71 \ - --hash=sha256:d248d8c23c67d2291ffd47af766e2a3aa9fa1c6703155c099feb11f526c63a92 \ - --hash=sha256:d3a62fa76a32b462a97198e4c9e99afb9ab375115e74e9a83ce180e7a496f643 \ - --hash=sha256:e26e72bec7ab387ac80caa7496e0f908ff954f31065b0ffc1f8ecb1338b11b54 \ - --hash=sha256:e3cb43ce200f59483eb82949bf1835a99cf43d7571e900d7c8d5c62cdf25d2f9 +greenlet==3.5.1 \ + --hash=sha256:001775efe7b8e758861294c7a27c28af87f3f3f1c20468a2bc618c45b346c061 \ + --hash=sha256:00929c98ec525fd9bf075875d8c5f6a983a90906cdf78a66e6de2d8e466c2a19 \ + --hash=sha256:017a544f0385d441e88714160d089d6900ef46c9eff9d99b6715a5ef2d127747 \ + --hash=sha256:089fff7a6ce8d9316d1f65ebc00273a56be258c1725b32b94de90a3a979557e1 \ + --hash=sha256:1072b4f9edcc1e192d9283a66a3e68d6b84c561de33a83d7858beb9ba1effe10 \ + --hash=sha256:10a9a1c0bfbc93d41156ffcb90c75fbc05544054faf15dcc1fdf9765f8b607f0 \ + --hash=sha256:110a1ca7b49b014b097f6078272c3f4ed31af45b254de5228b79adba879f6af9 \ + --hash=sha256:111e2390ffffc47d5840b01711dd7fac07d4c09283d0283e7f3264b14e284c64 \ + --hash=sha256:17d86354f0ae6b61bf9be5148d0dd34e06c3cb7c602c671f79f29ac3b150e659 \ + --hash=sha256:1ffdb3c0bb002c99cd8f298957e046c3dbf6006b5b7cdf11a4e19194624a0a0a \ + --hash=sha256:2baee5ca02031757ffe8cc3d69f0cc0aec7065ce362622da74f32d3bcab1c541 \ + --hash=sha256:2c18ef16bf6d4dd410e4dd52996888ea1497be26892fe5bbc73580aba4287b8e \ + --hash=sha256:2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c \ + --hash=sha256:3bfbd69cc349e43bf3a8ae1c85548ff0718efc887615c2db16c3833d7b0b072d \ + --hash=sha256:3c8bb982ad117d29478ef8f5533e97df21f1e2befd17a299257b0c96d1371c0b \ + --hash=sha256:3d955c89b75eeca4723d7cc14135f393cd47c32e2a6cb4a8e4c6e760a26b0986 \ + --hash=sha256:4378720dd888136c27215a0214d32a4d37c3852765d45bc37aad0623423cfd78 \ + --hash=sha256:45718441607f9325d948db98cbc691276059316d0358c188c246da4e1d4d23d2 \ + --hash=sha256:5028648bf2253ec4745add746129d3904121fa7fe871a76bed23c5720573ce0a \ + --hash=sha256:50ae25a67bea74ea41fb14b960bc532df73eb713417b2d61892dced82fe8d3bc \ + --hash=sha256:51518ff74664078fc51bffcc6fc529b0df5ae58da192691cee765d45ce944a2b \ + --hash=sha256:540dae7b956209af4d70a3be35927b4055f617763771e5e84a5255bea934d2f5 \ + --hash=sha256:5a56aeb7d5d9cc4b3a735efb5095bd4b4f6f0e4f93e5ca876d0e2315137b7829 \ + --hash=sha256:5e300185139abc337ade480c327183adf42a875ac7181bfe66d7d4efea31fbea \ + --hash=sha256:67821bb03e4e98664490edb787ff6af501194c29bbee0f5c1dfdcf1dc3d9d436 \ + --hash=sha256:6c09df69dc1712d131332054a858a3e5cca400967fa3a672e2324fbb0971448c \ + --hash=sha256:6ebeb75c81211f5c702576cf81f315e77e23cfdb2c7c6fcb9dd143e6de35c360 \ + --hash=sha256:73f78f9b9f0a5c06e5c946ba1e8e36f5114923b6be109ee618c54f079c3ea14f \ + --hash=sha256:7546556f0d649f99f6a361098a55f761181bb2ea12ff150bb16d26092ad88244 \ + --hash=sha256:7715a5a2c3378ba602c3a440558261e13a820bb53a82693aacd7b7f6d964e283 \ + --hash=sha256:7b5f5fae05b8ac6d176a61b60c394a8cbdc2b5b91b81793066e68745cf165e54 \ + --hash=sha256:7eacb17a9d41538a2bc4912eba5ef13823c83cb69e4d141d0813debe7163187f \ + --hash=sha256:7ffdb990dcaa0234cf9845aead5df2e3c3a8b6507d409274dd87e0d5ab05ffc2 \ + --hash=sha256:80eb4b04dadc4e67df3fae179a32c4706a3f495bc7f22fc8a81115d5f5512188 \ + --hash=sha256:88e300d136eac057b2397aa1cfd7328b4c87c7eb66a09c7bc6a1292234db474e \ + --hash=sha256:89101bfd5011e069be974903cb3a4e4523845e4ece2d62dcd8d358933c0ef249 \ + --hash=sha256:8a17c42330e261299766b75ac1ea32caa437a9453c8f65d16a13140db378ecd3 \ + --hash=sha256:8a271fcd66c74615cda6a964fda3f304267a12e50a084472218a39bb0376f563 \ + --hash=sha256:8d8a23250ea3ec7b36de8fa4b541e9e2db3ee82915cc060ab0631609ad8b28de \ + --hash=sha256:92fd6d44ac5e5a887c8a5dc4a8ba0ba908527c31c12f78c6bc7dcfe8aab279f6 \ + --hash=sha256:975eac34b44a7077ca4d421348455b94f0f518246a7f14bc6d2fdcfe5b584368 \ + --hash=sha256:9ab3c3a0b2ae6198e67c898dad5215a49f9ae0d0081b3c3ec59f333e39eeca26 \ + --hash=sha256:9b1ec3274918a81d3ea778b9e75b56b72b33f300edb6cf7f3a7fe1dae56683de \ + --hash=sha256:9d59e840387076a51016777a9328b3f2c427c6f9208a6e958bad251be50a648d \ + --hash=sha256:a0cbed8bb44e23c5b199f888f4e4ce096b45ad9f25ff74a7ad0213875e936bb2 \ + --hash=sha256:a19570c52a21420dcbc94e661994bc325c0b5b11304540fed514586da5dc8f2e \ + --hash=sha256:a203a8bd0acb0701653d3bbb26e404854a68674139ed5cbb778830f42b09bb33 \ + --hash=sha256:a4764e0bfc6a4d114c865b32520805c16a990ef5f286a514413b05d5ecd6a23d \ + --hash=sha256:a57b0d05a0448eed231d59c0ceb287dde984551e54cbc51ac2d4865712838e9c \ + --hash=sha256:a5c81f74d204d3edd136ebfd50dce53acbb776995d721a0fe801626cfc93b8cd \ + --hash=sha256:a5ea42a752d47a145eae922b605cd1634665ac3d5ec1e72402d5048e8d60d207 \ + --hash=sha256:a6fdf2433a5441ef9a95464f7c3e674775da1c8c1177fff311cee1acad4626ed \ + --hash=sha256:add5217d68b31130f0beca584d7fef4878327d2e31642b66618a14eef312b63b \ + --hash=sha256:b0703c2cef53e01baec47f7a3868009913ad71ec678bbecb42a6f40895e4ce62 \ + --hash=sha256:b9152fca4a6466e114aaec745ae61cba739903a109754a9d4e1262f01e9259b1 \ + --hash=sha256:c0141e37414c10164e702b8fb1473304221ad98f71600850c6ef7ff4880feba0 \ + --hash=sha256:c3d35f87c7253b715d13d679e0783d845910144f282cb939fe1ba4ac8616269c \ + --hash=sha256:c5551170cf4f5ff5623e9af81323751979fee2c731e2287b61f73cd27257b823 \ + --hash=sha256:cbfc69be86e10dcfef5b1e6269d1d6926552aa89ee39e1de3353360c1b6989ab \ + --hash=sha256:cc6ab7e555c8a112ad3a76e368e86e12a2754bcae1652a5602e133ec7b635523 \ + --hash=sha256:cd443683db272ebaaca03af98c0b063ab30db70ea8a31a1559f35e3f7b744ccd \ + --hash=sha256:d0932b81d72f552ded9d810d00021b64d89f2195a91ce115b893f943b7a4ab3c \ + --hash=sha256:d40a890035c0058cadbdc4af7569800fd28a0e527a0fdbb7b5f9418f176846ce \ + --hash=sha256:d5ee3ea898009fa898f85f9982255d35278c477bebe185beca249cab42d4526c \ + --hash=sha256:d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07 \ + --hash=sha256:dc71ff466927a201b08305acac451ebe1aedfcea002f62f1f2f2ac2ac1e6a135 \ + --hash=sha256:de2daaaebd1a5aa88c49045b6baf9310b3263796bd88db713edf37cf53e7bb4e \ + --hash=sha256:ded7b068c7c31c1a8657d4fd42d886b3e051ae29f88b80c5ff9d502257b0f071 \ + --hash=sha256:e5cc9606aa5f4e0bde0d3bd502b44f743864c3ffa5cfa1011b1e30f5aa02366f \ + --hash=sha256:e630136e905fe5ff43e86945ae41220b6d1470956a39220e708110ac48d01ea5 \ + --hash=sha256:e6cd99ea59dd5d89f0c956606571d79bfe6f68c9eb7f4a4083a41a7f1587edee \ + --hash=sha256:e7516cf6ae6b8a582c2770a0caed47b8a48373ed732c33d69a72913ae6ac923e \ + --hash=sha256:ea37d5a157eb9493820d3792ac4ece28619a394391d2b9f2f78057d396ff0f0f \ + --hash=sha256:ea8da1e900d758d078810d4255d8c6aa572181896a31ec79d779eb79c3adc9ad \ + --hash=sha256:ed8cdb691169715a9a492844a83246f090182247d1a5031dc78a403f68ba1e97 \ + --hash=sha256:ef08c1567c78074b22d1a200183d52d04a14df447bf70bcbb6a3507a48e776fc \ + --hash=sha256:f16ba1efc0715b680a18b8123d90dad887c6112ae3555b4b5c32c149540c6b4e \ + --hash=sha256:fa4f98af3a528f0c3fd592a26df7f376f93329c8f4d987f6bb979057af8bf5e2 \ + --hash=sha256:ffea73584b216150eab159b6d12348fb253e68757974de1e2c40d8a318ac89ed # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1022,21 +1101,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -1054,157 +1133,182 @@ hatch-vcs==0.4.0 \ --hash=sha256:093810748fe01db0d451fabcf2c1ac2688caefd232d4ede967090b1c1b07d9f7 \ --hash=sha256:b8a2b6bee54cf6f9fc93762db73890017ae59c9081d1038a41f16235ceaf8b2c # via feast (pyproject.toml) -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # feast (pyproject.toml) # hatch-fancy-pypi-readme # hatch-vcs -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1220,9 +1324,9 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1233,9 +1337,9 @@ imagesize==2.0.0 \ --hash=sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 \ --hash=sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3 # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1260,109 +1364,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1455,9 +1559,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1733,45 +1837,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1844,85 +1954,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1936,6 +2046,7 @@ packaging==26.0 \ # setuptools-scm # snowflake-connector-python # sphinx + # vcs-versioning pandas==2.3.3 \ --hash=sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7 \ --hash=sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593 \ @@ -2001,9 +2112,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -2024,16 +2135,16 @@ patchelf==0.17.2.4 \ --hash=sha256:d842b51f0401460f3b1f3a3a67d2c266a8f515a5adfbfa6e7b656cb3ac2ed8bc \ --hash=sha256:d9b35ebfada70c02679ad036407d9724ffe1255122ba4ac5e4be5868618a5689 # via feast (pyproject.toml) -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ @@ -2043,151 +2154,150 @@ prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2226,68 +2336,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2300,12 +2410,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2318,141 +2426,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2460,31 +2567,31 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2507,13 +2614,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2596,9 +2703,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2606,9 +2713,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2616,6 +2723,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python # sphinx @@ -2625,9 +2733,9 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework @@ -2751,13 +2859,9 @@ rpds-py==0.30.0 \ # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ @@ -2770,11 +2874,10 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus # setuptools-scm -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via hatch-vcs shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ @@ -2786,37 +2889,37 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ @@ -2850,83 +2953,79 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2942,54 +3041,54 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via # fastapi-mcp # hatch-fancy-pypi-readme @@ -2999,9 +3098,10 @@ tomli==2.4.0 \ # scikit-build-core # setuptools-scm # sphinx -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 + # vcs-versioning +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -3010,41 +3110,44 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via feast (pyproject.toml) -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiobotocore + # aiohttp # aiosignal # anyio # cryptography # exceptiongroup # fastapi + # grpcio # ibis-framework # mcp # multidict @@ -3053,15 +3156,18 @@ typing-extensions==4.15.0 \ # psycopg-pool # pydantic # pydantic-core + # pyjwt # pyopenssl # referencing # scikit-build-core + # setuptools-scm # snowflake-connector-python # sqlalchemy # starlette # typeguard # typing-inspection # uvicorn + # vcs-versioning typing-inspection==0.4.2 \ --hash=sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 \ --hash=sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464 @@ -3070,101 +3176,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -3232,116 +3252,118 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3410,222 +3432,207 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata # The following packages were excluded from the output: diff --git a/sdk/python/requirements/py3.10-requirements.txt b/sdk/python/requirements/py3.10-requirements.txt index 70c69bbebb6..ec690d1ee5d 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -8,144 +8,195 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # starlette # watchfiles -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via requests -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask @@ -158,9 +209,9 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ @@ -170,17 +221,17 @@ exceptiongroup==1.3.1 \ --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 # via anyio -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via feast (pyproject.toml) -fsspec==2026.2.0 \ - --hash=sha256:6544e34b16869f5aacd5b90bdf1a71acb37792ea3ddf6125ee69a22a53fb8bff \ - --hash=sha256:98de475b5cb3bd66bedd5c4679e87b4fdfe1a3bf4d707b151b3c07e58c9a2437 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -188,60 +239,67 @@ h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 # via uvicorn -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # requests -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -255,97 +313,97 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -551,45 +609,51 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -655,85 +719,9 @@ numpy==2.2.6 \ # feast (pyproject.toml) # dask # pandas -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -800,23 +788,23 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -protobuf==7.34.0 \ - --hash=sha256:3871a3df67c710aaf7bb8d214cc997342e63ceebd940c8c7fc65c9b3d697591a \ - --hash=sha256:4a72a8ec94e7a9f7ef7fe818ed26d073305f347f8b3b5ba31e22f81fd85fca02 \ - --hash=sha256:8e329966799f2c271d5e05e236459fe1cbfdb8755aaa3b0914fa60947ddea408 \ - --hash=sha256:964cf977e07f479c0697964e83deda72bcbc75c3badab506fb061b352d991b01 \ - --hash=sha256:9d7a5005fb96f3c1e64f397f91500b0eb371b28da81296ae73a6b08a5b76cdd6 \ - --hash=sha256:9f9079f1dde4e32342ecbd1c118d76367090d4aaa19da78230c38101c5b3dd40 \ - --hash=sha256:e3b914dd77fa33fa06ab2baa97937746ab25695f389869afdf03e81f34e45dc7 \ - --hash=sha256:f791ec509707a1d91bd02e07df157e75e4fb9fbdad12a81b7396201ec244e2e3 +protobuf==7.35.0 \ + --hash=sha256:4c4617b83ade0e279d1d2bfe04025a1adb87f9ed657de038620dc0ff959357f6 \ + --hash=sha256:4cbf5cc286130e06a6c9bbefac442431173906dfcc979712183d4adcc01b37ee \ + --hash=sha256:66be6c513931c794fa92c080ffee41671390da3d79da219cf9c0c0907f035dda \ + --hash=sha256:6c0f98f10c8a05ea30f8993dfef2de093d27b490fdae78bb60c8343795d55011 \ + --hash=sha256:a2efd84605f41e559f1881b0912b44099d0a2ac9bf46b3474823f10fb393b0e6 \ + --hash=sha256:c13f325cf242bad135c350629eeb5d54b24228eb472fb3e2e9ebbd4c5dc20ca0 \ + --hash=sha256:f05bcadf9a2a6b8dda047007075135fb7d08c73d9177aabc067e1be46881a201 \ + --hash=sha256:fcbe42a4ac09d3ec9c987ddfcd956afd0b15f1ff613bd8371bde9405ffd5c8e5 # via feast (pyproject.toml) psutil==7.2.2 \ --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ @@ -841,196 +829,195 @@ psutil==7.2.2 \ --hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \ --hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8 # via feast (pyproject.toml) -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via feast (pyproject.toml) -pyjwt==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via feast (pyproject.toml) python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -1040,9 +1027,9 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via uvicorn -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via pandas pyyaml==6.0.3 \ --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ @@ -1128,9 +1115,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via feast (pyproject.toml) rpds-py==0.30.0 \ --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ @@ -1255,75 +1242,72 @@ six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 # via python-dateutil -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 - # via fastapi +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 + # via + # feast (pyproject.toml) + # fastapi tabulate==0.10.0 \ --hash=sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d \ --hash=sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 @@ -1336,54 +1320,54 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via mypy toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -1391,13 +1375,13 @@ toolz==1.1.0 \ # via # dask # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -1409,6 +1393,7 @@ typing-extensions==4.15.0 \ # mypy # pydantic # pydantic-core + # pyjwt # referencing # sqlalchemy # starlette @@ -1421,13 +1406,13 @@ typing-inspection==0.4.2 \ # via # fastapi # pydantic -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via pandas -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via requests uvicorn[standard]==0.34.0 \ --hash=sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4 \ @@ -1490,116 +1475,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websockets==16.0 \ --hash=sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c \ @@ -1664,7 +1647,7 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata diff --git a/sdk/python/requirements/py3.11-ci-requirements.txt b/sdk/python/requirements/py3.11-ci-requirements.txt index 3acbb20d03a..f6fdfb0d5dc 100644 --- a/sdk/python/requirements/py3.11-ci-requirements.txt +++ b/sdk/python/requirements/py3.11-ci-requirements.txt @@ -4,139 +4,140 @@ accelerate==1.13.0 \ --hash=sha256:cf1a3efb96c18f7b152eb0fa7490f3710b19c3f395699358f08decca2b8b62e0 \ --hash=sha256:d631b4e0f5b3de4aff2d7e9e6857d164810dfc3237d54d017f075122d057b236 # via docling-ibm-models -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a # via # aiobotocore # aiohttp-cors # fsspec + # kubernetes + # mlflow # ray aiohttp-cors==0.8.1 \ --hash=sha256:3180cf304c5c712d626b9162b195b1db7ddf976a2a25172b35bb2448b890a80d \ @@ -154,6 +155,10 @@ alabaster==0.7.16 \ --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 # via sphinx +alembic==1.18.4 \ + --hash=sha256:a5ed4adcf6d8a4cb575f3d759f071b03cd6e5c7618eb796cb52497be25bfe19a \ + --hash=sha256:cb6e1fd84b6174ab8dbb2329f86d631ba9559dd78df550b57804d607672cedbc + # via mlflow altair==4.2.2 \ --hash=sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5 \ --hash=sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87 @@ -166,9 +171,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # elasticsearch # httpx @@ -230,9 +235,9 @@ asttokens==3.0.1 \ --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 # via stack-data -async-lru==2.2.0 \ - --hash=sha256:80abae2a237dbc6c60861d621619af39f0d920aea306de34cb992c879e01370c \ - --hash=sha256:e2c1cf731eba202b59c5feedaef14ffd9d02ad0037fcda64938699f2c380eafe +async-lru==2.3.0 \ + --hash=sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6 \ + --hash=sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315 # via jupyterlab async-property==0.2.2 \ --hash=sha256:17d9bd6ca67e27915a75d92549df64b5c7174e9dc806b30a3934dc4ff0506380 \ @@ -246,28 +251,28 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonlines # jsonschema # openlineage-python # referencing -azure-core==1.38.2 \ - --hash=sha256:074806c75cf239ea284a33a66827695ef7aeddac0b4e19dda266a93e4665ead9 \ - --hash=sha256:67562857cb979217e48dc60980243b61ea115b77326fa93d83b729e7ff0482e7 +azure-core==1.41.0 \ + --hash=sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d \ + --hash=sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a # via # azure-identity # azure-storage-blob -azure-identity==1.25.2 \ - --hash=sha256:030dbaa720266c796221c6cdbd1999b408c079032c919fef725fcc348a540fe9 \ - --hash=sha256:1b40060553d01a72ba0d708b9a46d0f61f56312e215d8896d836653ffdc6753d +azure-identity==1.25.3 \ + --hash=sha256:ab23c0d63015f50b630ef6c6cf395e7262f439ce06e5d07a64e874c724f8d9e6 \ + --hash=sha256:f4d0b956a8146f30333e071374171f3cfa7bdb8073adb8c3814b65567aa7447c # via feast (pyproject.toml) -azure-storage-blob==12.28.0 \ - --hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \ - --hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41 +azure-storage-blob==12.29.0 \ + --hash=sha256:2824ddd7ebc9056034ebc76b17971a38e9aa5835abb0d565b9700493f2a6c657 \ + --hash=sha256:ccf8a1bcd5e49df83ab85aab793b579e5ba2eeea2ad8900b2f62ca3a37dc391f # via feast (pyproject.toml) babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ @@ -346,73 +351,79 @@ beautifulsoup4==4.14.3 \ # via # docling # nbconvert -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -bleach[css]==6.3.0 \ - --hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \ - --hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6 +bleach[css]==6.4.0 \ + --hash=sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452 \ + --hash=sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081 # via nbconvert -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +blinker==1.9.0 \ + --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ + --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc + # via flask +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # moto # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # moto # s3transfer # snowflake-connector-python -build==1.4.0 \ - --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ - --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 +build==1.5.0 \ + --hash=sha256:13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f \ + --hash=sha256:302c22c3ba2a0fd5f3911918651341ebb3896176cbdec15bd421f80b1afc7647 # via # feast (pyproject.toml) # pip-tools # singlestoredb -cassandra-driver==3.29.3 \ - --hash=sha256:064bf45d3ca87239e11168c0110676fc64f7fdbddb4bcba9be787b8ad5f6d734 \ - --hash=sha256:0785f6e0986089e922378ae3b64b5f696440aeb595fb84c2cf3ccef220c6ae91 \ - --hash=sha256:158f7e5cb894a76a592aa0ca659a8e7c2a57ef603e04c07bbbc289a70e9ac893 \ - --hash=sha256:1c241ba08473baf31a333feb59793190d01625541c2368d3bbb0f43a586f1d6a \ - --hash=sha256:26013d768b2ea4728c09144b08c0eb86ad692e85cb15f4e52e3107abca83683c \ - --hash=sha256:27adf8869937461ad08c5fefb47857532e467b408db496db4dbf8b132a4bd623 \ - --hash=sha256:281f67af1b8df88741eef551afbb49f78e4f366a7ab23e7060a1f0d6ba655752 \ - --hash=sha256:29fc241475801872dc27c3dd1a3976373536223dd4fd1c01868ff86bdbbfd48b \ - --hash=sha256:2b72312a8b62a905da6133effbba9b0731c8e30af96e10ca77fc5c34532c6827 \ - --hash=sha256:2cb72808dfc46c40a6ee352ace181ce3170adde1cfd1447da91709a8cf482e20 \ - --hash=sha256:38216e13d6f2e0d4513a5b8806e70ce4a8f28a82962793a67371582fc2c7141b \ - --hash=sha256:3f654b01d8d49f68deedfaff1edcff314e3103d29130b2a034df6c490c522351 \ - --hash=sha256:51d6a5390e2454b599500049f0a5c72aa701db155c1e542f9a1157c1c45814b1 \ - --hash=sha256:54afde4aaa5b55fbc2c075e1c55fb14a5739459428f3bb81f849ad020f7d5bcf \ - --hash=sha256:572bd5a01089ab92da12f4f52b32b878547bbc544a798d8cfd042e7fc2601c75 \ - --hash=sha256:5a0113020d86e8f61c7a2ae3d508720cd036df7462a55926b85dd97ada27e143 \ - --hash=sha256:5f9858b5ccdf75dd89c20d74474b59dd3a2e2f86c7251b310011c46acdef3874 \ - --hash=sha256:638047c1f70fb14c9d8f743931d4f4f42aff6793b47afded3097c002ef8c1165 \ - --hash=sha256:63adca0f9219be3fe8789f4aa7b77c5f6a7bf65d6442959db52c653140ca4185 \ - --hash=sha256:7552fb7189acd06161f8feac7045a387dc9e03b3b9f7dcb5675178906cee792e \ - --hash=sha256:7a2f371af54cd1d153ef373a733889ebfbcc9c30e00429fc12a2569bad9239e1 \ - --hash=sha256:84b24f69a7bbe76302330d47422a7fcc1998a6a96ffd414a795d7d95992b49cb \ - --hash=sha256:891a1b6a111a591ad9f1c9e088846848dc9e6be030a6086c8c3aa5d2d837f266 \ - --hash=sha256:96ad742f5cbfb771df512959ab5de36e248ce9aa2c487fd81c37d5c0a627c094 \ - --hash=sha256:9abedc832e9a6636741299aae46c032d8c1248b507d8cebbaa2f48ec202904bc \ - --hash=sha256:9b7032b44769c454e96aa11483bfd167a87ea341268f1075b0ff84f780c910a9 \ - --hash=sha256:c935431682557ffcd3efc1c7bcb01b0f6769a1c90751a7154d5e3c905a6a2042 \ - --hash=sha256:e1d09691d757f5b1900a98cc3b6cc7d8506683a2188c01eca86545f91edbbaf5 \ - --hash=sha256:facd488c2b9be8bffcad5903566581e96d2863d2ec4bcad7f114d1b2b2f39ad0 \ - --hash=sha256:fcf45725ae1751cb934b9b827a7d9cd899bbd09eb1ad28e2160b4584de35ba77 \ - --hash=sha256:ff6b82ee4533f6fd4474d833e693b44b984f58337173ee98ed76bce08721a636 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via + # mlflow-skinny + # mlflow-tracing + # pymilvus +cassandra-driver==3.30.0 \ + --hash=sha256:0c28a8e84917acebecbaed39844047c2f135739c3627dd7b9f8541af33e11df3 \ + --hash=sha256:0f4225082a11d9529416c223553ab38a29c4e65da6646b40159c554480dc002c \ + --hash=sha256:136b46437b9902673264e101cdaab309d3e40607bff34430bda86b785badc6e4 \ + --hash=sha256:137498e2a9b6f578d1902e1af8a988e50b8fe134c76a176f1b8a774e906bc66c \ + --hash=sha256:17fb53587c9fc6a27b5c4a89b4f3d9169be43fc572d6f3f67494aa74708be936 \ + --hash=sha256:1d64cbdce764c33e284d339b9a749736d68971edf8b537888f2d13c4b0d1313f \ + --hash=sha256:212af4d8ff934c30538f4bdf7da61f14dc9a30349f6cac2161c8125e56fad928 \ + --hash=sha256:2637644eac9274e46b0c2a7f729158bdf8582b6842dc48e18297211dd3ee1fec \ + --hash=sha256:289e86c81be2543cb9055600c0819850db921e6e138a84e5c88ec160662c7207 \ + --hash=sha256:2a0679ebcfdcecb3763c690b5bc6a517e0c0803f7bc88e0a6c793e5e421b558a \ + --hash=sha256:385134eba72f048707cd800de0a61cf3c23246113edffe9bc6bc2eb86282d26b \ + --hash=sha256:5c6cbb396ad6fe456efc799d3b8b6bda360ffc06552c5be2ce1a88ac381a305c \ + --hash=sha256:61d7eeb17d8f76d5b4a9b1239145250f2a9f7bf949c30e2cc36196b5a0523ce1 \ + --hash=sha256:6a5c8982f2b9eb4e789fc12cdd930b1e1511b6d046dde31d0703f855745556a3 \ + --hash=sha256:6d449f49ce866ac20a1c3d80b1f9245ecdfd1e67b843dccd3d6eccdfe519c02e \ + --hash=sha256:7e4cfd6ec3023576ed0ffa34882d9778e4bacfd918048ae9139ccdd00628ed85 \ + --hash=sha256:83a9148d408a3dbb48ea1802d643d60fa53cd69dc7b9a244511ecf5b917e4f53 \ + --hash=sha256:8c4acd28791854c23ca68be50a7a750c9413ba80fec0ca5c27c2be05f6f3fe0a \ + --hash=sha256:8d5e3575ec01d8c043b56ff25de6f61ff4c9ed5cb3ea4c3d9df98def71ba710c \ + --hash=sha256:923a6e1c3fa5f98f846a028b1a7207ec9e7d8cfa54ea47a507d41122efa2f54f \ + --hash=sha256:c1b4aa6c7706dec839134adb6a2094d90c5f6f35efa08028ed6aae6e67c8643e \ + --hash=sha256:c64e20bf46b49f8ef64569208d4a395b0928c27d5960559922a2d13471924d0d \ + --hash=sha256:d2f9e00127f70dff42d4ef932df8a6b81170c2861d4e75c8b13f4b4816b4450c \ + --hash=sha256:d73c0429813045ba86b92fc033fbcfd495aa10e9d4a40fe30b6e9dfe8b5d3ab4 \ + --hash=sha256:e12dfcd3f0074c16f4bfe650242edb406b935864373ae86160e09e3f5e437e84 \ + --hash=sha256:ff2e9fbdc1be54c1d041ea3f7d09812442f334be14bb5ad7aede175544765d25 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # clickhouse-connect # docling @@ -517,203 +528,218 @@ cfgv==3.5.0 \ --hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \ --hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132 # via pre-commit -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.2.1 \ - --hash=sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202 \ - --hash=sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask + # flask # geomet # great-expectations + # mlflow-skinny # pip-tools # ray # typer # uvicorn -clickhouse-connect==0.13.0 \ - --hash=sha256:0f7223ccfc24394e24c6376c32f63325e3eb56df7e0a7e3e7b23040d7a73e180 \ - --hash=sha256:170e39ef6d76a2da322aa8f06ee4b0f2a91954a9a894b5dbb24e3e0ebaf994ff \ - --hash=sha256:17a6c60fddcc7894245692729fac88769036ae2e9243c45882dcd0234227a1a9 \ - --hash=sha256:18303de2a0058bf594dc7991d5bba95d4258249c80d7c04770cfd410a5238924 \ - --hash=sha256:1b2b1258d8fa4e840be929142f0cd60e534d4763c9132d59f1be7bc9529042d3 \ - --hash=sha256:2b8bbf54bd5cb69791201a4cf4fd4c4a677d7e4cc2a6f60c58af6092f715d0cc \ - --hash=sha256:33fd35aa22ef3a5b44a46ef2fc7510723db2bc5b1c466d147da34c2da974fd9c \ - --hash=sha256:4d4266f5bf7f26a00d335de4eaabb74cf7dbf71056ee256673b040ac68378805 \ - --hash=sha256:4fb2394c9300265f2cb9739ae8acc71630b2aa6e53d829706fe3da9a05c26599 \ - --hash=sha256:52ced166cff735db529780d388c3192d8ec4fb09d5e5acf46ed6dc43e9aa5d80 \ - --hash=sha256:56bb65b08bb40e0c356559666a47c164e55266181601367f8165524052019079 \ - --hash=sha256:56edc95c954e14ec4d5360ee93382566a48c7f00196c4b8d75d5f4874f93c730 \ - --hash=sha256:5a1a654db64fca213920c2dc07524a99b8ecab64f1c0dca321c9f389694dc5af \ - --hash=sha256:5a5e58fb3229f06fb0c60a9e893cda1d181e21ff2e31fb8c51641dd035d12c34 \ - --hash=sha256:5c4ea58b450a0815a85550ce6e10b7ed9a6e0b902bf4d97286c9cf73f9692e4c \ - --hash=sha256:7121fa8c80554dc3facc65c930e04e43033e7fa5d7fc3359e2c0d85c39854d58 \ - --hash=sha256:7322aec94c8e337a6cb120c806fa13b8fd9b1286c89ed755b2cfa9937953f2ed \ - --hash=sha256:746254b0c6c97fc912f0b4b11909d4576b57db614fbc408cfcc45804474fb7de \ - --hash=sha256:804c4be52695ddd8a87b870bbab38dc071f5bf33bbe29566d4378321dbc67d04 \ - --hash=sha256:8569a33c5c884da1c8442172603f1376871876e726d0b679901834e767918ad4 \ - --hash=sha256:859d58c8f0ddc632885ee206bf96e27f02cec6e985995d77f18a458929cd808a \ - --hash=sha256:8832c907756b8564f3b9cdc1a41c22cddcb69801613eefd15b2a9eea2e40ed53 \ - --hash=sha256:8d4283d6e8a41ebbd304574f2da2773c74e12b6e9fd32ed2ea133494e4f6ca7e \ - --hash=sha256:913a53f6b0d948b60fbafe5cb5ae2c10fc2347cf0e17917c842223e571bdbaa5 \ - --hash=sha256:974b0800656b372aa001c9e0fd958a4b43086e4650bbc571aaed3993607bdc69 \ - --hash=sha256:97d00f52f7611ff2e7a0b58d8e3cb0ea470dcbfc56ac6469163c36e4caf7d14c \ - --hash=sha256:993eb2887b01a9714da4d68c1b8c97d91e267ba5510374955c0dc5ae34554923 \ - --hash=sha256:99f198ed4cb99924cc80b69270a4fea1f25cde8cf2f6fb26fde4f9ac9e99cc97 \ - --hash=sha256:9ff33742d7380a1b072e19f84ae9dd7863ae00483731f3a5ff3b18cdcc9a60e9 \ - --hash=sha256:a373713c1f2c3964474cdfc69cff29090ead1d142c41c6fa8cda3ab34dce2916 \ - --hash=sha256:a4712c2ce29f70c1f194f3f92c98169d600390f288295271c6eb0feda8b24548 \ - --hash=sha256:a668810f0b670d7c284c119100af019a3e405cd3d61e08a4a2dff3ecea802c4d \ - --hash=sha256:ae8b308a34b4c6b1e0d77c977a46fbd2841d926bedea37f57618c4dd6cef636d \ - --hash=sha256:af5a6e924111b2fa4e6c17d7425f842f54fb2a014ad7a793a91462dccbdbca4e \ - --hash=sha256:af703d0477c081e2d32297abf8af2fe9aa61a9aa818b1f3b7a473de9c58d822e \ - --hash=sha256:b11ae56992f7d972692ae4d38e79de2a52333a5e38a55a144fb47f644b921cc5 \ - --hash=sha256:b1b0c92c91f2f3d0f2422d1c938af221abad2d6fda50bb4c816ebac373d5ddf1 \ - --hash=sha256:b5a2eb5851dfd8469d4b6253f5ec4666fb9fba018b47ac35d15fa2bca62b4979 \ - --hash=sha256:b60b54ffbbd65a630bc551fa979bfa47f0ca3dceeccd6ebdc043c66b30eed714 \ - --hash=sha256:b7f4cdc2b34f7b88e4c96c3e13a2574732c3bd6c21a6b2b2ab2b1fc3914301f1 \ - --hash=sha256:b9ae5a28c511e7680224f868acd461f7cd3d8793ea8545f22bafb71d4235b663 \ - --hash=sha256:bb8e8d508ff0331e34aef747d0cf5748ca0736e982c785b4aa08fca984459db5 \ - --hash=sha256:cc9781d0fdd31108d1c707cd3c3b7e50f97f819c6dc10d71b86c2d3bb6b83a49 \ - --hash=sha256:ccbb7d8e43904074eb66ac99dd58750b4d68501d2e794169ca8e3b27ba6c35db \ - --hash=sha256:d30ce9f85033325ab042e9f515dc2d9375fd972f71169d46181bc41ede77305b \ - --hash=sha256:d7756cac9afa4dde22549f271b3bbf6739f4f4a533e45f1ffc3faaaf87086371 \ - --hash=sha256:d7a574b53d41769e352a149fe52904859ffccd423cf11c69dc21938ff94235e7 \ - --hash=sha256:d96fb3c6912cd570b37a4de5e93cc7528afe56f10e5d8f33ed8c7a26fe24e7d1 \ - --hash=sha256:dbc8871ead7d06db00980bd6d59d899add80b0184e52b33a14ed23ac4a8109ea \ - --hash=sha256:dcc6c5106b436cb63af4b47b22dd75f38497e61857b3fefb2226562040884a5b \ - --hash=sha256:e04d4b11b54e33d12218add69a6eac2d4fa3262b522489663ab948c08eb27f1f \ - --hash=sha256:e2267b41e69203e334761f28f1102ad47d3ff218e565b06b215b61f1f62e4171 \ - --hash=sha256:e449006b1606e22822695c85d4fc1faf3c1d0a5a3622d4b8fc28bfa014dbb295 \ - --hash=sha256:e72aded5dbb2e2fa8d6a2d70ef061556ff94baec3eca8b800c45e103507aa90f \ - --hash=sha256:ed741ab68b6226669f3b09fc663710764b985f83c0c9f753a8ae98276893284b \ - --hash=sha256:efa3d8d968e66ef0fe79fc880b824368787329e63b61feab86194e113a7795ff \ - --hash=sha256:f0c9efea902187f1de351bc32995d08d1f1f27350798508f8a6c238ecac4ccb0 \ - --hash=sha256:f1ee372499dfa784653cba035df6a6b12ed67c74c8c42ace13c3af99db4491f0 \ - --hash=sha256:fa9ef035faaa60f06470b15f6c1912b4b402b03dc9d4de07d445b9e817c933f0 +clickhouse-connect==1.1.1 \ + --hash=sha256:0b602967810358408ebd55693fd582f3a20e08800f721fb72ae320f0f74686ff \ + --hash=sha256:0bb2c8f82bb2bd5f645c0114d5d766a95dc1e0dec33c07deafa5a68dbb75f898 \ + --hash=sha256:0e9e294601aac4de51ac7cd2423176fe5111da41b5d120047606eb855795853c \ + --hash=sha256:0ec2f574530c65412a490ac6a29445509ca6346dbb15d39a825e27c73d680f3a \ + --hash=sha256:10055ae880742ffc61244eb129bbbafa6fe97731aa959d717b16513b5094255a \ + --hash=sha256:10c0354b858f500f4f26195dc37cd6047eb4d324b0b08ca6873e2241ea4a2ea8 \ + --hash=sha256:11ca173d36405d446f97dfea0a3e1531389d90d23c686ec18ebcbc0eed17200e \ + --hash=sha256:1284cb2a73b6af208aac06ad04d9121a8aa33f4b971b9d5a65264d2137b5cf0f \ + --hash=sha256:1781f330cd0678b203dc35d5df85c3b212577412c0dcf664432edbfc71a20489 \ + --hash=sha256:1e2b000c55e698220cba80e660349c60d7acb3b82172c320a51519d191e24826 \ + --hash=sha256:22ed08e9a361e1d21762c68275610ee0e023f281fe9a1653763b62fc5585a6f0 \ + --hash=sha256:233cc6eae3dbec122ed7ff694f657aa9676b36c2acbcef64e97166e4f75f5040 \ + --hash=sha256:27b665a01711e9a5b08e4412d501baf76ce4ccbeb937ec67e73040094492adbc \ + --hash=sha256:2913a4c96c3aede2b39489731eb8c39e37792755df9b56548b162ab1e09df4f3 \ + --hash=sha256:2c9a1bdb1d9705a270ec8036cd89113db04f4437a4d3b5db0774312ec4d06e30 \ + --hash=sha256:3cdae5ce54cc7d5fdaced13857612b25ae58f0830987a4b17ebcf376d71df3b2 \ + --hash=sha256:43e1fb7d588a799a3e55a4982946d59484edf1e960abc9e7ac330a3330ee4fc5 \ + --hash=sha256:49cb0d82e3f68d7304275bf350419095c080ddd49f99704dd44a956273fa7c09 \ + --hash=sha256:4f0c6c52245322c04bdccc71565ac8db9731e1787c90665df9167928101f0b89 \ + --hash=sha256:4ff227719006516877b5152e89cba514ceee9807e6b030a1ddba8d9355b87412 \ + --hash=sha256:6062c400d67dd4ab03fc3f9473134fc0a240593c242998d032d32cb04a65f083 \ + --hash=sha256:646408372c2a4b0e4068145897a35100cefc6974a409c68b20ba22403665fe5a \ + --hash=sha256:68d6e245db80ea42c59c32dbed655f28e82337d61405dde6aa5e009c507a6eee \ + --hash=sha256:70b9dee3c4629e06f2b5788d02b6cded0a32d2509966bc293cf1c39abc395a29 \ + --hash=sha256:763f7fabc921ee9fb4c07d180447a6324980bfeb981c3f53065d04bda5f133b7 \ + --hash=sha256:770da683bf65d3536c46d564e5a9311d6cd40d191a0357a762ac702813774965 \ + --hash=sha256:784a1c9513a33f6f8df0c260e43ea5cdc5fde0a2c91bca7e69ce26bc4990abcd \ + --hash=sha256:7fb296b2c51e5ad8d7f677a08a093b3b122cd4411619678a968567f3b34bf075 \ + --hash=sha256:8857676711197c981afc317a38ad1b92aedcf81b7052e67098f40adcf4b5d4ba \ + --hash=sha256:8b0590065a4c6551d1145229adf3405befc053843f6b1ffeb3802ae7221d53dc \ + --hash=sha256:8f2f9029f6589d2d349912a94a17d9997c550a7f19dd5b747f6b452764dc0e54 \ + --hash=sha256:92d885943b1b0a1489501408d6af91ec2d96189dbc475f3552f22cd43c9c6270 \ + --hash=sha256:9de3999bad13146823e9c6811dbe9a66653bf5c71980472f8fe5165d186451ee \ + --hash=sha256:a4639a1c6291358a0dd40ba0a6a6059eb5fcc9acd6f4cd61eb52b3cb5165d37e \ + --hash=sha256:a4740e012dc4ed2fab769dba4b13be92142e2df2bfb0de547b0b73f13296bcb8 \ + --hash=sha256:a6c0a8f1c4e4954161051b26bee8d24f1e53254125d2bf6e18c9360cd41fe059 \ + --hash=sha256:a706631a540ac21aac4434a446d50263c0872c9507bc6a0ccfb51467c0ff74a4 \ + --hash=sha256:ad6b32a1bb391f15345c6af4ecee152e04362c6331cd93472f2fa5e64f8a9aaa \ + --hash=sha256:b1e83e71d5b0df09cb807657ab0457eb1fd116a331039d3c5d3051387092ff6a \ + --hash=sha256:c336452cd5aeada902ac41d57296498766f95a175cb1dcf13d48479b5b31ac6b \ + --hash=sha256:c54bdd8870a644a9baa7cd68fdfc5100f5b19aa246657be863788a6a7bf4052e \ + --hash=sha256:ca28e361a51afe2e7e2fcff47c1423fd61271d26af7d19e37f6ff0ab67bf086f \ + --hash=sha256:cd501e3ccee60d4cccf5cde4b4c92632b62763563b08aa07dbfd3e2583c12005 \ + --hash=sha256:d1df245b5c21fa7bd70193164cc97f3937ccee3087dbc7906daf2e97b226b2a8 \ + --hash=sha256:d3b3806986340192ed2b197241be193649717cc58f7ef9bdf86d119758289a0f \ + --hash=sha256:d4a5e4b36219d678d495120007d0ba8b7d1bf4c5105292b35fa4473038fc2892 \ + --hash=sha256:d749389301b201ae7329c8fc96599fc116de8aadc16a5a4416e399483c569ea9 \ + --hash=sha256:d84c8ed4cc26976d2cc6725e36b85d4e24f1c43c11d82483b3060116ac0bcfd4 \ + --hash=sha256:dcdfee2f707225bfbd80ba2da5c995a38393aa02920adf770264c6f5b041e9ed \ + --hash=sha256:e762f70ebf57cb43a6257daa6196f5beb574d69915dd06c29735d5811dfd8dce \ + --hash=sha256:ee7d8308c8a688c6851b19d2bc743a02ed5d6f8679203a13872a80cf4066dd57 \ + --hash=sha256:f205be896551d7ea0a0140a86e36d261e249f99541d68a3dfdd47dd8c7c2bbbb \ + --hash=sha256:f552668320b8c533b6f2b93d03dd4840cfe0e8f5f01c76ea0d2989e4127fa60e \ + --hash=sha256:f75e0d62bdb53ba72fa2aa962950c5c107627158c9fe8900ca14da557295bdb2 # via feast (pyproject.toml) cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ --hash=sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a - # via dask -codeflare-sdk==0.33.1 \ - --hash=sha256:6622a73edde5042455ae7d76279a5279c55db4950533ea7f12aac2fc51d49bb8 \ - --hash=sha256:ad41ec5260217fd030904fb4b9fe62e26c3f51ac7999a5d607eb4b1359edd5e5 + # via + # dask + # mlflow-skinny +codeflare-sdk==0.37.0 \ + --hash=sha256:2106118d9341db7e329da59f296bc635c08e365d4a644013bb9a55ce38c54da5 \ + --hash=sha256:a5f86b9541a3ef2498bc920465b0e106c4e58bfa2004d14ff177f83761afd469 # via feast (pyproject.toml) colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ @@ -731,6 +757,80 @@ comm==0.2.3 \ # via # ipykernel # ipywidgets +contourpy==1.3.3 \ + --hash=sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69 \ + --hash=sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc \ + --hash=sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880 \ + --hash=sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a \ + --hash=sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8 \ + --hash=sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc \ + --hash=sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470 \ + --hash=sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5 \ + --hash=sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 \ + --hash=sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b \ + --hash=sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5 \ + --hash=sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 \ + --hash=sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3 \ + --hash=sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4 \ + --hash=sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e \ + --hash=sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f \ + --hash=sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772 \ + --hash=sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286 \ + --hash=sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 \ + --hash=sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301 \ + --hash=sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77 \ + --hash=sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7 \ + --hash=sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411 \ + --hash=sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1 \ + --hash=sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 \ + --hash=sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a \ + --hash=sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b \ + --hash=sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db \ + --hash=sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6 \ + --hash=sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620 \ + --hash=sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989 \ + --hash=sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea \ + --hash=sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67 \ + --hash=sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5 \ + --hash=sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d \ + --hash=sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36 \ + --hash=sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99 \ + --hash=sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1 \ + --hash=sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e \ + --hash=sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b \ + --hash=sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8 \ + --hash=sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d \ + --hash=sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7 \ + --hash=sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7 \ + --hash=sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339 \ + --hash=sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1 \ + --hash=sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659 \ + --hash=sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4 \ + --hash=sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f \ + --hash=sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20 \ + --hash=sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36 \ + --hash=sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb \ + --hash=sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d \ + --hash=sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8 \ + --hash=sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0 \ + --hash=sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b \ + --hash=sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7 \ + --hash=sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe \ + --hash=sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77 \ + --hash=sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497 \ + --hash=sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd \ + --hash=sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 \ + --hash=sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216 \ + --hash=sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13 \ + --hash=sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae \ + --hash=sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae \ + --hash=sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77 \ + --hash=sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3 \ + --hash=sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f \ + --hash=sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff \ + --hash=sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9 \ + --hash=sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a + # via matplotlib couchbase==4.3.2 \ --hash=sha256:032a180afd6621358b2c73543b9c5db9939b442fc3ad6d54417c36c8a8f65838 \ --hash=sha256:11ce688ed46edf8387bf51866618c7b4e06399e7fb34a6df002764996c109d1f \ @@ -797,142 +897,164 @@ couchbase-columnar==1.0.0 \ --hash=sha256:fc0fad2d386c5b5df7aaaccd8751e01caa886cc640cc8c92523dd07c4e7be519 \ --hash=sha256:fc4efa3e15190c3731478006de494b046bc57785e9c8ae99ac8b375a91683e38 # via feast (pyproject.toml) -coverage[toml]==7.13.4 \ - --hash=sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246 \ - --hash=sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459 \ - --hash=sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 \ - --hash=sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6 \ - --hash=sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415 \ - --hash=sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf \ - --hash=sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80 \ - --hash=sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 \ - --hash=sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0 \ - --hash=sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b \ - --hash=sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9 \ - --hash=sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b \ - --hash=sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f \ - --hash=sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505 \ - --hash=sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47 \ - --hash=sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55 \ - --hash=sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def \ - --hash=sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689 \ - --hash=sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012 \ - --hash=sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5 \ - --hash=sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3 \ - --hash=sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95 \ - --hash=sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9 \ - --hash=sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601 \ - --hash=sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997 \ - --hash=sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c \ - --hash=sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac \ - --hash=sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c \ - --hash=sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa \ - --hash=sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750 \ - --hash=sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3 \ - --hash=sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d \ - --hash=sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12 \ - --hash=sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a \ - --hash=sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932 \ - --hash=sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356 \ - --hash=sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92 \ - --hash=sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148 \ - --hash=sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39 \ - --hash=sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634 \ - --hash=sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6 \ - --hash=sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72 \ - --hash=sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98 \ - --hash=sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef \ - --hash=sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3 \ - --hash=sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9 \ - --hash=sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0 \ - --hash=sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a \ - --hash=sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9 \ - --hash=sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552 \ - --hash=sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc \ - --hash=sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f \ - --hash=sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525 \ - --hash=sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940 \ - --hash=sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a \ - --hash=sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23 \ - --hash=sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f \ - --hash=sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc \ - --hash=sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b \ - --hash=sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056 \ - --hash=sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7 \ - --hash=sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb \ - --hash=sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a \ - --hash=sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd \ - --hash=sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea \ - --hash=sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126 \ - --hash=sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299 \ - --hash=sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9 \ - --hash=sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b \ - --hash=sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00 \ - --hash=sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf \ - --hash=sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda \ - --hash=sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2 \ - --hash=sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5 \ - --hash=sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d \ - --hash=sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9 \ - --hash=sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 \ - --hash=sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b \ - --hash=sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa \ - --hash=sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092 \ - --hash=sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58 \ - --hash=sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea \ - --hash=sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26 \ - --hash=sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea \ - --hash=sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9 \ - --hash=sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053 \ - --hash=sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f \ - --hash=sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0 \ - --hash=sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3 \ - --hash=sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256 \ - --hash=sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a \ - --hash=sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903 \ - --hash=sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91 \ - --hash=sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd \ - --hash=sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505 \ - --hash=sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7 \ - --hash=sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0 \ - --hash=sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2 \ - --hash=sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a \ - --hash=sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71 \ - --hash=sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985 \ - --hash=sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242 \ - --hash=sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d \ - --hash=sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af \ - --hash=sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c \ - --hash=sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0 +coverage[toml]==7.14.1 \ + --hash=sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86 \ + --hash=sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd \ + --hash=sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d \ + --hash=sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5 \ + --hash=sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42 \ + --hash=sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de \ + --hash=sha256:10274a1fbeb8ec5d72966e17bb198a3104257aca4ac09d98667c5f8aca8c8548 \ + --hash=sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1 \ + --hash=sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7 \ + --hash=sha256:1238cb94638e610e972c60dac68e813f868dc7d6e982535270558443058d9d59 \ + --hash=sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906 \ + --hash=sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af \ + --hash=sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1 \ + --hash=sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d \ + --hash=sha256:196a13319ad88d6d8ef5ab489ec4f44ddde2143c0c7d5b27786f6c3ffd56a7e1 \ + --hash=sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be \ + --hash=sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02 \ + --hash=sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42 \ + --hash=sha256:23bf7fa51ac02e07fc7c96849b82946da47ae862dc8f86d183b2a4864fc38129 \ + --hash=sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e \ + --hash=sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be \ + --hash=sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e \ + --hash=sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65 \ + --hash=sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54 \ + --hash=sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1 \ + --hash=sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5 \ + --hash=sha256:3a56abc20a472baf0304c455721bc601477440d28ecfde8a03dde79ede07e0df \ + --hash=sha256:3c18ebc343e15be53049b3a2dce38fe82d58f37e20ab9094b3a39c0aa4f6bb47 \ + --hash=sha256:3d452fd08b5c72c5167c93e6867b5c08500bd40f2a21e1e854a500550b6cc36f \ + --hash=sha256:3e3680291c4a1d0dadfa84a2c459576a4af5133abb617905714339a0c73138cf \ + --hash=sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37 \ + --hash=sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4 \ + --hash=sha256:478b5bcd63c2e1357c5c7e16c070690df7b07f676b1c114d7b93e533c664309f \ + --hash=sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84 \ + --hash=sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1 \ + --hash=sha256:4ea1c034f95c9b056e856b794630b17f9fa3d57e4800ff1e503d3be0f9c9078c \ + --hash=sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8 \ + --hash=sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e \ + --hash=sha256:59baf88468dbc8d63b1887afd92bda52e40bb1561696e5819670601403810cec \ + --hash=sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d \ + --hash=sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54 \ + --hash=sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890 \ + --hash=sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b \ + --hash=sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d \ + --hash=sha256:62a9f70b52e0b5a95cfef4a5c5641b06983cadc5e538a3feeb5c00211f523ac2 \ + --hash=sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33 \ + --hash=sha256:6a3cb83d1552c0cd1b4906655b6a33fd4a8473229633a901c6b73bf86914dee9 \ + --hash=sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e \ + --hash=sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6 \ + --hash=sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce \ + --hash=sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247 \ + --hash=sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901 \ + --hash=sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36 \ + --hash=sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69 \ + --hash=sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416 \ + --hash=sha256:7f02d09f70776579b926d889a4c9c235070a1f47c40458aeaca563fae5acfdb5 \ + --hash=sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500 \ + --hash=sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad \ + --hash=sha256:84ac9499e48700399a5dd0ea7085b5091961fec52c68d66b4ec0d3cf7f4441b1 \ + --hash=sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b \ + --hash=sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b \ + --hash=sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a \ + --hash=sha256:87ebdf787d4888e3f3f2d523eadc6e18c6d18c6d0eb173801a189641627fb37e \ + --hash=sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee \ + --hash=sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07 \ + --hash=sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a \ + --hash=sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d \ + --hash=sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c \ + --hash=sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343 \ + --hash=sha256:a24a81f9715ee42ef59a316cc11611c98fe23920f7c81861315c9f3ff4a230f4 \ + --hash=sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2 \ + --hash=sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8 \ + --hash=sha256:a5274669f37f2343635a347b91a60777621341ab3378e9c6ac9335eee704bddf \ + --hash=sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb \ + --hash=sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c \ + --hash=sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff \ + --hash=sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e \ + --hash=sha256:b84ffdf877644e7096aa936991efeed873f7f3df57b9cd001312b7668ab08550 \ + --hash=sha256:bcaa50684dcaadfa599ac48f81103c756d791cfd85c97203d2217c593d48b860 \ + --hash=sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793 \ + --hash=sha256:c643734307300234fafa36bf2a040a7235f8f177ea1fd6ec1423aea6fb7b929f \ + --hash=sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851 \ + --hash=sha256:c7e057326434e441306226fbeb5d1aaf14a2637efe97ba668306635835f32ad7 \ + --hash=sha256:c912c259304cfb5ee584481cfb7ce1ff932b4d61e6c9140b8f19cb7b5ed82332 \ + --hash=sha256:ce66d8e46da2bb5ee313a745cbd2e391d319176c1f7a9451bfcd3a2fb920859b \ + --hash=sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2 \ + --hash=sha256:cfe5a5fec635799ef33428f1e5e61bafa45a92a96190ba731561ba558ccc214d \ + --hash=sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a \ + --hash=sha256:d34d75f892b3ab73ba11cab5442cce7b3e168fd64162b16f0e1e0d09c508edef \ + --hash=sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474 \ + --hash=sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee \ + --hash=sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43 \ + --hash=sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034 \ + --hash=sha256:dd34767fa19848d35659ffc0a75314f58c7af3f1cd87ec521e8292a1238398a3 \ + --hash=sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c \ + --hash=sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d \ + --hash=sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7 \ + --hash=sha256:e854312c4103f2ad4c0dc023b69b77ebfd2c89db5f86c4c94dc2353f9a92167e \ + --hash=sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d \ + --hash=sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4 \ + --hash=sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9 \ + --hash=sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52 \ + --hash=sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a \ + --hash=sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c \ + --hash=sha256:fc459e5d73be2d6332fcfe8dbf3d8994671fe33c700f4565988ecfa511547253 \ + --hash=sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c # via pytest-cov -cryptography==43.0.3 \ - --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ - --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ - --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ - --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ - --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ - --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ - --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ - --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ - --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ - --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ - --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ - --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ - --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ - --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ - --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ - --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ - --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ - --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ - --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ - --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ - --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ - --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ - --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ - --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ - --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ - --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ - --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 +cryptography==46.0.7 \ + --hash=sha256:04959522f938493042d595a736e7dbdff6eb6cc2339c11465b3ff89343b65f65 \ + --hash=sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832 \ + --hash=sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067 \ + --hash=sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de \ + --hash=sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4 \ + --hash=sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0 \ + --hash=sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b \ + --hash=sha256:3986ac1dee6def53797289999eabe84798ad7817f3e97779b5061a95b0ee4968 \ + --hash=sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef \ + --hash=sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b \ + --hash=sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4 \ + --hash=sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3 \ + --hash=sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308 \ + --hash=sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e \ + --hash=sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163 \ + --hash=sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f \ + --hash=sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee \ + --hash=sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77 \ + --hash=sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85 \ + --hash=sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99 \ + --hash=sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7 \ + --hash=sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83 \ + --hash=sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85 \ + --hash=sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006 \ + --hash=sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb \ + --hash=sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e \ + --hash=sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba \ + --hash=sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325 \ + --hash=sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d \ + --hash=sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1 \ + --hash=sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1 \ + --hash=sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2 \ + --hash=sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0 \ + --hash=sha256:d02c738dacda7dc2a74d1b2b3177042009d5cab7c7079db74afc19e56ca1b455 \ + --hash=sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842 \ + --hash=sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457 \ + --hash=sha256:d3b99c535a9de0adced13d159c5a9cf65c325601aa30f4be08afd680643e9c15 \ + --hash=sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2 \ + --hash=sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c \ + --hash=sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb \ + --hash=sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5 \ + --hash=sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4 \ + --hash=sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902 \ + --hash=sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246 \ + --hash=sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022 \ + --hash=sha256:fc9ab8856ae6cf7c9358430e49b368f3108f050031442eaeb6b9d87e4dcf4e4f \ + --hash=sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e \ + --hash=sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298 \ + --hash=sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce # via # feast (pyproject.toml) # azure-identity @@ -941,6 +1063,7 @@ cryptography==43.0.3 \ # google-auth # great-expectations # jwcrypto + # mlflow # moto # msal # oracledb @@ -950,59 +1073,69 @@ cryptography==43.0.3 \ # snowflake-connector-python # types-pyopenssl # types-redis -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +cycler==0.12.1 \ + --hash=sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 \ + --hash=sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c + # via matplotlib +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.6.1 \ - --hash=sha256:140ce500bc41939ff6ce995702d66b1f4b2ee7f117bb9b07512fab6804d4070a \ - --hash=sha256:f53228e6dadc9f837037b1bf3051d7d8c054abbb3eb29f1f022926e08090e0da +databricks-sdk==0.114.0 \ + --hash=sha256:25a40b83d76fa6c8a621f884da41e45e3ae5267218dafa71db9b363dd9238f57 \ + --hash=sha256:d62e6fcb1dc98b0b390d369261d1d68a6cf9f91139c34cf659865faf50b1d044 + # via + # mlflow-skinny + # mlflow-tracing +datasets==5.0.0 \ + --hash=sha256:7dd34927a0fd7046e98aad5cb9430e699c373238a15befa7b9bf22b991a7fee6 \ + --hash=sha256:83dbbbdb07a33b82192b8c419deb18739b138ee2ce1a322d55ce6b100954ec1a # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.12.0 \ - --hash=sha256:3db93df7969c3f22c6fbf75a51b0af4c21b189d8db6f3c54e8471102c775bb0d \ - --hash=sha256:9d1c0ed41926102c1c39fdd780e1a332f58c9b794e94dba0dcf5dfefc847d6ea +dbt-artifacts-parser==0.13.2 \ + --hash=sha256:9eca1e413f7eee522cc1556634b0b9effe790b70d8ffcc46ae2328b9868efaf1 \ + --hash=sha256:abb798aa73ff8cc295b4ecf03ee02d6a3bc48ad79f7d093d4bb3ffef68e77fb4 # via feast (pyproject.toml) -debugpy==1.8.20 \ - --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ - --hash=sha256:0dfd9adb4b3c7005e9c33df430bcdd4e4ebba70be533e0066e3a34d210041b66 \ - --hash=sha256:157e96ffb7f80b3ad36d808646198c90acb46fdcfd8bb1999838f0b6f2b59c64 \ - --hash=sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb \ - --hash=sha256:20d6e64ea177ab6732bffd3ce8fc6fb8879c60484ce14c3b3fe183b1761459ca \ - --hash=sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f \ - --hash=sha256:3ca85463f63b5dd0aa7aaa933d97cbc47c174896dcae8431695872969f981893 \ - --hash=sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390 \ - --hash=sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d \ - --hash=sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33 \ - --hash=sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 \ - --hash=sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a \ - --hash=sha256:60f89411a6c6afb89f18e72e9091c3dfbcfe3edc1066b2043a1f80a3bbb3e11f \ - --hash=sha256:70ad9ae09b98ac307b82c16c151d27ee9d68ae007a2e7843ba621b5ce65333b5 \ - --hash=sha256:760813b4fff517c75bfe7923033c107104e76acfef7bda011ffea8736e9a66f8 \ - --hash=sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec \ - --hash=sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344 \ - --hash=sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf \ - --hash=sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b \ - --hash=sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173 \ - --hash=sha256:9eeed9f953f9a23850c85d440bf51e3c56ed5d25f8560eeb29add815bd32f7ee \ - --hash=sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3 \ - --hash=sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be \ - --hash=sha256:b773eb026a043e4d9c76265742bc846f2f347da7e27edf7fe97716ea19d6bfc5 \ - --hash=sha256:bff8990f040dacb4c314864da95f7168c5a58a30a66e0eea0fb85e2586a92cd6 \ - --hash=sha256:c1178ae571aff42e61801a38b007af504ec8e05fde1c5c12e5a7efef21009642 \ - --hash=sha256:c29dd9d656c0fbd77906a6e6a82ae4881514aa3294b94c903ff99303e789b4a2 \ - --hash=sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393 \ - --hash=sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b \ - --hash=sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7 +debugpy==1.8.21 \ + --hash=sha256:0042da0ecd0a8b50dc4a54395ecd870d258d73fa18776f50c91fdcabdcad2675 \ + --hash=sha256:0fddfdc130ac6d8bfc0415b0409822fa901c8f310e5c945ac5653a0352532344 \ + --hash=sha256:13678151fc401e2d68c9880b91e28714f797d40422994572b24560ef80910a88 \ + --hash=sha256:15d4963bd5ffa48f0da0947fd06757fa7621945048a14ad7705431566d3c0e7c \ + --hash=sha256:2c2ae706dec41d99a9ca1f7ebc987a83e65578363be6f6b3ac9067504917fae1 \ + --hash=sha256:3d6922439bf33fd38a3e2c447869ebc7b97da5cd3d329ff1ef9bc06c4903437e \ + --hash=sha256:4743373c1cac7f9e74a1b9915bf1dbe0e900eca657ffb170ae07ac8363205ae9 \ + --hash=sha256:4e70cc8b5079f885cb43910924ee0aab73b8b6b2a14eff23afdd9895d86e79eb \ + --hash=sha256:4e7c2d784d78ad4b71a5f8cd7b59c167719ec8a7a0211dbb3eb1bfeda78bc4e2 \ + --hash=sha256:72b5d676c4cbfac3bac5bb01c138a4656e843f93f03ce2a5f4e394ad49fbee73 \ + --hash=sha256:84c564d8cc701d41843b29a92814c1f1bef6798724ca9d675c284ad9f6a547d7 \ + --hash=sha256:8eeab7b5462f683452c57c0126aaa5ec4e974ddb705f39ba87dff8818c8e08f9 \ + --hash=sha256:9bb2a685287a2ac9b181cde89edcec64845cb51de7faaa75badb9a698bc24782 \ + --hash=sha256:9f5171176a0084b95d2ebe55a4d1f7b2a75b74c5dbec577ebd3a85c740551c36 \ + --hash=sha256:9f96713896f39c3dff0ee841f47320c3f2983d33c341e009361bb0ebc79adc4e \ + --hash=sha256:a3c53278e84c94e11bd87c53970ec391d1a67396c8b22609fcac576520e611a6 \ + --hash=sha256:a7fe47fd23da57b9e0bec3f4a8ee65a2dc55782455ed7f2141d75ab5d2eaeef5 \ + --hash=sha256:aa648733047443eb1d07682c4ef287d36a54507b643ffdf38b09a3ef002c72a0 \ + --hash=sha256:aa9d941d6dfe3d0407e4b3ca0b9ec466030e260fbf1174094f68785680f66db6 \ + --hash=sha256:b1e37d333663c8851516a47364ef473da127f9caebe4417e6df6f5825a7e9a92 \ + --hash=sha256:bd7ba9dd3daa7c2f942c6ca8d4695a16bf9ac16b63615261c7982bc74f7ed20c \ + --hash=sha256:c193d474f0a211191f2b4449d2d06157c689013035bd952f3b617e0ef422b176 \ + --hash=sha256:da456226c7b4c69e35dbe35dcee6623d912000a77816db7856a41af1c72a0264 \ + --hash=sha256:e935f9dc0501be523c8a8e1853c39432e1354e9ece717ae5998fd2371c4542c3 \ + --hash=sha256:ecbd158386c31ffe71d46f72d44d56e66331ab9b16cad649156d514368f23ab2 \ + --hash=sha256:f15c10084f9861b5e8414a48f18f8e4aadf51a98a59e72c16aa28281ca994672 \ + --hash=sha256:f68b891688e61bdc08b8d364d919ff0051e0b94657b39dcd027bc3173edb7cdc \ + --hash=sha256:f843a8b08c2edeaf9b1582eed4f25441af21a297c22ff16bf76a662557aa9c9e \ + --hash=sha256:fe0744a12353406de0ae8ccff0d0a4a666f00801a3db8fd04e7a5f761cd520e8 \ + --hash=sha256:ffd932c6796afadab6993ec96745918a8cb2444dbd392074f769db5ea40ab440 # via ipykernel -decorator==5.2.1 \ - --hash=sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360 \ - --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a +decorator==5.3.1 \ + --hash=sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82 \ + --hash=sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c # via ipython defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ @@ -1019,6 +1152,10 @@ deltalake==0.25.5 \ --hash=sha256:cb1c7e826fd7c3bdd3676c7471d3b551e1a3674e44cd8e3747a0017a2c0292b7 \ --hash=sha256:e8f0d24bf64455f702da8402307b22e01f91e0f76694f7c5e33c9513011e8d29 # via feast (pyproject.toml) +deprecated==1.3.1 \ + --hash=sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f \ + --hash=sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223 + # via cassandra-driver deprecation==2.1.0 \ --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a @@ -1030,28 +1167,36 @@ dill==0.3.9 \ # feast (pyproject.toml) # datasets # multiprocess -distlib==0.4.0 \ - --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ - --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d +distlib==0.4.1 \ + --hash=sha256:9c2c552c68cbadc619f2d0ed3a69e27c351a3f4c9baa9ffb7df9e9cdc3d19a97 \ + --hash=sha256:c3804d0d2d4b5fcd44036eb860cb6660485fcdf5c2aba53dc324d805837ea65b # via virtualenv +dnspython==2.8.0 \ + --hash=sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af \ + --hash=sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f + # via + # feast (pyproject.toml) + # pymongo docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 - # via testcontainers + # via + # mlflow + # testcontainers docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.69.0 \ - --hash=sha256:4c3817ce00c7cb5622e59ddb4e5268a58083ae67f6e1436b36a84b6b4bbf6899 \ - --hash=sha256:9760e13063de5f373dbc3417de3ef9a3709c6eb18c0e60ada3c1f96c8b37c14e +docling-core[chunking]==2.78.1 \ + --hash=sha256:7463a2ce3e70590f330cf16dce11a7dbb761ece007a50e9082b44b7fed849820 \ + --hash=sha256:a700d4dc98592e95c05c57ae8d25698f514b8dfbe25e97f36a314f85e9cc0684 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.12.0 \ - --hash=sha256:008fe1f5571db413782efe510c1d6327ea9df20b5255d416d0f4b56cfd090238 \ - --hash=sha256:85c2b6c9dbb7fbb8eaf0f2a462b5984626457a6dc33148643491270c27767b46 +docling-ibm-models==3.13.3 \ + --hash=sha256:50fc83d244ce2dc43158e02155d1caa68374d7a169d0f34e67d7eb14f396ffe6 \ + --hash=sha256:8c8b55e80b3d20fc74d85ca49a4d064578ef75b9f7251eec42fc9df6af426218 # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1086,42 +1231,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1130,13 +1275,13 @@ durationpy==0.10 \ easyocr==1.7.2 \ --hash=sha256:5be12f9b0e595d443c9c3d10b0542074b50f0ec2d98b141a109cd961fd1c177c # via docling -elastic-transport==9.2.1 \ - --hash=sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4 \ - --hash=sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d +elastic-transport==9.4.1 \ + --hash=sha256:186a29e6c66ff269487e33f7b17176316e18b6061702c25eb0bb15681302e91d \ + --hash=sha256:d12c86ea73528690ebf63a488d9ae323292e6aa5ee55e1e29f14293472f4197f # via elasticsearch -elasticsearch==9.3.0 \ - --hash=sha256:67bd2bb4f0800f58c2847d29cd57d6e7bf5bc273483b4f17421f93e75ba09f39 \ - --hash=sha256:f76e149c0a22d5ccbba58bdc30c9f51cf894231b359ef4fd7e839b558b59f856 +elasticsearch==9.4.1 \ + --hash=sha256:1d78fdfba97a903ec35a5eb5808a74e33392b7c620bd5f742d465a3a26c27d75 \ + --hash=sha256:71ab71c3d1b20fd88c2922fb82c3277cce7ea03c160686e7b9368b265c2b4cac # via feast (pyproject.toml) entrypoints==0.4 \ --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ @@ -1150,9 +1295,9 @@ execnet==2.1.2 \ --hash=sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd \ --hash=sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # via pytest-xdist -executing==1.2.0 \ - --hash=sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc \ - --hash=sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107 +executing==2.2.1 \ + --hash=sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4 \ + --hash=sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017 # via # codeflare-sdk # stack-data @@ -1183,12 +1328,13 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp + # mlflow-skinny fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d @@ -1197,9 +1343,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via # datasets # huggingface-hub @@ -1212,6 +1358,68 @@ filetype==1.2.0 \ --hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \ --hash=sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25 # via docling +flask==3.1.3 \ + --hash=sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb \ + --hash=sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c + # via + # flask-cors + # mlflow +flask-cors==6.0.2 \ + --hash=sha256:6e118f3698249ae33e429760db98ce032a8bf9913638d085ca0f4c5534ad2423 \ + --hash=sha256:e57544d415dfd7da89a9564e1e3a9e515042df76e12130641ca6f3f2f03b699a + # via mlflow +fonttools==4.63.0 \ + --hash=sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69 \ + --hash=sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c \ + --hash=sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac \ + --hash=sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096 \ + --hash=sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d \ + --hash=sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68 \ + --hash=sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616 \ + --hash=sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78 \ + --hash=sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f \ + --hash=sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b \ + --hash=sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b \ + --hash=sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02 \ + --hash=sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d \ + --hash=sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f \ + --hash=sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8 \ + --hash=sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272 \ + --hash=sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49 \ + --hash=sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419 \ + --hash=sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001 \ + --hash=sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03 \ + --hash=sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196 \ + --hash=sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9 \ + --hash=sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e \ + --hash=sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5 \ + --hash=sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007 \ + --hash=sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380 \ + --hash=sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8 \ + --hash=sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27 \ + --hash=sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40 \ + --hash=sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e \ + --hash=sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0 \ + --hash=sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263 \ + --hash=sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb \ + --hash=sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94 \ + --hash=sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b \ + --hash=sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6 \ + --hash=sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579 \ + --hash=sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4 \ + --hash=sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59 \ + --hash=sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0 \ + --hash=sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e \ + --hash=sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be \ + --hash=sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd \ + --hash=sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18 \ + --hash=sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22 \ + --hash=sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0 \ + --hash=sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b \ + --hash=sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b \ + --hash=sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af \ + --hash=sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745 + # via matplotlib fqdn==1.5.1 \ --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 @@ -1350,9 +1558,9 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec[http]==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec[http]==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask @@ -1364,9 +1572,17 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +gitdb==4.0.12 \ + --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ + --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + # via gitpython +gitpython==3.1.50 \ + --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \ + --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 + # via mlflow-skinny +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1377,10 +1593,11 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-storage # opencensus # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via + # databricks-sdk # google-api-core # google-auth-oauthlib # google-cloud-bigquery @@ -1391,37 +1608,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -1465,88 +1682,100 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status +graphene==3.4.3 \ + --hash=sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa \ + --hash=sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71 + # via mlflow +graphql-core==3.2.11 \ + --hash=sha256:0b3e35ff41e9adba53021ab0cef475eb18f57c7f53f0f2ca55567fbf3c537ea0 \ + --hash=sha256:e7e156d10beb127cab5c89ff0da71416fc73d27c484a4757d3b2d35633774802 + # via + # graphene + # graphql-relay +graphql-relay==3.2.0 \ + --hash=sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c \ + --hash=sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5 + # via graphene great-expectations==0.18.8 \ --hash=sha256:ab41cfa3de829a4f77bdcd4a23244684cbb67fdacc734d38910164cd02ec95b6 \ --hash=sha256:c1205bede593f679e22e0b3826d6ae1623c439cafd553f9f0bc2b0fd441f6ed9 # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1558,77 +1787,81 @@ grpcio==1.62.3 \ # pymilvus # qdrant-client # ray -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -grpcio-testing==1.62.3 \ - --hash=sha256:06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb \ - --hash=sha256:f63577f28aaa95ea525124a0fd63c3429d71f769f4179b13f5e6cbc54979bfab +grpcio-testing==1.81.0 \ + --hash=sha256:32370bdffc0cd09abade928fd880f919bf070afe5d012a2de1412427b2dc1921 \ + --hash=sha256:f754ea3efd110127920513f0177f31b5c9bcbdc7e4af9ac568d8b3a5684df3c6 # via feast (pyproject.toml) -grpcio-tools==1.62.3 \ - --hash=sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133 \ - --hash=sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e \ - --hash=sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e \ - --hash=sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7 \ - --hash=sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf \ - --hash=sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa \ - --hash=sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5 \ - --hash=sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c \ - --hash=sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373 \ - --hash=sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184 \ - --hash=sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1 \ - --hash=sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950 \ - --hash=sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61 \ - --hash=sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0 \ - --hash=sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26 \ - --hash=sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5 \ - --hash=sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1 \ - --hash=sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23 \ - --hash=sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d \ - --hash=sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833 \ - --hash=sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492 \ - --hash=sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43 \ - --hash=sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7 \ - --hash=sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3 \ - --hash=sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc \ - --hash=sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed \ - --hash=sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a \ - --hash=sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557 \ - --hash=sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193 \ - --hash=sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325 \ - --hash=sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b \ - --hash=sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf \ - --hash=sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d \ - --hash=sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10 \ - --hash=sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9 \ - --hash=sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc \ - --hash=sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5 \ - --hash=sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5 \ - --hash=sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f \ - --hash=sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc \ - --hash=sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f \ - --hash=sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6 \ - --hash=sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29 \ - --hash=sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434 \ - --hash=sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14 \ - --hash=sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667 \ - --hash=sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57 \ - --hash=sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d +grpcio-tools==1.81.0 \ + --hash=sha256:0034997767960644f0f4a2aecf35df5fc426d43fa5639dd1b8317da835bab2a4 \ + --hash=sha256:012d580d98db189e4bd231a6529b162bc27a5f52c4854e2d21a4016edc47c760 \ + --hash=sha256:019f05a17b5495d561603f75a74a4a76ad22456a95dc7623c7be4e4b44391b88 \ + --hash=sha256:0733d773eca8cb461f4f2a1b79c64c123db9661be41b08184b81497b2b991ccb \ + --hash=sha256:1e21049aeedd9d62e5e58146e5d00f3b75674d8d8d3cc69709ab950082be8421 \ + --hash=sha256:1ecb833118bfa2c3051e534692f2b43f7c6db14e1eac9b1e7f6e66b6b6dc5074 \ + --hash=sha256:23831f5c66038c5793cb5d2651120bc24a33705e1ce2887a88f54272b73b240f \ + --hash=sha256:244619491a12d1f8d4119bb5930272827084a1e7caa8f9d5a0d4ca6595bb1dea \ + --hash=sha256:283bb3465331a4034b14dce35425c47b0cfbd287b09a6e9d15c9f26fbb17e799 \ + --hash=sha256:2a369a9e27fcb6279387744778d67a64551de82db0e9cf7e1e9451c22f719e07 \ + --hash=sha256:33c579bf24040dbdce751e05b5bcedc13dafffa8f2dfa07193bc05960dc95b49 \ + --hash=sha256:3401d6d4668c064c9ed344825fe97ff076cd8ba719a24e3d3c7169b604cbf00f \ + --hash=sha256:374fe0435447f283e3c69f719ef1bc66f2e187a239ce25444b2de45cb3a6a744 \ + --hash=sha256:3f1ac691debbdbf00e7635ecacf28647f48f67fb4b14120a4541c8bb0f8333ae \ + --hash=sha256:404ca893d54f26fddb868bbd4a54b203fbf914264d26c52e2f2aff35851a9f72 \ + --hash=sha256:40b7a17629e5c944c8ba98a438f051b9affaf30794e6e096578ba0030725f90c \ + --hash=sha256:42e1eaa98199bd4f900f8af091e27aef804dd53b59c92adafcc9faabc0a92240 \ + --hash=sha256:475286558410e4d0394fc8129559080c22835ece3c23cac194b46c5ad7d0fad1 \ + --hash=sha256:4a8d9fdf42537cd1924f7e95013771aa73c89501ccf112b7517c22ca825be9f5 \ + --hash=sha256:52687858c044a6a4dd3fc4049b012b131254a3061360d6de2f97c3e38a7aedd9 \ + --hash=sha256:564624654f5a0377adc69f226f93ec5ff52715030c2f846af6c54ccc4ca2d225 \ + --hash=sha256:5783b6758244f6eaceb41a0e651828824b0d0c92724ddf4b68879ced9bfd9b50 \ + --hash=sha256:58e65dd13f7ffc25f5a9cd9890fddfd39b3c51e5c3c1acd987813b1dc1173704 \ + --hash=sha256:5a7c89432a3b200be306e76307b866716663b4c71d7816bdf382af81e00abd51 \ + --hash=sha256:5c5f44305786c1295320fed477f5673be4ca5f6ed1b31f8696f0791d4b12906d \ + --hash=sha256:61d9ad6b5c0f3857663701bdc2cbb3da7f7d835ce9a8d597ffca443124a96894 \ + --hash=sha256:677207d88b659048f63697c237bf650b123a7a1de36158db57176f84c5bca84a \ + --hash=sha256:69f8355b723db7b5e26a3bff76f9deb3a407d22fe289bca486ccf95d6133cad0 \ + --hash=sha256:760775f79bbefa321cd327fe1019a9d6ad0d93acb1ede7b7905c712679542fd7 \ + --hash=sha256:78c2514bf172b20631685840fea0c5d1bec5518b649d0a498f6dd8f91dfce56a \ + --hash=sha256:7af4faf34376c57f4f3c42aa05f065d3b10e774b8a8d8b27d659d5cc351e5c75 \ + --hash=sha256:98b57a592a75553f4dd38db3993b037953245991b8df9f06927a8978962dcd82 \ + --hash=sha256:a741007631248dd903f880b575a63c0662433ed4b966262ab0f437ea860c9b7e \ + --hash=sha256:a87ea8056beea56b24353d27b7f0ab814daabb372aa517d2e179470e66fd8f6b \ + --hash=sha256:b2b26111795d0e7a72fa483d377a75b57203edaac8bbbac1e9b8f174e7b01ff3 \ + --hash=sha256:bac1c6ddc5eb3762257e773829b4e00ea7d0592f02498f27e5bdb75cd3182d69 \ + --hash=sha256:bf19fdc8b6258fbf36ea65f5672206483ef4639a16d33e3367d77e4523b4089b \ + --hash=sha256:bf2ffd98c754d54a5affddfe3a18d4822b972c5c37ca6a33a456c94e6f3dd82b \ + --hash=sha256:d56060281599d87e66a0dc6840b68730d81c215dbb1b5c50882f819bc9b6aba5 \ + --hash=sha256:d744ea354c9ca33ca17522436825e2842df9b731bcc924a73f4a7d205ed53006 \ + --hash=sha256:dce33d09851bc15dead814bd9d21023bffdf0f838ecf65995a2456e5692831fd \ + --hash=sha256:e5d241c694a226bada06dae9accc47c5c25e586f49464823498e84cff63eedea \ + --hash=sha256:e9945945edc14022abab07caec0ebc16bf51219e586b4f008d09334cc479655c \ + --hash=sha256:f02d796474e58bba879965d228874c2c34164b6a5d96c0faf6bf896a6c3d8a0b \ + --hash=sha256:f1f407697873acbf1d961c6fb9223114a3e679938469d4186623b8b872dbdae0 \ + --hash=sha256:f35da7b3b9537ecce9a5cfd967b1316a815378d5a3729e9ea556b22a14f6e315 \ + --hash=sha256:f37ce0440e5dc563662da89d7d1edd20654e6fb615ada5c8027f15f881bd40d0 \ + --hash=sha256:fa529a1f7a946cdb6881141a07d8fc8fb074af2fd17323e5f3530c8718101680 \ + --hash=sha256:fbe12f98aeddfeaa74d3dbe41dc451f008edf3ab1b82eb62f7a61011003d4833 \ + --hash=sha256:ffa74b84d201bea407f22e00ac0367f12df48a0073b0ffd9f3be9d8126a55245 \ + --hash=sha256:ffb1e507f9849ee013473f732b1ca5d732457f9b1d0d298efe8a77c33bb65d3a # via feast (pyproject.toml) -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) + # mlflow # uvicorn-worker h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -1648,128 +1881,146 @@ hazelcast-python-client==5.6.0 \ --hash=sha256:834b87076a47c781ef80bdcb522b86abc75ff28992dfe384e47f669f06cabb18 \ --hash=sha256:e2cec409068990ca9b4381fe97160cc2375412334782bef45ab4c8fe4d10536c # via feast (pyproject.toml) -hf-xet==1.3.2 \ - --hash=sha256:06b724a361f670ae557836e57801b82c75b534812e351a87a2c739f77d1e0635 \ - --hash=sha256:06cdbde243c85f39a63b28e9034321399c507bcd5e7befdd17ed2ccc06dfe14e \ - --hash=sha256:1c88fbd90ad0d27c46b77a445f0a436ebaa94e14965c581123b68b1c52f5fd30 \ - --hash=sha256:211f30098512d95e85ad03ae63bd7dd2c4df476558a5095d09f9e38e78cbf674 \ - --hash=sha256:305f5489d7241a47e0458ef49334be02411d1d0f480846363c1c8084ed9916f7 \ - --hash=sha256:3155a02e083aa21fd733a7485c7c36025e49d5975c8d6bda0453d224dd0b0ac4 \ - --hash=sha256:31612ba0629046e425ba50375685a2586e11fb9144270ebabd75878c3eaf6378 \ - --hash=sha256:335a8f36c55fd35a92d0062f4e9201b4015057e62747b7e7001ffb203c0ee1d2 \ - --hash=sha256:35b855024ca37f2dd113ac1c08993e997fbe167b9d61f9ef66d3d4f84015e508 \ - --hash=sha256:433c77c9f4e132b562f37d66c9b22c05b5479f243a1f06a120c1c06ce8b1502a \ - --hash=sha256:4a6817c41de7c48ed9270da0b02849347e089c5ece9a0e72ae4f4b3a57617f82 \ - --hash=sha256:4bc995d6c41992831f762096020dc14a65fdf3963f86ffed580b596d04de32e3 \ - --hash=sha256:7c2a054a97c44e136b1f7f5a78f12b3efffdf2eed3abc6746fc5ea4b39511633 \ - --hash=sha256:83d8ec273136171431833a6957e8f3af496bee227a0fe47c7b8b39c106d1749a \ - --hash=sha256:91b1dc03c31cbf733d35dc03df7c5353686233d86af045e716f1e0ea4a2673cf \ - --hash=sha256:9298b47cce6037b7045ae41482e703c471ce36b52e73e49f71226d2e8e5685a1 \ - --hash=sha256:959083c89dee30f7d6f890b36cdadda823386c4de63b1a30384a75bfd2ae995d \ - --hash=sha256:a85d3d43743174393afe27835bde0cd146e652b5fcfdbcd624602daef2ef3259 \ - --hash=sha256:c1980abfb68ecf6c1c7983379ed7b1e2b49a1aaf1a5aca9acc7d48e5e2e0a961 \ - --hash=sha256:c1ae4d3a716afc774e66922f3cac8206bfa707db13f6a7e62dfff74bfc95c9a8 \ - --hash=sha256:c34e2c7aefad15792d57067c1c89b2b02c1bbaeabd7f8456ae3d07b4bbaf4094 \ - --hash=sha256:cfa760888633b08c01b398d212ce7e8c0d7adac6c86e4b20dfb2397d8acd78ee \ - --hash=sha256:d6dbdf231efac0b9b39adcf12a07f0c030498f9212a18e8c50224d0e84ab803d \ - --hash=sha256:e130ee08984783d12717444e538587fa2119385e5bd8fc2bb9f930419b73a7af \ - --hash=sha256:f93b7595f1d8fefddfede775c18b5c9256757824f7f6832930b49858483cd56f +hf-xet==1.5.0 \ + --hash=sha256:1e60df5a42e9bed8628b6416af2cba4cba57ae9f02de226a06b020d98e1aab18 \ + --hash=sha256:2806c7c17b4d23f8d88f7c4814f838c3b6150773fe339c20af23e1cfaf2797e4 \ + --hash=sha256:2baea1b0b989e5c152fe81425f7745ddc8901280ba3d97c98d8cdece7b706c60 \ + --hash=sha256:3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949 \ + --hash=sha256:4b35549ce62601b84da4ff9b24d970032ace3d4430f52d91bcbb26c901d6c690 \ + --hash=sha256:526345b3ed45f374f6317349df489167606736c876241ba984105afe7fd4839d \ + --hash=sha256:5906bf7718d3636dc13402914736abe723492cb730f744834f5f5b67d3a12702 \ + --hash=sha256:5f3dc2248fc01cc0a00cd392ab497f1ca373fcbc7e3f2da1f452480b384e839e \ + --hash=sha256:73a0dae8c71de3b0633a45c73f4a4a5ed09e94b43441d82981a781d4f12baa42 \ + --hash=sha256:786d28e2eb8315d5035544b9d137b4a842d600c434bb91bf7d0d953cce906ad4 \ + --hash=sha256:7d70fe2ce97b9db73b9c9b9c81fe3693640aec83416a966c446afea54acfae3c \ + --hash=sha256:872d5601e6deea30d15865ede55d29eac6daf5a534ab417b99b6ef6b076dd96c \ + --hash=sha256:8dbcbab554c9ef158ef2c991545c3e970ddd8cc7acdcd0a78c5a41095dab4ded \ + --hash=sha256:9929561f5abf4581c8ea79587881dfef6b8abb2a0d8a51915936fc2a614f4e73 \ + --hash=sha256:9a0ee58cd18d5ea799f7ed11290bbccbe56bdd8b1d97ca74b9cc49a3945d7a3b \ + --hash=sha256:a60290ec57e9b71767fba7c3645ddafdd0759974b540441510c629c6db6db24a \ + --hash=sha256:b285cea1b5bab46b758772716ba8d6854a1a0310fed1c249d678a8b38601e5a0 \ + --hash=sha256:b6c9df403040248c76d808d3e047d64db2d923bae593eb244c41e425cf6cd7be \ + --hash=sha256:c799d49f1a5544a0ef7591c0ee75e0d6b93d6f56dc7a4979f59f7518d2872216 \ + --hash=sha256:cf7b2dc6f31a4ea754bb50f74cde482dcf5d366d184076d8530b9872787f3761 \ + --hash=sha256:dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56 \ + --hash=sha256:e0fb0a34d9f406eed88233e829a67ec016bec5af19e480eac65a233ea289a948 \ + --hash=sha256:e5de0f6deada0dada870bb376a11bcd1f08abf3a968a6d118f33e72d1b1eb480 \ + --hash=sha256:f7b7bbae318e583a86fb21e5a4a175d6721d628a2874f4bd022d0e660c32a682 \ + --hash=sha256:fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a # via huggingface-hub -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1779,50 +2030,57 @@ httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx[http2]==0.27.2 \ --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ @@ -1840,6 +2098,10 @@ httpx-sse==0.4.3 \ --hash=sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc \ --hash=sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d # via mcp +huey==3.0.1 \ + --hash=sha256:5de8ff852021da670efe8d4d78db8719c0255ebbde0772766a0114f997ea61f6 \ + --hash=sha256:83ca54fa77c4ee27349393212fc13088142244f491be903f620a9e46e8fca4ce + # via mlflow huggingface-hub==0.36.2 \ --hash=sha256:1934304d2fb224f8afa3b87007d58501acfda9215b334eed53072dd5e815ff7a \ --hash=sha256:48f0c8eac16145dfce371e9d2d7772854a4f591bcb56c9cf548accf531d54270 @@ -1848,6 +2110,7 @@ huggingface-hub==0.36.2 \ # datasets # docling # docling-ibm-models + # sentence-transformers # timm # tokenizers # transformers @@ -1859,13 +2122,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.17 \ - --hash=sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0 \ - --hash=sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1881,31 +2144,31 @@ imagesize==2.0.0 \ --hash=sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 \ --hash=sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3 # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via # dask - # opentelemetry-api -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec + # mlflow-skinny +importlib-resources==7.1.0 \ + --hash=sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708 \ + --hash=sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1 # via happybase iniconfig==2.3.0 \ --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # via pytest -invoke==2.2.1 \ - --hash=sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 \ - --hash=sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707 +invoke==3.0.3 \ + --hash=sha256:437b6a622223824380bfb4e64f612711a6b648c795f565efc8625af66fb57f0c \ + --hash=sha256:f11327165e5cbb89b2ad1d88d3292b5113332c43b8553b494da435d6ec6f5053 # via paramiko ipykernel==7.2.0 \ --hash=sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e \ --hash=sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661 # via jupyterlab -ipython==9.10.0 \ - --hash=sha256:c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d \ - --hash=sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77 +ipython==9.10.1 \ + --hash=sha256:82d18ae9fb9164ded080c71ef92a182ee35ee7db2395f67616034bebb020a232 \ + --hash=sha256:e170e9b2a44312484415bdb750492699bf329233b03f2557a9692cce6466ada4 # via # great-expectations # ipykernel @@ -1928,9 +2191,13 @@ isoduration==20.11.0 \ --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 # via jsonschema -jedi==0.19.2 \ - --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ - --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 +itsdangerous==2.2.0 \ + --hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \ + --hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173 + # via flask +jedi==0.20.0 \ + --hash=sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67 \ + --hash=sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011 # via ipython jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1938,6 +2205,7 @@ jinja2==3.1.6 \ # via # feast (pyproject.toml) # altair + # flask # great-expectations # jupyter-server # jupyterlab @@ -1957,9 +2225,9 @@ joblib==1.5.3 \ --hash=sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 \ --hash=sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3 # via scikit-learn -json5==0.13.0 \ - --hash=sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc \ - --hash=sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf +json5==0.14.0 \ + --hash=sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a \ + --hash=sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb # via jupyterlab-server jsonlines==4.0.0 \ --hash=sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74 \ @@ -1969,9 +2237,9 @@ jsonpatch==1.33 \ --hash=sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade \ --hash=sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c # via great-expectations -jsonpointer==3.0.0 \ - --hash=sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 \ - --hash=sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef +jsonpointer==3.1.1 \ + --hash=sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900 \ + --hash=sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca # via # jsonpatch # jsonschema @@ -1996,9 +2264,9 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -jupyter-client==8.8.0 \ - --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ - --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a +jupyter-client==8.9.0 \ + --hash=sha256:23c0c182e1901ffdab96b5a02cb7bc6f0b04524fd7fc43688a14c4ff2308fb77 \ + --hash=sha256:a0efc16adcec2bb6669d2cf91e3ba5337b338bd1ecd0d9c70940752fcb1144b2 # via # ipykernel # jupyter-server @@ -2014,17 +2282,17 @@ jupyter-core==5.9.1 \ # nbclient # nbconvert # nbformat -jupyter-events==0.12.0 \ - --hash=sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb \ - --hash=sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b +jupyter-events==0.12.1 \ + --hash=sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf \ + --hash=sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3 # via jupyter-server -jupyter-lsp==2.3.0 \ - --hash=sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245 \ - --hash=sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f +jupyter-lsp==2.3.1 \ + --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ + --hash=sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6 # via jupyterlab -jupyter-server==2.17.0 \ - --hash=sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5 \ - --hash=sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f +jupyter-server==2.19.0 \ + --hash=sha256:1731236bc32b680223e1ceb9d68209a845203475012ef68773a81434b46a31a7 \ + --hash=sha256:cb76591b76d7093584c2ad2ae72ac3d58614a4b597507a1bb04e1f9f683cf9ea # via # jupyter-lsp # jupyterlab @@ -2035,9 +2303,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.5 \ - --hash=sha256:a35694a40a8e7f2e82f387472af24e61b22adcce87b5a8ab97a5d9c486202a6d \ - --hash=sha256:eac620698c59eb810e1729909be418d9373d18137cac66637141abba613b3fda +jupyterlab==4.5.8 \ + --hash=sha256:7d514c856d0d607601ec7692374da4f26e2aaf3b6e7cd363136b422a50588d6c \ + --hash=sha256:af54d7242cc689a1e6c3ad213cc9b6d9781787d9ec67c52ec9a8f4707088cadd # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -2053,23 +2321,147 @@ jupyterlab-widgets==3.0.16 \ --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 # via ipywidgets -jwcrypto==1.5.6 \ - --hash=sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 \ - --hash=sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039 +jwcrypto==1.5.7 \ + --hash=sha256:70204d7cca406eda8c82352e3c41ba2d946610dafd19e54403f0a1f4f18633c6 \ + --hash=sha256:729463fefe28b6de5cf1ebfda3e94f1a1b41d2799148ef98a01cb9678ebe2bb0 # via python-keycloak -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kiwisolver==1.5.0 \ + --hash=sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9 \ + --hash=sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679 \ + --hash=sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0 \ + --hash=sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8 \ + --hash=sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 \ + --hash=sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96 \ + --hash=sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e \ + --hash=sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac \ + --hash=sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f \ + --hash=sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a \ + --hash=sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15 \ + --hash=sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7 \ + --hash=sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368 \ + --hash=sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02 \ + --hash=sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9 \ + --hash=sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681 \ + --hash=sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57 \ + --hash=sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 \ + --hash=sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4 \ + --hash=sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920 \ + --hash=sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374 \ + --hash=sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 \ + --hash=sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa \ + --hash=sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23 \ + --hash=sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859 \ + --hash=sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb \ + --hash=sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d \ + --hash=sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc \ + --hash=sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581 \ + --hash=sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c \ + --hash=sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099 \ + --hash=sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05 \ + --hash=sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9 \ + --hash=sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd \ + --hash=sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc \ + --hash=sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796 \ + --hash=sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303 \ + --hash=sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca \ + --hash=sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314 \ + --hash=sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489 \ + --hash=sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57 \ + --hash=sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1 \ + --hash=sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797 \ + --hash=sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021 \ + --hash=sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db \ + --hash=sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22 \ + --hash=sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028 \ + --hash=sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083 \ + --hash=sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65 \ + --hash=sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588 \ + --hash=sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0 \ + --hash=sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a \ + --hash=sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1 \ + --hash=sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c \ + --hash=sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac \ + --hash=sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476 \ + --hash=sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53 \ + --hash=sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3 \ + --hash=sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4 \ + --hash=sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615 \ + --hash=sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb \ + --hash=sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18 \ + --hash=sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b \ + --hash=sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1 \ + --hash=sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2 \ + --hash=sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c \ + --hash=sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac \ + --hash=sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d \ + --hash=sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf \ + --hash=sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2 \ + --hash=sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f \ + --hash=sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f \ + --hash=sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4 \ + --hash=sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9 \ + --hash=sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e \ + --hash=sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737 \ + --hash=sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b \ + --hash=sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed \ + --hash=sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3 \ + --hash=sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7 \ + --hash=sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08 \ + --hash=sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e \ + --hash=sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902 \ + --hash=sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd \ + --hash=sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6 \ + --hash=sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310 \ + --hash=sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537 \ + --hash=sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554 \ + --hash=sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e \ + --hash=sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87 \ + --hash=sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a \ + --hash=sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c \ + --hash=sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79 \ + --hash=sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e \ + --hash=sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16 \ + --hash=sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1 \ + --hash=sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875 \ + --hash=sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd \ + --hash=sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0 \ + --hash=sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9 \ + --hash=sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646 \ + --hash=sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657 \ + --hash=sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4 \ + --hash=sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232 \ + --hash=sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819 \ + --hash=sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384 \ + --hash=sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309 \ + --hash=sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede \ + --hash=sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2 \ + --hash=sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203 \ + --hash=sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7 \ + --hash=sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df \ + --hash=sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c \ + --hash=sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167 \ + --hash=sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3 \ + --hash=sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09 \ + --hash=sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398 + # via matplotlib +kube-authkit==0.4.0 \ + --hash=sha256:1df61ac392fca96c8f5ae8c3d6e9918f1e1655d212434b3c3da5f92cc23b660d \ + --hash=sha256:3bf5fc6ddc882498040118c907628ea68789f9a947454c241972008be59601a3 + # via codeflare-sdk +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via # feast (pyproject.toml) # codeflare-sdk + # kube-authkit lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.78.1 \ - --hash=sha256:f089b6d75e85b937f99693c93e8c16c0804008672c3dd2a3d25affd36f238100 \ - --hash=sha256:f941db80bf41db33f31df87b304e8b588f8166b813b0257c11c98f7a9d0aac71 +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2281,13 +2673,17 @@ makefun==1.16.0 \ --hash=sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4 \ --hash=sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947 # via great-expectations -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +mako==1.3.12 \ + --hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \ + --hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a + # via alembic +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich -marko==2.2.2 \ - --hash=sha256:6940308e655f63733ca518c47a68ec9510279dbb916c83616e4c4b5829f052e8 \ - --hash=sha256:f064ae8c10416285ad1d96048dc11e98ef04e662d3342ae416f662b70aa7959e +marko==2.2.3 \ + --hash=sha256:8e1d7a0387281e59dfbc52a381b58c570156970e36b2bbe047f8a3a2f368cacc \ + --hash=sha256:e31ec2875383bc62f9093d16babed5a2c2cde601c00d834ea935a2222120ec19 # via docling markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -2380,22 +2776,81 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via + # flask # jinja2 + # mako # nbconvert # werkzeug marshmallow==3.26.2 \ --hash=sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73 \ --hash=sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57 # via great-expectations -matplotlib-inline==0.2.1 \ - --hash=sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76 \ - --hash=sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe +matplotlib==3.10.9 \ + --hash=sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9 \ + --hash=sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42 \ + --hash=sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d \ + --hash=sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b \ + --hash=sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37 \ + --hash=sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b \ + --hash=sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456 \ + --hash=sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc \ + --hash=sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f \ + --hash=sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6 \ + --hash=sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2 \ + --hash=sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4 \ + --hash=sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320 \ + --hash=sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20 \ + --hash=sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf \ + --hash=sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c \ + --hash=sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80 \ + --hash=sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9 \ + --hash=sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716 \ + --hash=sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585 \ + --hash=sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb \ + --hash=sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38 \ + --hash=sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4 \ + --hash=sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2 \ + --hash=sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217 \ + --hash=sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838 \ + --hash=sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4 \ + --hash=sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda \ + --hash=sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb \ + --hash=sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f \ + --hash=sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f \ + --hash=sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f \ + --hash=sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c \ + --hash=sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb \ + --hash=sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b \ + --hash=sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285 \ + --hash=sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294 \ + --hash=sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65 \ + --hash=sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e \ + --hash=sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d \ + --hash=sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f \ + --hash=sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8 \ + --hash=sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39 \ + --hash=sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6 \ + --hash=sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f \ + --hash=sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf \ + --hash=sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2 \ + --hash=sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe \ + --hash=sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99 \ + --hash=sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb \ + --hash=sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8 \ + --hash=sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1 \ + --hash=sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 \ + --hash=sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba \ + --hash=sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358 + # via mlflow +matplotlib-inline==0.2.2 \ + --hash=sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6 \ + --hash=sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79 # via # ipykernel # ipython -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -2406,19 +2861,29 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) minio==7.2.11 \ --hash=sha256:153582ed52ff3b5005ba558e1f25bfe1e9e834f7f0745e594777f28e3e81e1a0 \ --hash=sha256:4db95a21fe1e2022ec975292d8a1f83bd5b18f830d23d42a4518ac7a5281d7c5 # via feast (pyproject.toml) -mistune==3.2.0 \ - --hash=sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a \ - --hash=sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 +mistune==3.2.1 \ + --hash=sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048 \ + --hash=sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28 # via # great-expectations # nbconvert +mlflow==3.13.0 \ + --hash=sha256:7ca9cb2f623f300dabadaf5e985c85af77c5db3d7c36f56769d22c101b132f6c \ + --hash=sha256:a95198d592a8a15fad3db7f56b228acc9422c09f0daa7c6c976a9996ab73c3e2 + # via feast (pyproject.toml) +mlflow-skinny==3.13.0 \ + --hash=sha256:ced3d9a580564fae093d14732df8531fb180574f6483d4c642b6083879eb86fc \ + --hash=sha256:d2273bfa21f776359f7d6ab2267967e3a6732a5fb00996ad433d0e777dfa3b71 + # via mlflow +mlflow-tracing==3.13.0 \ + --hash=sha256:2f8187ce2b1af7419be71d2d8ab5fec53d207d4b8d703cd15e5db64939098d72 \ + --hash=sha256:42c435b0fdcab00f1865cab4a52f7a85a2a08d68a959f36bcf90a1c9fe65db0a + # via mlflow mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -2544,9 +3009,9 @@ mpmath==1.3.0 \ --hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \ --hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c # via sympy -msal==1.35.1 \ - --hash=sha256:70cac18ab80a053bff86219ba64cfe3da1f307c74b009e2da57ef040eb1b5656 \ - --hash=sha256:8f4e82f34b10c19e326ec69f44dc6b30171f2f7098f3720ea8a9f0c11832caa3 +msal==1.37.0 \ + --hash=sha256:1b1672a33ee467c1d70b341bb16cafd51bb3c817147a95b93263794b03971bec \ + --hash=sha256:dd17e95a7c71bce75e8108113438ba7c4a086b3bcad4f57a8c09b7af3d753c2d # via # azure-identity # msal-extensions @@ -2828,13 +3293,17 @@ mypy-protobuf==3.3.0 \ --hash=sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d \ --hash=sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248 # via feast (pyproject.toml) -nbclient==0.10.4 \ - --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ - --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 +narwhals==2.22.1 \ + --hash=sha256:60567d774edf77db53906f89d9fbd164e66e56d66d388e1e6990f17ac33cfb53 \ + --hash=sha256:d62920805a0a43b7ff8b54b0c0d3142d796f8a9301836ada37e573d6a33cbcd9 + # via scikit-learn +nbclient==0.11.0 \ + --hash=sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a \ + --hash=sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895 # via nbconvert -nbconvert==7.17.0 \ - --hash=sha256:1b2696f1b5be12309f6c7d707c24af604b87dfaf6d950794c7b07acab96dda78 \ - --hash=sha256:4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518 +nbconvert==7.17.1 \ + --hash=sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2 \ + --hash=sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8 # via jupyter-server nbformat==5.10.4 \ --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ @@ -2879,9 +3348,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.4 \ - --hash=sha256:860e31782b3d3a25ca0819ff039f5cf77845d1bf30c78ef9528b88b25e0a9850 \ - --hash=sha256:b928b2ba22cb63aa83df2e0e76fe3697950a0c1c4a41b84ebccf1972b1bb5771 +notebook==7.5.7 \ + --hash=sha256:1f95f79d117e47d20b5555b5c85a397d2cfecf136978aaab767cf0314b09165b \ + --hash=sha256:d6d59288a25303b25e1dcb71e9b017ec3a785f7d92f38b9bc288ca1970d5b0a8 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -2889,83 +3358,84 @@ notebook-shim==0.2.4 \ # via # jupyterlab # notebook -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # accelerate # altair + # contourpy # dask # datasets # db-dtypes @@ -2975,6 +3445,8 @@ numpy==2.4.3 \ # great-expectations # ibis-framework # imageio + # matplotlib + # mlflow # opencv-python-headless # pandas # pandas-gbq @@ -2984,7 +3456,9 @@ numpy==2.4.3 \ # scikit-image # scikit-learn # scipy + # sentence-transformers # shapely + # skops # tifffile # torchvision # transformers @@ -3010,8 +3484,8 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.44.1 \ - --hash=sha256:cc121f82cb15dcf5f2f1347bd30d4c83cae1d510809e6ccce111b98298271503 +openlineage-python==1.48.0 \ + --hash=sha256:107f460e5836f5a2d618c3b30f816ee5cd18974c7be899c86cac879a379b54c9 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ @@ -3021,149 +3495,172 @@ openshift-client==1.0.18 \ --hash=sha256:be3979440cfd96788146a3a1650dabe939d4d516eea0b39f87e66d2ab39495b1 \ --hash=sha256:d8a84080307ccd9556f6c62a3707a3e6507baedee36fa425754f67db9ded528b # via codeflare-sdk -opentelemetry-api==1.40.0 \ - --hash=sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f \ - --hash=sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9 +opentelemetry-api==1.42.1 \ + --hash=sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714 \ + --hash=sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716 # via + # mlflow-skinny + # mlflow-tracing # opentelemetry-exporter-prometheus # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-exporter-prometheus==0.61b0 \ - --hash=sha256:3013b41f4370143d48d219a2351473761423e5882fa4c213811eaefacba39cb7 \ - --hash=sha256:7c4919bd8e79abd62b610767e80f42c9c3a06c5183f4dd9141eedeb57aea284b +opentelemetry-exporter-prometheus==0.63b1 \ + --hash=sha256:0efd00aa6b1939345ddcc6de141b83ebffa2b4401a37a68f880e54217602701d \ + --hash=sha256:31902e22c89431058a95b6dcdb644f9309f226aa4872cc755f0a780d2895e97f # via ray -opentelemetry-proto==1.27.0 \ - --hash=sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6 \ - --hash=sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace - # via ray -opentelemetry-sdk==1.40.0 \ - --hash=sha256:18e9f5ec20d859d268c7cb3c5198c8d105d073714db3de50b593b8c1345a48f2 \ - --hash=sha256:787d2154a71f4b3d81f20524a8ce061b7db667d24e46753f32a7bc48f1c1f3f1 +opentelemetry-proto==1.42.1 \ + --hash=sha256:c6a51e6b4f05ae63565f3a113217f3d2bfaec68f78c02d7a6c85f9010d1cfca6 \ + --hash=sha256:dedb74cba2886c59c7789b227a7a670613025a07489040050aedff6e5c0fb43c + # via + # mlflow-skinny + # mlflow-tracing + # ray +opentelemetry-sdk==1.42.1 \ + --hash=sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d \ + --hash=sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7 # via + # mlflow-skinny + # mlflow-tracing # opentelemetry-exporter-prometheus # ray -opentelemetry-semantic-conventions==0.61b0 \ - --hash=sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a \ - --hash=sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2 +opentelemetry-semantic-conventions==0.63b1 \ + --hash=sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9 \ + --hash=sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682 # via opentelemetry-sdk -oracledb==3.4.2 \ - --hash=sha256:00c79448017f367bb7ab6900efe0706658a53768abea2b4519a4c9b2d5743890 \ - --hash=sha256:0e16fe3d057e0c41a23ad2ae95bfa002401690773376d476be608f79ac74bf05 \ - --hash=sha256:0f04a2d62073407672f114d02529921de0677c6883ed7c64d8d1a3c04caa3238 \ - --hash=sha256:1617a1db020346883455af005efbefd51be2c4d797e43b1b38455a19f8526b48 \ - --hash=sha256:19fa80ef84f85ad74077aa626067bbe697e527bd39604b4209f9d86cb2876b89 \ - --hash=sha256:1e4930d7f6584832dcc15b8ca415a7957b0c45f5aa7c4f88702e070e5c53bf93 \ - --hash=sha256:23aa07c1eaca17ae74c6fdc86b218f58484d56452958aead1aa460c0596a76c1 \ - --hash=sha256:31b7ee83c23d0439778303de8a675717f805f7e8edb5556d48c4d8343bcf14f5 \ - --hash=sha256:3df8eee1410d25360599968b1625b000f10c5ae0e47274031a7842a9dc418890 \ - --hash=sha256:404ec1451d0448653ee074213b87d6c5bd65eaa74b50083ddf2c9c3e11c71c71 \ - --hash=sha256:46e0f2278ff1fe83fbc33a3b93c72d429323ec7eed47bc9484e217776cd437e5 \ - --hash=sha256:55397e7eb43bb7017c03a981c736c25724182f5210951181dfe3fab0e5d457fb \ - --hash=sha256:574c8280d49cbbe21dbe03fc28356d9b9a5b9e300ebcde6c6d106e51453a7e65 \ - --hash=sha256:59ad6438f56a25e8e1a4a3dd1b42235a5d09ab9ba417ff2ad14eae6596f3d06f \ - --hash=sha256:5d7befb014174c5ae11c3a08f5ed6668a25ab2335d8e7104dca70d54d54a5b3a \ - --hash=sha256:5ed78d7e7079a778062744ccf42141ce4806818c3f4dd6463e4a7edd561c9f86 \ - --hash=sha256:643c25d301a289a371e37fcedb59e5fa5e54fb321708e5c12821c4b55bdd8a4d \ - --hash=sha256:6d85622664cc88d5a82bbd7beccb62cd53bd272c550a5e15e7d5f8ae6b86f1f1 \ - --hash=sha256:9f434a739405557bd57cb39b62238142bb27855a524a70dc6d397a2a8c576c9d \ - --hash=sha256:a7396664e592881225ba66385ee83ce339d864f39003d6e4ca31a894a7e7c552 \ - --hash=sha256:ac25a0448fc830fb7029ad50cd136cdbfcd06975d53967e269772cc5cb8c203a \ - --hash=sha256:b1095d95d0c8b37e4d0e17cf1928919cb59222b6344362a1cf6a2f3ca205a28a \ - --hash=sha256:b26a10f9c790bd141ffc8af68520803ed4a44a9258bf7d1eea9bfdd36bd6df7f \ - --hash=sha256:b8e4b8a852251cef09038b75f30fce1227010835f4e19cfbd436027acba2697c \ - --hash=sha256:b974caec2c330c22bbe765705a5ac7d98ec3022811dec2042d561a3c65cb991b \ - --hash=sha256:d7ce75c498bff758548ec6e4424ab4271aa257e5887cc436a54bc947fd46199a \ - --hash=sha256:d8d75e4f879b908be66cce05ba6c05791a5dbb4a15e39abc01aa25c8a2492bd9 \ - --hash=sha256:e068ef844a327877bfefbef1bc6fb7284c727bb87af80095f08d95bcaf7b8bb2 \ - --hash=sha256:f8ea989965a4f636a309444bd696ab877bba373d5d67bf744785f9bd8c560865 \ - --hash=sha256:f93cae08e8ed20f2d5b777a8602a71f9418389c661d2c937e84d94863e7e7011 \ - --hash=sha256:ff3c89cecea62af8ca02aa33cab0f2edc0214c747eac7d3364ed6b2640cb55e4 +oracledb==4.0.1 \ + --hash=sha256:032ca4f558b05f03fa1bef1b04e59ec350ae0b22e6d85c47f4ac62ae98315823 \ + --hash=sha256:03afeda85bec3eca983ebf3ad9910d0f217d99300258366d287e015a041d6c13 \ + --hash=sha256:08e84a6af1b6e5921dba088dd9fc0738927206eafe5ce9763c34195f87556849 \ + --hash=sha256:0d3c6ed987df64b914ece0722692419fe494d07f15bb4d7715adeada4f914c3a \ + --hash=sha256:0ece951553c106a0896c8e1690bcdf69d472761fa65fec9b8152cbce13ab8b81 \ + --hash=sha256:10204432f0eea8707a79c75bdccb84071e43fd19c658cb3b34d1746b12c6e7fe \ + --hash=sha256:20a10f903c8da59e9689a98bd68012f78fa19bed950ad9f19cd8f5b8b97e73a0 \ + --hash=sha256:29ae0ff517a3241060eeee15a321b710c3f83a688cf2da7d5729adbe212e2b00 \ + --hash=sha256:34bbea44423ed8b24093aa859ca7ee9b6e76ea490f9acdc5f6ff01aa1083e343 \ + --hash=sha256:3b5ef1676a27b7e0a7ec55be27fd8f6d28d1601f5e8dfdae78705909f25b7c0a \ + --hash=sha256:416b324cd7715073cf5f3d577330387ffd59741463995c25bdc2d82b3e80b88e \ + --hash=sha256:443b2f03461e873ccd73dff3d8541fcf974c05e13e296a6687ffbb0c4a72c0a1 \ + --hash=sha256:4b42725337f80d433a3bd2928c08667e5b89da9ce05cf9ae3a4189c4fc4805ea \ + --hash=sha256:523b3356cde9d588ba250cefafdfc34869233d65c179f805ea6e4d3d6b209a7f \ + --hash=sha256:5332a4499d61c3cd659ed09bbd0d3c9a4c74a70bd51136d5c3de9127dc6d7434 \ + --hash=sha256:5646c126d4ab506ee2bda261e792f0036231ee929296057e79857ec678d86d4f \ + --hash=sha256:7156ef112a901967b3ee89b6c582bafc5a3082c47ca566de1a79e9ac3b48da32 \ + --hash=sha256:73ba32597fe1da72e0824aaa4b1900ec08a3b77268cb4eb45c733ae7e7043e70 \ + --hash=sha256:7bbe5611f9196f0ec15d4bf838ec728d89586a962a20d65cad898aec020e11c4 \ + --hash=sha256:7db5a43c29a23ed23923a29816c65c7a81fe00f2abfe6bf36d83ad952abd9b89 \ + --hash=sha256:8159c5bd8f25b0ca0ce30f21e7a732a2bdfb4adb81b9c8ea1ca75339d8ec8398 \ + --hash=sha256:828dd4c981b286f0467feab1c035fae8d3888cfdc707706841734821877ae1f3 \ + --hash=sha256:86a06d0afb3bb3a24bace0e72fb9abca2093efe0fa3457c65c13ba4eb5000b0b \ + --hash=sha256:86ac65cbc8d29626b1d9d203f9151566c26a78e55bdfc030c06169ae8017f458 \ + --hash=sha256:873fcca53306e2b3b445a7d657cddc19e415a7aa7e392c473dfd1a3ae3970989 \ + --hash=sha256:8e13ff1e6f28fdb863180d23fa94cb42c619c29d2981e24992431e51b97caa54 \ + --hash=sha256:8fcad6d9628923281bf21e48a391ac2f87ec6950dc63381d8fea470e3128aef0 \ + --hash=sha256:90586b3c7729b9cf3d40df902e81257f01e15e3408d8b6b9dbf91e939b64f72c \ + --hash=sha256:9f521b3f3f14fa9b8e748aeb79b064ae6767fcb0e8ff969a9aba7a852f059658 \ + --hash=sha256:a029dcee759bca56a8c95e952040c3d3f57e5ec05965355293b21930a66967fb \ + --hash=sha256:ae894ca2705929eb0ac228329336fd03388ad6e3b54002be6f5d4400a8feaf52 \ + --hash=sha256:b05bfadbfe462c39cc97258a973972f5bbbc9f8e2e9a4c2e0efcb1ec86b91088 \ + --hash=sha256:b09eec35681d72c9476e6d715b89bb775724a31e7363df6beba7470494ea8040 \ + --hash=sha256:b73820521eccd290506af94e1ffb9a8a5941b4018e3861df9b040652a7cef123 \ + --hash=sha256:c05a01d6ad610a88c2aa1a43b1dc0a8485f5fbd4374d2b36908859d4205de192 \ + --hash=sha256:c24b174aac8163065736072a726a50091791f6d30ac5c44965cf7044e86fbaf8 \ + --hash=sha256:c2d394453f669858bec942ff0da18b6ebade296ece823d582ad2b464ed5c6c90 \ + --hash=sha256:cb7727f93ff962ab826bc3d0bca4b0e5bf45ecb7c525551c70c9e094f0f27027 \ + --hash=sha256:ce3f25552fe58df5c266874f8b13f0a8ab7fcd09ab4b476bc15520a67527ca4b \ + --hash=sha256:ce6319ee01dcbb4d74f0e2a5794c6a566f339958ecac9830c67c7070521620e2 \ + --hash=sha256:cf61e42b9ef723dbdd0b23032b695e872009ed7341003df59d9a97cd960df977 \ + --hash=sha256:d132af7d95474d207632363575c7968b09e2d33dd24af3a36f539254433f4ae8 \ + --hash=sha256:d7cd278d59780e22e0a7451d208460756d779dc62b55bdbd95652f9640fbf8c3 \ + --hash=sha256:dbe8b44fea57385617838f2acfce8cc19f6c95cd9e65e7235e86b5932af1acd9 \ + --hash=sha256:e36581bb10e719d928dad12018c2d42606db2c34f49d6665b06f701f049255f0 \ + --hash=sha256:e3d54b624748cfe42248c4bc62c3f788632a2077058485a9acb3150312b1c396 \ + --hash=sha256:e4926e699a42c526137724960fa4303ecb0b542186b11d3705ac84414a896508 # via ibis-framework -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 # via - # feast (pyproject.toml) + # pymilvus # trino overrides==7.7.0 \ --hash=sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a \ --hash=sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 # via jupyter-server -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # accelerate # build @@ -3184,6 +3681,9 @@ packaging==26.0 \ # jupyterlab-server # lazy-loader # marshmallow + # matplotlib + # mlflow-skinny + # mlflow-tracing # nbconvert # openlineage-python # pandas-gbq @@ -3191,6 +3691,7 @@ packaging==26.0 \ # ray # safetensors # scikit-image + # skops # snowflake-connector-python # sphinx # transformers @@ -3262,6 +3763,7 @@ pandas==2.3.3 \ # google-cloud-bigquery # great-expectations # ibis-framework + # mlflow # pandas-gbq # pymilvus # ray @@ -3274,17 +3776,17 @@ pandocfilters==1.5.1 \ --hash=sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e \ --hash=sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc # via nbconvert -paramiko==4.0.0 \ - --hash=sha256:0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 \ - --hash=sha256:6a25f07b380cc9c9a88d2b920ad37167ac4667f8d9886ccebd8f90f654b5d69f +paramiko==5.0.0 \ + --hash=sha256:36763b5b95c2a0dcfdf1abc48e48156ee425b21efe2f0e787c2dd5a95c0e5e79 \ + --hash=sha256:b7044611c30140d9a75261653210e2002977b71a0497ff3ba0d98d7edbf62f7c # via openshift-client parsimonious==0.11.0 \ --hash=sha256:32e3818abf9f05b3b9f3b6d87d128645e30177e91f614d2277d88a0aea98fae2 \ --hash=sha256:e080377d98957beec053580d38ae54fcdf7c470fb78670ba4bf8b5f9d5cad2a9 # via singlestoredb -parso==0.8.6 \ - --hash=sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd \ - --hash=sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff +parso==0.8.7 \ + --hash=sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c \ + --hash=sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1 # via jedi parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -3417,12 +3919,13 @@ pillow==11.3.0 \ # docling-parse # easyocr # imageio + # matplotlib # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1.2 \ + --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ + --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3454,6 +3957,10 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) +prettytable==3.17.0 \ + --hash=sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0 \ + --hash=sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 + # via skops prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 @@ -3466,154 +3973,153 @@ prompt-toolkit==3.0.52 \ --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 # via ipython -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==4.25.8 \ - --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ - --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ - --hash=sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af \ - --hash=sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0 \ - --hash=sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd \ - --hash=sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0 \ - --hash=sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7 \ - --hash=sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9 \ - --hash=sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f \ - --hash=sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3 \ - --hash=sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24 +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) + # databricks-sdk # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable @@ -3625,6 +4131,8 @@ protobuf==4.25.8 \ # grpcio-status # grpcio-testing # grpcio-tools + # mlflow-skinny + # mlflow-tracing # mypy-protobuf # opentelemetry-proto # proto-plus @@ -3668,80 +4176,70 @@ psutil==5.9.0 \ # feast (pyproject.toml) # accelerate # ipykernel -psycopg[binary, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[binary, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-binary==3.2.5 \ - --hash=sha256:02fb96091e2fb3ea1470b113fef08953baaedbca1d39a3f72d82cb615177846c \ - --hash=sha256:11e3ed8b94c750d54fc3e4502dd930fb0fd041629845b6a7ce089873ac9756b0 \ - --hash=sha256:1494827c43265820d5dcdc6f8086521bc7dd04b9da8831310978a788cdcd2e62 \ - --hash=sha256:21b839f9bfd77ed074f7f71464a43f453400c57d038a0ba0716329a28e335897 \ - --hash=sha256:23a1dc61abb8f7cc702472ab29554167a9421842f976c201ceb3b722c0299769 \ - --hash=sha256:274e852f9e61252bc8e80a0a43d300ba352d40219e856733054023a3bb960eb4 \ - --hash=sha256:28bd5cb2324567e5e70f07fe1d646398d6b0e210e28b49be0e69593590a59980 \ - --hash=sha256:2b053eae21dd3a6828b516a1171e1274d1af5f7c07d2d9a8f597f2e19c732168 \ - --hash=sha256:2cbb8649cfdacbd14e17f5ab78edc52d33350013888518c73e90c5d17d7bea55 \ - --hash=sha256:2cc86657c05e09c701e97f87132cd58e0d55381dd568520081ac1fe7580a9bbb \ - --hash=sha256:2d10ce4c39eb9631381a0c3792727946a4391e843625a7ee9579ac6bb11495a5 \ - --hash=sha256:2d22a15e45f43d36ed35aed4d5261f8ef6ab7d9b84ee075576ca56ae03b9e0aa \ - --hash=sha256:2dbaf32c18c0d11c4480016b89c9c5cadb7b64c55de7f181d222b189bd13a558 \ - --hash=sha256:32b5673736f04c36ccbf8012800fe5bc01b46dac22c5d59e41b043bebaad9d3d \ - --hash=sha256:375149006e21d58ed8aba640e0295d8e636043064c433af94eb58057f9b96877 \ - --hash=sha256:393ab353196d364858b47317d27804ecc58ab56dbde32217bd67f0f2f2980662 \ - --hash=sha256:39e2cd10bf15442d95c3f48376b25dc33360418ea6c3c05884d8bf42407768c0 \ - --hash=sha256:3d2e57a1d06f3968e49e948ba374f21a7d8dcf44f37d582a4aeddeb7c85ce239 \ - --hash=sha256:3eb71cfc35116e4a8e336b7e785f1fe06ca23b4516a48ea91facd577d1a1fdf6 \ - --hash=sha256:3f893c0ed3d5c7b83b76b1f8f7d3ca5a03e38bcd3cab5d65b5c25a0d1064aca4 \ - --hash=sha256:473f6827cf1faf3924eb77146d1e85126a1b5e48a88053b8d8b78dd29e971d78 \ - --hash=sha256:48f97936145cb7de18b95d85670b2d3e2c257277263272be05815b74fb0ef195 \ - --hash=sha256:48fcb12a0a72fdfe4102bdb1252a7366e8d73a2c89fe6ce5923be890de367c2f \ - --hash=sha256:4914dc60f2fddf0884464985e31d775aa865b665471fa156ec2f56fa72a1a097 \ - --hash=sha256:51a96d9fe51f718912b4a0089784f1f32d800217499fd0f0095b888506aba4c5 \ - --hash=sha256:5244bebaa9734a236b7157fb57c065b6c0f2344281916187bd73f951df1899e0 \ - --hash=sha256:5b81342e139ddccfa417832089cd213bd4beacd7a1462ca4019cafe71682d177 \ - --hash=sha256:5d2253189aa4cca0a425e2ca896d1a29760cd3a2b10ab12194e4e827a566505c \ - --hash=sha256:5fd017d7ed71c58f19b0f614e7bfb8f01ec862bacb67ae584f494d090956102e \ - --hash=sha256:605f70e267222d567fc40de7813ee3fb29f8145a1a20aa6fd3dc62baba9312f1 \ - --hash=sha256:60d0f36a42a822e43c4c7472df8a0c980c0f32e5d74ed871333c423a4e942f11 \ - --hash=sha256:62965045cc0fe3dc5dd55d39779620b225ef75962825c7b1b533033cb91810bd \ - --hash=sha256:65162a9cc3f86d70b1d895dbda506e3c079f80d082eb41c54d3f6d33a00b3965 \ - --hash=sha256:659f2c675d478b1bc01b95a8d3ded74fa939b370e71ffbecd496f617b215eb05 \ - --hash=sha256:6b581da13126b8715c0c0585cd37ce934c9864d44b2a4019f5487c0b943275e6 \ - --hash=sha256:71d82dbc7c6c7f5746468e7992e5483aa45b12250d78d220a2431ab88795825c \ - --hash=sha256:7376b13504396da9678b646f5338462347da01286b2a688a0d8493ec764683a2 \ - --hash=sha256:7623659d44a6aa032be4a066c658ba45009d768c2481526fbef7c609702af116 \ - --hash=sha256:7a94020821723a6a210206ddb458001f3ed27e1e6a0555b9422bebf7ead8ff37 \ - --hash=sha256:7d5f1bfc848a94e0d63fe693adee4f88bd9e5c415ecb4c9c17d2d44eba6795a6 \ - --hash=sha256:7efe6c732fd2d7e22d72dc4f7cf9b644020adacfff61b0a8a151343da8e661c0 \ - --hash=sha256:8a602d9fdb567cca090ca19ac3ebf10219065be2a4f8cf9eb8356cffb5a7ab1d \ - --hash=sha256:8cd9ebf335262e864d740f9dad3f672f61162cc0d4825a5eb5cf50df334a688f \ - --hash=sha256:8e6f2bef5aed021fbdf46323d3cd8847bf960efb56394698644a8ee2306f8892 \ - --hash=sha256:93221d5a759bd39b1face1d7d887d2b9ede3e55aefaff8eacf1b663ccdcd204b \ - --hash=sha256:9639289b72f9339721982e156527c296693236d6192ccc31412ab36fccd1683c \ - --hash=sha256:98efaedf2bf79f4d563ca039a57a025b72847bd80568f54709cc39fc1404772c \ - --hash=sha256:9abe093a303e25ac58774a11241150e2fe2947358d1ca12521ad03c90b131060 \ - --hash=sha256:a4321ee8180982d70458d3e8378e31448901bf0ee40fe0d410a87413578f4098 \ - --hash=sha256:a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed \ - --hash=sha256:a91b0e096fdfeb52d86bb8f5ee25dc22483d6960af9b968e6b381a8ec5bfbf82 \ - --hash=sha256:b5e0acbc991472188c9df40eb56d8a97ad3ad00d4de560b8b74bdc2d94041a8f \ - --hash=sha256:b6b5a4542aca4095ab35e184517cb0d18895ba4b6661c92865b431fa7b7974d8 \ - --hash=sha256:ba4a610882171bdaae0779f14e0ff45f3ee271fd2dbf16cdadfc81bd67323232 \ - --hash=sha256:bc5bd9bf5f5894923b78a41c5becd52d6bced1e1e43744855bd85cb341376ca6 \ - --hash=sha256:c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 \ - --hash=sha256:c3c5fa3d4fa0a651cefab391b783f89bc5e331afa0a4e93c9b16141993fa05c8 \ - --hash=sha256:ca5e36a3e7480a5c09aed99ecdb8e6554b21485c3b064297fe77f7b1b5806106 \ - --hash=sha256:d4e0c1b1aa5283f6d9a384ffc7a8400d25386bb98fdb9bddae446e4ef4da7366 \ - --hash=sha256:dc8bc40d82d1ee8dec136e10707c7f3147a6322fd8014e174a0f3446fb793649 \ - --hash=sha256:de576c49d7deab2b78088feb24e1f6ae3e16a0020e8496cdd3b8543f5e350e87 \ - --hash=sha256:e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 \ - --hash=sha256:eb8293d66c6a4ddc72fceb7ad0e111cb196cc394954ae0f9b63c251d97f1b00e \ - --hash=sha256:ee6d8f489a9b116ea8dc797664a50671585a4ca20573359f067858e1231cc217 \ - --hash=sha256:efb878d08dd49d7d9d18512e791b418a1171d08f935475eec98305f0886b7c14 +psycopg-binary==3.3.4 \ + --hash=sha256:018fbed325936da502feb546642c982dcc4b9ffdea32dfef78dbf3b7f7ad4070 \ + --hash=sha256:0579252a1202cd73e4da137a1426e2dae993ae44e757605344282af3a082848c \ + --hash=sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc \ + --hash=sha256:13a7f380824c35896dcac7fe0f61440f7ca49d6dc73f3c13a9a4471e6a3b302e \ + --hash=sha256:17a21953a9e5ff3a16dab692625a3676e2f101db5e40072f39dbee2250194d68 \ + --hash=sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae \ + --hash=sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829 \ + --hash=sha256:22cdbf5f91ef7bb91fe0c5757e1962d3127a8010256eefd9c61fcaf441802097 \ + --hash=sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c \ + --hash=sha256:276904e3452d6a23d474ef9a21eee19f20eed3d53ddd2576af033827e0ba0992 \ + --hash=sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97 \ + --hash=sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6 \ + --hash=sha256:32a6fbf8481e3a370d0d72b860d35948a693cb01281da217f7b2f307636e591a \ + --hash=sha256:41f2ec0fea529832982bcb6c9415de3c86264ebe562b77a467c0fbcd7efbba8d \ + --hash=sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228 \ + --hash=sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e \ + --hash=sha256:494ca54901be8cf9eb7e02c25b731f2317c378efa44f43e8f9bd0e1184ae7be4 \ + --hash=sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41 \ + --hash=sha256:574ea21a9651958f1535c5a1c649c7409e9168bcbffa29a3f2f961f58b322949 \ + --hash=sha256:580ae30a5f95ccd90008ec697d3ed6a4a2047a516407ad904283fa42086936e9 \ + --hash=sha256:5ab28a2a7649df3b72e6b674b4c190e448e8e77cf496a65bd846472048de2089 \ + --hash=sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf \ + --hash=sha256:612a627d733f695b1de1f9b4bd511c15f999a5d8b915d444bbd7dd71cf3370da \ + --hash=sha256:6402a9d8146cf4b3974ded3fd28a971e83dc6a0333eb7822524a3aa20b546578 \ + --hash=sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014 \ + --hash=sha256:71e55ccbdfae79a2ed9c6369c3008a3025817ff9d7e27b32a2d84e2a4267e66e \ + --hash=sha256:7465bfe6087d2d5b42d4c53b9b11ca9f218e477317a4a162a10e3c19e984ba8e \ + --hash=sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31 \ + --hash=sha256:773d573e11f437ce0bdb95b7c18dc58390494f96d43f8b45b9760436114f7652 \ + --hash=sha256:77df19583501ea288eaf15ac0fe7ad01e6d8091a91d5c41df5c718f307d8e31b \ + --hash=sha256:7f7668f30b9dd5163197e5cbf4e0efd54e00f0a859cc566ce56cfc31f4054839 \ + --hash=sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277 \ + --hash=sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7 \ + --hash=sha256:ab8cca8ef8fb1ccf5b048ae5bd78ba55b9e4b5d472e3ce5ca39ff4d2a9c249e4 \ + --hash=sha256:ad3bc94054876155549fdaedf4a46d1ec69d39a5bcee377148afe498e84c4b8e \ + --hash=sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70 \ + --hash=sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf \ + --hash=sha256:b7bfff1ca23732b488cbca3076fc11bc98d520ee122514fdb17a8e20d3338f5a \ + --hash=sha256:bdef84570ebbce1d42b4e7ea952d21c414c5f118ad02fee00c5625f35e134429 \ + --hash=sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8 \ + --hash=sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3 \ + --hash=sha256:cf7f73a4a792bc5db58a4b385d8a1467e8d468f7548702fb0ed1e9b7501b1c13 \ + --hash=sha256:cffc3408d77a27973f33e5d909b624cce683db5fc25964b02fe0aae7886c1007 \ + --hash=sha256:d7b4d40c153fa352ab3cca530f3a0baedf7621b2ebcbd7f084009522c21788fc \ + --hash=sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38 \ + --hash=sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9 \ + --hash=sha256:e2631da29253a98bd496e6c4813b24e09a4fe3fb2a9e88513305d6f8747cce95 \ + --hash=sha256:e7510c37550f91a187e3660a8cc50d4b760f8c3b8b2f89ebc5698cd2c7f2c85d \ + --hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \ + --hash=sha256:eb4eed2079c01a4850bf467deacfab56d356d4225040170af03dc9958321242d \ + --hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \ + --hash=sha256:f80e3f2b5331dbbf0901bcb658056c03eeb2c1ef31d774afb0d61598b242e744 \ + --hash=sha256:f9b1c2533af01cd7648378599f82b0b8ae32f293296e6eec5753a625bc97ef28 \ + --hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \ + --hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg ptyprocess==0.7.0 \ --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ @@ -3761,71 +4259,71 @@ py-cpuinfo==9.0.0 \ --hash=sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690 \ --hash=sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5 # via pytest-benchmark -py-spy==0.4.1 \ - --hash=sha256:1fb8bf71ab8df95a95cc387deed6552934c50feef2cf6456bc06692a5508fd0c \ - --hash=sha256:4972c21890b6814017e39ac233c22572c4a61fd874524ebc5ccab0f2237aee0a \ - --hash=sha256:532d3525538254d1859b49de1fbe9744df6b8865657c9f0e444bf36ce3f19226 \ - --hash=sha256:6a80ec05eb8a6883863a367c6a4d4f2d57de68466f7956b6367d4edd5c61bb29 \ - --hash=sha256:809094208c6256c8f4ccadd31e9a513fe2429253f48e20066879239ba12cd8cc \ - --hash=sha256:d92e522bd40e9bf7d87c204033ce5bb5c828fca45fa28d970f58d71128069fdc \ - --hash=sha256:e53aa53daa2e47c2eef97dd2455b47bb3a7e7f962796a86cc3e7dbde8e6f4db4 \ - --hash=sha256:ee776b9d512a011d1ad3907ed53ae32ce2f3d9ff3e1782236554e22103b5c084 +py-spy==0.4.2 \ + --hash=sha256:142887e984a4e541071c99a4401ff8c3770f255d329dbd0f64e8c1dd51882cce \ + --hash=sha256:1ccf688393105111684435f035bc14ec3f22117dd2b85b2414612cf27a22755a \ + --hash=sha256:24720573f95230653b457671a1dcc3c5a381fcf4e92677761e328a430ad251b2 \ + --hash=sha256:7f1c6d9b0e2379ead5bf792df43f4cf36153aa79e6dda4fb8ac7740cf8017110 \ + --hash=sha256:8b06a353c177677e4e1701b288d8c58e2f8d4208ee81a8048d9f72ba800918f8 \ + --hash=sha256:90e600b27bb6bb40479637baca5a5b4bc2ba3395c93d889e672315d93042c4ae \ + --hash=sha256:a0e6f6810ccf0fc5e64e85e0182a5b626c4496eec01b14fb8755154b363a4831 \ + --hash=sha256:aeb0323409199c785f730645e9f4bb7a7b9ca2c481f2c331a55642b5d13fa52f # via ray py4j==0.10.9.9 \ --hash=sha256:c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 \ --hash=sha256:f694cad19efa5bd1dee4f3e5270eb406613c974394035e5bfc4ec1aba870b879 # via pyspark -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -3834,6 +4332,7 @@ pyarrow==23.0.1 \ # deltalake # google-cloud-bigquery # ibis-framework + # mlflow # pandas-gbq # ray # snowflake-connector-python @@ -3841,12 +4340,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -3940,9 +4437,9 @@ pycryptodome==3.23.0 \ --hash=sha256:e3f2d0aaf8080bda0587d58fc9fe4766e012441e2eed4269a77de6aea981c8be \ --hash=sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7 # via minio -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # codeflare-sdk @@ -3955,146 +4452,148 @@ pydantic==2.12.5 \ # fastapi-mcp # great-expectations # mcp + # mlflow-skinny + # mlflow-tracing # pydantic-settings # qdrant-client # ray -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # ipython @@ -4103,11 +4602,12 @@ pygments==2.19.2 \ # nbconvert # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) + # kube-authkit # mcp # msal # singlestoredb @@ -4115,9 +4615,82 @@ pyjwt[crypto]==2.11.0 \ pylatexenc==2.10 \ --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 # via docling -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 + # via feast (pyproject.toml) +pymongo==4.17.0 \ + --hash=sha256:0ff6bd2f735ab5356541e3e57d5b7dbfbc3f2ee1ccb10b6b0f82d58af69d1d8e \ + --hash=sha256:1175563375d682260f613a96fb7a53dce746ed752bfd924eab61de3bc5bfde34 \ + --hash=sha256:1195370a77baf003b59b10e91ecc4706297197f0dd9d29c840cc556dc08f7cee \ + --hash=sha256:12c4fded3a9f1d6a687e36ebd384ac6d00b9b00de1969aa74048e7051ec2a713 \ + --hash=sha256:15d3f3d732aecac1f8d481bde4029755615639bd3076f258a2147210aec8515a \ + --hash=sha256:20323b0b1c1d33770ad1fc68d429c757734ce9ad3594421c3d6618f10572b1b9 \ + --hash=sha256:2a0d5ac205728c86e0a02192f1aa5f865b0d7d51f8df6101c01a69a7fc620d72 \ + --hash=sha256:2db66aa8dd253a0fc1fad3b0d23d5b3993f7ebde02fbbd7727128debf2853675 \ + --hash=sha256:2e190827834fce70ecdf9d46796c6dbc0ce08ea87dc2ff5bc6f3f5579b605cb9 \ + --hash=sha256:320b34457b20bbcc79997801f95d25ce00472915ca5241167242b42c4359e027 \ + --hash=sha256:3689ea34f6b647c7d1e7bdc60fcfb214b2789ed1359a7fb96569c69f50e5f18f \ + --hash=sha256:37a8385c29881b43eab31f584100fa0eaddedd5607adf010147ba1810118be90 \ + --hash=sha256:3987e96e7c7be4083d42e8ac2cc6c0d5b78db9973c90fce42ae800b616ca6b20 \ + --hash=sha256:4141e6c6a339789b2974efa00ecd9409101672d77a0e3ee2cc3839eedf8ec4df \ + --hash=sha256:422fa50d7d7f5c22ea0953554396c9ef95684a2d775f860bd75a7b510538dfca \ + --hash=sha256:47b021363cd923ace5edc7a1d63c0ff8a6d9d43859b8a1ba23645f5afae63221 \ + --hash=sha256:485c8a8eaa4c739f00a331fc73757898ee7c092c214a79e63866ff76aaf282ff \ + --hash=sha256:48bbc576677b50af043df870d84ded67cc3a9b4aa7553201beef4da5dc050a0a \ + --hash=sha256:4ae22fafca69dd3c78261969e999782ac5fc23b76cf8cccfbc3707982a74cc3d \ + --hash=sha256:50e8f8e23c6df7c6d6929f5e734980b227706e73ee847517c9ba5af90f7fc466 \ + --hash=sha256:51e1915761f65f2aaabd0ba691a31d56551d3f19d1263c2d6bf261730603de5f \ + --hash=sha256:5376ad67bb30ae910d83affcf997f706d9dee37e8b5dad8b6fedb0626e262d85 \ + --hash=sha256:5960519b4d7168f1ecdd3ea10c81b2aedeb9423651aca953cfbc8e76705d3b38 \ + --hash=sha256:5a5de048e6da5c18e27cc2437e8c15b3b0cdc8385c15b41178b0caa3322a09c2 \ + --hash=sha256:5ab3b8ff79e0dfc49b68f3c925e8cc735ea95c60efaed84cfe75692dffcaac2a \ + --hash=sha256:64837adbbd72073301af51bb0fc80e3d7707fe5527cea1033ba0320f0b2f881b \ + --hash=sha256:6877214bff5f06f6884a9fc8d9016a4a7a5f51f537f5c51ac3a576f93e7dfb32 \ + --hash=sha256:68fca71e05ee5da23a8d73cee8379dfb3d26e609a377cae731d742771ed96946 \ + --hash=sha256:6c5f62862d0f87be481fa1fe8cb811994486773c94a2b61e509285e3f2890763 \ + --hash=sha256:6fe0de9d0f6791abce3471230b32b4817bf89d27b1182b6a550e1ec0fa72aa9a \ + --hash=sha256:70ffa08ba641468cc068cf46c06b34f01a8ce3489f6411309fcb5ceabe6b2fc0 \ + --hash=sha256:757f2a4c0c2c46cab87df0333681ce69e86c9d5b45bc5203ceba5410b3489e59 \ + --hash=sha256:75bc3aa5b94fdb7138d357ec6ca61cd97e0c79f4f7f0bd3efe9639b15cc50942 \ + --hash=sha256:77aa4bc164b4de60d5db193b322f0f5b6ead716e831031bfdef8e8bd92205556 \ + --hash=sha256:7db10678814cdf7ea39fd308c6f41395cfa7b29d904bcd7895288963d8f892ba \ + --hash=sha256:809ec74de3b9148ae43fa8df9faf53470f511c8d384f13b99d6f671f2a379f15 \ + --hash=sha256:8446ff4bfcb6ec2a2e50998c860986a1e992136f998b7f53e7a717fb8aa5a0b9 \ + --hash=sha256:8a1be016198a03fd7727cdd55998964bfa4e5a6fd9733c8e95830628cef34d29 \ + --hash=sha256:8e97e03fa13327c87e3fdc5656acd01e71817f0c1dc3221cd8f30de136bf4ec3 \ + --hash=sha256:93641192644fa1ee0f34030e774fd31022a27ad11ba22cb1716142231524f8bd \ + --hash=sha256:9543d8f84c2e5608565c08ac679774811e6730770d8a645439b073422a4276fb \ + --hash=sha256:9828485f72f63c7d802e0ec41f71906f633c2692621ab3af55ca990186b091b1 \ + --hash=sha256:9eb5d63a3c518cb0804ed678f5e2b875af032d89a7cf57a57360322cf6a4d222 \ + --hash=sha256:a431b737816bf4cddd4fa0fcef04e424ad36b7692734a64150f872fb8f3208be \ + --hash=sha256:a8f9c40a09bb7d4b9fc8b1da65ecf6efa79bda5cb2756f39d9b6940fac1d19ae \ + --hash=sha256:addd0498ebbdc6354227f6ed457ed9fce442d48a3bb30d5b5bad33e104996561 \ + --hash=sha256:b24598dc3c2feccbc83b43044be48145a0dc4f9bee49ef923e3d707d54a55d85 \ + --hash=sha256:b2dfcc795f5b9fedbe179a11fdf6051581479d196582a3fe819a92a00e9b9969 \ + --hash=sha256:b4384700cffc3f1dd98e088bc0072dedf6d7d68a230bb4b972665cf69c071c1e \ + --hash=sha256:b93b22eedc62598cf5ee9d8c8007a8e9121c50fd88137012d8985500e9dc3151 \ + --hash=sha256:ba2195d4f386f839a52a23ea1cfd60ffaaba78a3d7841db51b7e433001139918 \ + --hash=sha256:bb3ebc86782049f6928dcc583008287cb1c17d463501c94a620f035f5b4fd463 \ + --hash=sha256:bd835cdb37a1adec359dd072c24f8bb14809e2644fde86fab4ee2fc9719b9483 \ + --hash=sha256:c2292144505fb12156b981bd440f3dc994a883da06ac726c0c8692ccdbc1c510 \ + --hash=sha256:c4979e7e8887862bbb44d203f00cc8263a3f27237876fa691b6beba23e40e6d8 \ + --hash=sha256:c5c8e180cb2cabe37300e1e36c60aa4f2ff956cc579f0142135a5d2cba252243 \ + --hash=sha256:c797f8a80957134f6dd9690367a0f8f5906d672119af2c6aa55f0c527b656bed \ + --hash=sha256:c9786665926a09630c5d420c79762cfadbff35a9438bcbc4c81a9fb5ab9228b7 \ + --hash=sha256:cee36b3c0d0354f880fa7a7fdcdaf2bb5e542c2281e25c1bfadf8cfe21eba7d2 \ + --hash=sha256:d53ffa94b2340dbf6b055e09a0090618c60482c158ecfc9565642fc996bf0944 \ + --hash=sha256:df4a644af9ae132d4bfdb2e9516ea51a615fd881caddfbfbd071cf1354844479 \ + --hash=sha256:dff3de1294fbbc1db0ba6b511f77b8e540601d092538a31312e99c8a91a78b1e \ + --hash=sha256:e46767f28dea610e02edf6c5d956ce615c3c7790ea396660b9b1efd5c5ead2e0 \ + --hash=sha256:e4fab10f8403169ce92f3cea921609d9ee81107306caae06c08f592d4b8ad2b5 \ + --hash=sha256:e537e95514dae1aaa718f481ec03151a0f0394bcd05f1322896d8fc1330cb729 \ + --hash=sha256:e68c76b84e0c132d9dbf9307f12ff8185702328187a87b9aca8c941303873433 \ + --hash=sha256:e816db649ba5d7de0568cf3a9f287a9dc9aad21cf0ca667ab156a7ef47fca0b0 \ + --hash=sha256:f09645e0ce4e3825fa0baa8254064a716ed0be33f78feeedd4731016cb8aaa17 \ + --hash=sha256:f3ee3d241ed77a4fc99ce3cff3b289c3ebce37f61fdd7349d3592c23b82c8784 \ + --hash=sha256:faf03e4c2aafd6de626dbd30ba246d369ae33f47f10629d1bbe40f72115027a6 \ + --hash=sha256:ff5aa3f1c7e3f08eb0e7a016c91ba468b1850ccfd63d9b1f12f56350f4974cef # via feast (pyproject.toml) pymssql==2.3.2 \ --hash=sha256:06883bc9bdb297ae9132d9371b5b1a3a223c8f93dd6a87d1c112c6a688f26d53 \ @@ -4179,9 +4752,9 @@ pymssql==2.3.2 \ --hash=sha256:fb8a7b197aaf466a7577ca6690aa9d747081b653ab212d052d71f3cc10587c3b \ --hash=sha256:fdd774b26407babd0205ef85a098f90553e6b3da77a22322a1e7d2cb51f742c0 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) pynacl==1.6.2 \ --hash=sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c \ @@ -4278,14 +4851,16 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==25.1.0 \ - --hash=sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab \ - --hash=sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ --hash=sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc - # via great-expectations + # via + # great-expectations + # matplotlib pypdfium2==4.30.0 \ --hash=sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e \ --hash=sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29 \ @@ -4307,8 +4882,8 @@ pyproject-hooks==1.2.0 \ # via # build # pip-tools -pyspark==4.1.1 \ - --hash=sha256:77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec +pyspark==4.1.2 \ + --hash=sha256:fa5d6159f700d0990a07f4f62df1b7449401dccee9cd7d5d6df8957530841602 # via feast (pyproject.toml) pytest==7.4.4 \ --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ @@ -4332,9 +4907,9 @@ pytest-benchmark==3.4.1 \ --hash=sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809 \ --hash=sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47 # via feast (pyproject.toml) -pytest-cov==7.0.0 \ - --hash=sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1 \ - --hash=sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861 +pytest-cov==7.1.0 \ + --hash=sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2 \ + --hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 # via feast (pyproject.toml) pytest-env==1.1.3 \ --hash=sha256:aada77e6d09fcfb04540a6e462c58533c37df35fa853da78707b17ec04d17dfc \ @@ -4361,112 +4936,146 @@ pytest-xdist==3.8.0 \ --hash=sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 \ --hash=sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1 # via feast (pyproject.toml) -python-bidi==0.6.7 \ - --hash=sha256:01ff2fd676ef8351f32e820b2d3b61eac875a21702d2118263a2641b458e1996 \ - --hash=sha256:05fe5971110013610f0db40505d0b204edc756e92eafac1372a464f8b9162b11 \ - --hash=sha256:06650a164e63e94dc8a291cc9d415b4027cb1cce125bc9b02dac0f34d535ed47 \ - --hash=sha256:0cb75e8a410166fd677d55095e505bf6a4773c066f51efbda72d302ebc56e79b \ - --hash=sha256:0dbb4bbae212cca5bcf6e522fe8f572aff7d62544557734c2f810ded844d9eea \ - --hash=sha256:0f86e447e94ae78db7d56e7da2124c435eaee4425c87d3d92aea271317811112 \ - --hash=sha256:11c51579e01f768446a7e13a0059fea1530936a707abcbeaad9467a55cb16073 \ - --hash=sha256:1395e236c71f11267860b53293a33b19b991b06e0f4ac61045b892e6a99d96f2 \ - --hash=sha256:17572944e6d8fb616d111fc702c759da2bf7cedab85a3e4fa2af0c9eb95ed438 \ - --hash=sha256:19737d217088ef27014f98eac1827c5913e6fb1dea96332ed84ede61791070d9 \ - --hash=sha256:1ba28642928d1c8fdb18b0632fe931f156e888c646326a3ad8eb3e55ee904951 \ - --hash=sha256:1c061207212cd1db27bf6140b96dcd0536246f1e13e99bb5d03f4632f8e2ad7f \ - --hash=sha256:1c5fb99f774748de283fadf915106f130b74be1bade934b7f73a7a8488b95da1 \ - --hash=sha256:1dd0a5ec0d8710905cebb4c9e5018aa8464395a33cb32a3a6c2a951bf1984fe5 \ - --hash=sha256:24388c77cb00b8aa0f9c84beb7e3e523a3dac4f786ece64a1d8175a07b24da72 \ - --hash=sha256:24a4a268289bbe80ad7da3064d7325f1571173859e8ad75d2f99075d5278b02b \ - --hash=sha256:24afff65c581a5d6f658a9ec027d6719d19a1d8a4401000fdb22d2eeb677b8e3 \ - --hash=sha256:257d6dd0e07221f1dc8720fa61158471f5aae30d5f89837c38a026386151c250 \ - --hash=sha256:26a8fe0d532b966708fc5f8aea0602107fde4745a8a5ae961edd3cf02e807d07 \ - --hash=sha256:2a93b0394cc684d64356b0475858c116f1e335ffbaba388db93bf47307deadfa \ - --hash=sha256:2d28e2bdcadf5b6161bb4ee9313ce41eac746ba57e744168bf723a415a11af05 \ - --hash=sha256:349b89c3110bd25aa56d79418239ca4785d4bcc7a596e63bb996a9696fc6a907 \ - --hash=sha256:3a85275dfc24a96629da058c4c2fc93af6390aefe2f7cdde1500b6ac3fd40ca0 \ - --hash=sha256:3b63d19f3f56ff7f99bce5ca9ef8c811dbf0f509d8e84c1bc06105ed26a49528 \ - --hash=sha256:3b96744e4709f4445788a3645cea7ef8d7520ccd4fa8bbbfb3b650702e12c1e6 \ - --hash=sha256:414004fe9cba33d288ff4a04e1c9afe6a737f440595d01b5bbed00d750296bbd \ - --hash=sha256:4283f8b517411cc81b3c92d11998981fe54ac0d2300f4c58d803e0c071aba1ba \ - --hash=sha256:4636d572b357ab9f313c5340915c1cf51e3e54dd069351e02b6b76577fd1a854 \ - --hash=sha256:47deaada8949af3a790f2cd73b613f9bfa153b4c9450f91c44a60c3109a81f73 \ - --hash=sha256:49639743f1230648fd4fb47547f8a48ada9c5ca1426b17ac08e3be607c65394c \ - --hash=sha256:4c73cd980d45bb967799c7f0fc98ea93ae3d65b21ef2ba6abef6a057720bf483 \ - --hash=sha256:4d84e70923392f8c9611f0fb6b341577346ef6224f3809b05f0ae1fbf8f17578 \ - --hash=sha256:4ea928c31c7364098f853f122868f6f2155d6840661f7ea8b2ccfdf6084eb9f4 \ - --hash=sha256:5013ba963e9da606c4c03958cc737ebd5f8b9b8404bd71ab0d580048c746f875 \ - --hash=sha256:5debaab33562fdfc79ffdbd8d9c51cf07b8529de0e889d8cd145d78137aab21e \ - --hash=sha256:5ebc19f24e65a1f5c472e26d88e78b9d316e293bc6f205f32de4c4e99276336e \ - --hash=sha256:630cee960ba9e3016f95a8e6f725a621ddeff6fd287839f5693ccfab3f3a9b5c \ - --hash=sha256:6323e943c7672b271ad9575a2232508f17e87e81a78d7d10d6e93040e210eddf \ - --hash=sha256:6c051f2d28ca542092d01da8b5fe110fb6191ff58d298a54a93dc183bece63bf \ - --hash=sha256:6c19ab378fefb1f09623f583fcfa12ed42369a998ddfbd39c40908397243c56b \ - --hash=sha256:6df7be07af867ec1d121c92ea827efad4d77b25457c06eeab477b601e82b2340 \ - --hash=sha256:6f9fa1257e075eeeed67d21f95e411036b7ca2b5c78f757d4ac66485c191720a \ - --hash=sha256:7336a3c4ba4fc9e6741fbe60c6483266fe39e1f24830724dfce453471d11fa40 \ - --hash=sha256:73a88dc333efc42281bd800d5182c8625c6e11d109fc183fe3d7a11d48ab1150 \ - --hash=sha256:766d5f5a686eb99b53168a7bdfb338035931a609bdbbcb537cef9e050a86f359 \ - --hash=sha256:77bb4cbadf4121db395189065c58c9dd5d1950257cc1983004e6df4a3e2f97ad \ - --hash=sha256:77fea54c2379b93def4ed16db6390e1232e7b235679587295a23dd8b1925475f \ - --hash=sha256:8047c33b85f7790474a1f488bef95689f049976a4e1c6f213a8d075d180a93e4 \ - --hash=sha256:80e6fd06f6e4074d183cea73962c89cf76cb4f70c0ee403689f57a429ebde488 \ - --hash=sha256:849a57d39feaf897955d0b19bbf4796bea53d1bcdf83b82e0a7b059167eb2049 \ - --hash=sha256:8678c2272e7bd60a75f781409e900c9ddb9f01f55c625d83ae0d49dfc6a2674f \ - --hash=sha256:8814db38fa317bebec8eb74b826bae7d0cb978a7eca30dfe4ecf60e61f06ee0b \ - --hash=sha256:8860d67dc04dc530b8b4f588f38b7341a76f2ec44a45685a2d54e9dcffa5d15a \ - --hash=sha256:898db0ea3e4aaa95b7fecba02a7560dfbf368f9d85053f2875f6d610c4d4ec2c \ - --hash=sha256:8a17631e3e691eec4ae6a370f7b035cf0a5767f4457bd615d11728c23df72e43 \ - --hash=sha256:8a18c61817f3210ba74ad5792c8a5048d9550ba233233a0a8fe35800350988f4 \ - --hash=sha256:8d4e621caadfdbc73d36eabdb2f392da850d28c58b020738411d09dda6208509 \ - --hash=sha256:94dbfd6a6ec0ae64b5262290bf014d6063f9ac8688bda9ec668dc175378d2c80 \ - --hash=sha256:95867a07c5dee0ea2340fe1d0e4f6d9f5c5687d473193b6ee6f86fa44aac45d1 \ - --hash=sha256:95c9de7ebc55ffb777548f2ecaf4b96b0fa0c92f42bf4d897b9f4cd164ec7394 \ - --hash=sha256:9adeec7cab0f2c2c291bd7faf9fa3fa233365fd0bf1c1c27a6ddd6cc563d4b32 \ - --hash=sha256:9c463ae15e94b1c6a8a50bd671d6166b0b0d779fd1e56cbf46d8a4a84c9aa2d0 \ - --hash=sha256:9d9de35eb5987da27dd81e371c52142dd8e924bd61c1006003071ea05a735587 \ - --hash=sha256:a2eb8fca918c7381531035c3aae31c29a1c1300ab8a63cad1ec3a71331096c78 \ - --hash=sha256:a4319f478ab1b90bbbe9921606ecb7baa0ebf0b332e821d41c3abdf1a30f0c35 \ - --hash=sha256:a507fe6928a27a308e04ebf2065719b7850d1bf9ff1924f4e601ef77758812bd \ - --hash=sha256:a8892a7da0f617135fe9c92dc7070d13a0f96ab3081f9db7ff5b172a3905bd78 \ - --hash=sha256:a99d898ad1a399d9c8cab5561b3667fd24f4385820ac90c3340aa637aa5adfc9 \ - --hash=sha256:aa4136f8ccb9a8cd32befd1b3882c2597e6791e64e8b3cf3129c55549b5de62f \ - --hash=sha256:ab2a5177522b62426db897b655a02f574e27d9735bbeb6da41bc981b771df636 \ - --hash=sha256:ab806fd026bfd48bade5e21e06d0d799cbfad32f236989ff6f37db03a5fbe34f \ - --hash=sha256:ad5f0847da00687f52d2b81828e8d887bdea9eb8686a9841024ea7a0e153028e \ - --hash=sha256:b0bee27fb596a0f518369c275a965d0448c39a0730e53a030b311bb10562d4d5 \ - --hash=sha256:b31d66b62736b8514982a24a7dedcf8c062b27a8e9b51e52d7a5899045a45fe1 \ - --hash=sha256:b38ddfab41d10e780edb431edc30aec89bee4ce43d718e3896e99f33dae5c1d3 \ - --hash=sha256:be1bdbd52145dfe46880d8bb56eacc25aa75c3bb075fa103de7974295eb2811f \ - --hash=sha256:c10065081c0e137975de5d9ba2ff2306286dbf5e0c586d4d5aec87c856239b41 \ - --hash=sha256:c11c62a3cdb9d1426b1536de9e3446cb09c7d025bd4df125275cae221f214899 \ - --hash=sha256:c3777ae3e088e94df854fbcbd8d59f9239b74aac036cb6bbd19f8035c8e42478 \ - --hash=sha256:c3d93171dd65b36eca5367acf19eef82c79b4df557cb4bd0daf323b7a27f2d3b \ - --hash=sha256:c9a679b24f5c6f366a0dec75745e1abeae2f597f033d0d54c74cbe62e7e6ae28 \ - --hash=sha256:caa71c723f512f8d859fa239573086e16f38ffc426b5b2f7dab5d40fdb356c80 \ - --hash=sha256:ce86d9dfc6b409ad16556384244572bb3cbefa2ca0f0eab7fba0ff2112b2f068 \ - --hash=sha256:d4cd82e65b5aeb31bd73534e61ece1cab625f4bcbdc13bc4ddc5f8cbfb37c24a \ - --hash=sha256:d524a4ba765bae9b950706472a77a887a525ed21144fe4b41f6190f6e57caa2c \ - --hash=sha256:d7310312a68fdb1a8249cf114acb5435aa6b6a958b15810f053c1df5f98476e4 \ - --hash=sha256:d8274ff02d447cca026ba00f56070ba15f95e184b2d028ee0e4b6c9813d2aaf9 \ - --hash=sha256:d879be7fb5296409e18731c7ba666d56ecd45b816b2c9eb35138aa1d7777aeb5 \ - --hash=sha256:d87ed09e5c9b6d2648e8856a4e556147b9d3cd4d63905fa664dd6706bc414256 \ - --hash=sha256:dde1c3f3edb1f0095dcbf79cf8a0bb768f9539e809d0ad010d78200eea97d42a \ - --hash=sha256:df5e9db9539d70426f5d20c7ebb6f7b33da5fbd40620e11261fe3fba7e177145 \ - --hash=sha256:e7cad66317f12f0fd755fe41ee7c6b06531d2189a9048a8f37addb5109f7e3e3 \ - --hash=sha256:ec1694134961b71ac05241ac989b49ccf08e232b5834d5fc46f8a7c3bb1c13a9 \ - --hash=sha256:ec985386bc3cd54155f2ef0434fccbfd743617ed6fc1a84dae2ab1de6062e0c6 \ - --hash=sha256:ef9d103706560c15fecaf7d3cff939e0f68ce5763cf0e64d0e4e5d37f9bdd2d1 \ - --hash=sha256:f1350033431d75be749273236dcfc808e54404cd6ece6204cdb1bc4ccc163455 \ - --hash=sha256:f1fe71c203f66bc169a393964d5702f9251cfd4d70279cb6453fdd42bd2e675f \ - --hash=sha256:f24189dc3aea3a0a94391a047076e1014306b39ba17d7a38ebab510553cd1a97 \ - --hash=sha256:f57726b5a90d818625e6996f5116971b7a4ceb888832337d0e2cf43d1c362a90 \ - --hash=sha256:f7c055a50d068b3a924bd33a327646346839f55bcb762a26ec3fde8ea5d40564 \ - --hash=sha256:f7e5072269c34a1b719910ee4decf13b288159fb320f18aba3885f6b6aab7753 \ - --hash=sha256:f7e507e1e798ebca77ddc9774fd405107833315ad802cfdaa1ab07b6d9154fc8 \ - --hash=sha256:fbbffb948a32f9783d1a28bc0c53616f0a76736ed1e7c1d62e3e99a8dfaab869 \ - --hash=sha256:fd87d112eda1f0528074e1f7c0312881816cb75854133021124269a27c6c48dc \ - --hash=sha256:ff06e4aa781aa4f68fbfaf1e727fe221fa1c552fef8ae70b6d2a0178e1f229ad +python-bidi==0.6.10 \ + --hash=sha256:00e8f3504e63a7713bdc1367b3de46270ddc76551f1cf04510039d65a123fd53 \ + --hash=sha256:038d29ba39a638a5aa904e3f86547f6f883ca16b3ea1db98fbc861e9644762fe \ + --hash=sha256:0533a900b9b9fa94e1c906e8cdb15b579389ce3fa959af228a12e8527aaba8cc \ + --hash=sha256:0675bdaceac9e2bd8ea99729d064435d1d1502e1875b87ed72ad93a8da153ff0 \ + --hash=sha256:07de0d6b998184233e8f753cbff5e828e0204b38daa3deaa458af6cb53c0960d \ + --hash=sha256:099b82f05557c1588973cceab0ebd2535800990850b4cbf8eae57682ef746a16 \ + --hash=sha256:099c3c29d813e263e999205ec9d59658c519c3bc51256e8ab3761ff3dc46a1b3 \ + --hash=sha256:09c90aca4713ed86422acfbaf90d8c5c9f64cbae02e737e7f82f13cd2ff4f34c \ + --hash=sha256:09d70ad127cbcb9cc5e90c4f2f427d998450374870f305345a8c23338a0bca55 \ + --hash=sha256:0c63bf9de0646eb7cf8d520e258701e5086c010e18cbc32e8ab884e29d5ff12f \ + --hash=sha256:0e404d7e027bd47553e48d9e3f207f3ee255698cac1fa80380d4703d4397ffe5 \ + --hash=sha256:0ef816ef2a04ce92108cdcc61c7710860e0f2b11906d493e14c6e5b403b09a01 \ + --hash=sha256:0f1c310774819302fba49b0608126033ba4b2bd0fb01d23b2c232df6d31003a4 \ + --hash=sha256:0f6a5c7b00ce285a3389e261db3f0477c2c3e893b352e65889410d995ff5ee13 \ + --hash=sha256:15298befde960a80885729c3603a95058f611b7d71de645cfbdd875f98146e14 \ + --hash=sha256:153a2f75648ceb583a09e66b4da99ec54b82e3226e5c0992f79e05d2d00d5a6e \ + --hash=sha256:1552aad47e65e8458346307e8b3fe7ae8eb0fcf3ea4ce3aba5cf44c50117e30b \ + --hash=sha256:15f0deadc4e8bf4d5458d62c4c94f7716c1d29f106751f2d9f5a478698465df0 \ + --hash=sha256:19c06c20f47f4a3daad14b5e7c2b4e23e76f4277883ef43616ecd9a8eff73203 \ + --hash=sha256:1a156226a8723942b50ffa210d1840688da158c185e3d0840743345003249875 \ + --hash=sha256:1d7714b96ab30df31337f5d100bf71ebe637976e2464761c81ab05787c4bacff \ + --hash=sha256:22f51e0e5c64e18f5f9b6ac2d01fcbbecdfa6a2d571ae71323d3051d0635b9c6 \ + --hash=sha256:2371afc3f50da896212b2d1ea7f461134ef292e1737c87d7547dd0384c092388 \ + --hash=sha256:2598937e05401111ade68cd6e2212fa556fe8cc401b541d19dcd039496a0cfdd \ + --hash=sha256:27fc502f2e368ffcedb97b674956f8306573f43cd0204e2ed9fbe7f41d116a7b \ + --hash=sha256:29a476af5efbe7fedfb53c8d05d1447e4f4149da8d88fa0643716a374b6abf27 \ + --hash=sha256:2a2013623ea8713e4bc712922d37449a4a86a504275b42447e1d2f22eb565f9d \ + --hash=sha256:322bea01cd3f9c1cc153ea4ca3b8f82d27efe5ae8c4bd81cc981420e25490bd4 \ + --hash=sha256:327e570f10443995d3697e8096bc337970dfc32cd5339759fa4e87093cf5cdf9 \ + --hash=sha256:32c6075f2b44c1b3d01e7d0c8a5bb519bdbbc832bee2d4b01a06908117d3b050 \ + --hash=sha256:32eb932af02b2dec7d3043daed84a80e34a3f46327a7cacf6a813773369fceb8 \ + --hash=sha256:341d75c8b0e107bd5188e30a8a340ec5e1a26066f21de3c761b53fde54e6cd7d \ + --hash=sha256:3a2fcfc6be1917695cd6f7c9626481aa81ade7e3ef3f79c0f7a286edf68e4463 \ + --hash=sha256:3a485820e499c74332929eb9fe9246cec92fd4e6b8c2abde03e8d8f0fea00728 \ + --hash=sha256:3d0c48305c58a5ed0017500dbeedbfc62fc8b9cd552d582ea578a10f77eed1c1 \ + --hash=sha256:3ebbf3915c39ed8d0095e3672ed4f824dfe9544e950a273513956b147528a18b \ + --hash=sha256:3ff3bc2221d8c32427cf90999b60ee9bd5e31e2e0b7f54b63ad54a05912725b8 \ + --hash=sha256:441d931609adfb2d213892e2da0326a5c5048f05e36497d5e37087b97a3287dd \ + --hash=sha256:446f1cd15783b14a280fc6c8e8931afa3f4ec1edc0b341b82cfca1537886cf28 \ + --hash=sha256:44caa945d27b7634bb4fdfe8fbeaa27b33fb12b66418e326e5a491d235b5c61b \ + --hash=sha256:44e21c6dc51b88ede76aafe730a208ef5a23cf7275d30d7870ff46e3a6ad4314 \ + --hash=sha256:44e6566093397def4e72f85e47d246d442838c497e6be3b14be0bca7d9761a50 \ + --hash=sha256:452a7ff78909edef965d1f2dc87e8cf04e6d4234771eef9b876688fdd821ab1d \ + --hash=sha256:473e718a86e5a9290ee240cf0cf49093ec0ca841d709f0fef191b7f5ea4e8b3b \ + --hash=sha256:48af3fc3bee49c3be03bbd47b503dc794474c52db249c57d230a4616cf13cf52 \ + --hash=sha256:4ed6794f07fcb4374e74a1a973350c5997c2088ba6143a8fedb533010f379502 \ + --hash=sha256:5040b6595e6a9d1cbca5fc2298684994cc5f1036ff2015eaf30063f015f31540 \ + --hash=sha256:5899a244bc0b60d71ae80dcf0dfad16c72e742857c13c0d040d1c975bb758983 \ + --hash=sha256:5d11a3eb283fbde362c4b1faa32a4053413a83aa6abc2274827e1f03c89f53f4 \ + --hash=sha256:5e4752fc7228a2d70b69dc81fe4bbe602eca44a520b3d7ff46b50fb2b68d435e \ + --hash=sha256:5f3febf9b547b3b237429fb8c214ff8faa50972c6de0fc0fbaf060fc29e4696d \ + --hash=sha256:5fdea42e1356d428cdc1771e3468327cf776da51c44a8ced855b67b02809ea56 \ + --hash=sha256:6054e1b9920a917749fb4e7547b378e0647c25095c012a2a7c184493b9204ef1 \ + --hash=sha256:644d068e01071c7af565a70269f8c93f6434c031df2b1428625ed8f6040b94b4 \ + --hash=sha256:64d4adc41eb79de0561874bbbe74e8f7974b3bb947070d0edd73d388c98e1234 \ + --hash=sha256:6a75d9ab145003094475bc955120b4577d70f34ee02f0b69696d7f216b513479 \ + --hash=sha256:6c5be3141bf22d2908d6269e613c2bc3824db0f31560a61b95be75d224812c67 \ + --hash=sha256:6e2b535558cad96805b58695353a628471e455f4f30e346d1d0a10468c991d0e \ + --hash=sha256:704c76e64aa0f7c0d4b8dff04ce9e8fb38314bddd1426985856e2533e66d7d21 \ + --hash=sha256:732ad1ebff85d4669152ec8c0bbeebdf945a3460e26ae852a30d39d93765765c \ + --hash=sha256:73bc12f9599cf1dbc39e3792abaa8fc62656cff30340308c3341583631ea5fcc \ + --hash=sha256:78248580e38051ba799076bffa5d0498d2550a4fa6d2ec733c38e4ec5a2d8039 \ + --hash=sha256:7965b1c468b986a1bbb9fd3ba8641b51f4f93352cefc83eec851fdf15850019f \ + --hash=sha256:79ba6f914436c674cb0a25d4e1356e54b3b788ccd1498e1b130edd6ba1ad2f8e \ + --hash=sha256:7a3f20dca786d493c1383273992ca87ff78942456898b136e2973a682dad73ae \ + --hash=sha256:7a5452fda554628660eb4c1c4da6187986c5497f34fbeb07f920c867b6daa943 \ + --hash=sha256:7ae97eed360514e229b0c407095a4184d8a0e6383bc87962972ae27f6ecb96e6 \ + --hash=sha256:8012aed843d01a96fbd5c2fe4d8062696f8720d38990d68eaf871aa692652e98 \ + --hash=sha256:81b27ffd3e40e2d8f274e1acbf5967873e53d6f32bf677899e0d8421170703da \ + --hash=sha256:82897bacfd8fc2fb1157b1828a011af954c24b1dc25adb2aec33fdbcacd3935f \ + --hash=sha256:84f6975f51d2af2e9b474669f26673486899138ea985f9967db4f6ab9a431b95 \ + --hash=sha256:86dea78bc3953853afb701b7bf3531f062e7aa7d0a4bdb1a59f496200967bbf7 \ + --hash=sha256:8af0d7059829d43e5b9e4072103f09d3869d3da9fc6db66b51e93da0ed0b1161 \ + --hash=sha256:8f95878c574eb603942561ad76d09ed8b05e2ffd46917b32f15bb83878f7f40e \ + --hash=sha256:903b8e4ea0fed7d453e7e437d41ba0357be55572a108f8d6110ab74cbe3b2bb0 \ + --hash=sha256:916688bcee55ce613879751a27b25977f75403c681e6d110cdf301edb48027a1 \ + --hash=sha256:929c705687f506fed02aa1fbd6781fb310203d7a20420dd7f106cd87fe1d01c5 \ + --hash=sha256:9545c3cd8238a79ab7e0ff7b27326bef3439001207984ea47fa3be31551d364e \ + --hash=sha256:97692e9fb3271a637f18d728d5db4ff729c82ae25356e35d371fada2fe0ff006 \ + --hash=sha256:9c2ae7649b77a4354b6db6423c495bd57ac5727d62266dfe98254896eb573b25 \ + --hash=sha256:a06a6e54a95b5c5864e117af2479113bb367660b0d95295b4adf314b3dff77af \ + --hash=sha256:a0df4cb0fe94de7565c3fc875888431ef774d643f00b030bd041fdebbdcd189b \ + --hash=sha256:a2e1da56d841ae506c49df41e16893428b96d3c8c255f096b1aa83c512302c94 \ + --hash=sha256:a50b1ce6c5a2aaa4febbd72cf030ec7d9bd63a063977850e484fb4a7983f7eaf \ + --hash=sha256:a51922e22ab237431c3d5505b2511732748f936349ab65d0c1a4a13e224144fc \ + --hash=sha256:a5aac3c9648872dcf11543751e2a8970ab0e8e3192fdf83ed507838917f50d70 \ + --hash=sha256:a7853e894f723675489ac49aa4b52dc8eac87d7a67b5940631c8c9d2aab46f90 \ + --hash=sha256:a7871f1226a062c641c500f81f05c2c00274c23de26707d747ce16ede43a6fdb \ + --hash=sha256:a84f26e55770a9326cedf79c005c2e7f9c13da9e0cbb65bc36890382a793bda9 \ + --hash=sha256:a9b83026c2907ad207eff37d5d302ecdd20441ba87d89401a79fa4b9af11f24d \ + --hash=sha256:afd28c86da0968996595b3dcc1166b24367954d69242c186c0916721fe36274d \ + --hash=sha256:b048ba7ec56dfd0eb37bee34d395771d1ce444fd7a32c6e8ddd3bfc92090a1d8 \ + --hash=sha256:b0c77d935abdd7e3bee0f9b8a7d0ae8a7c230e5aca3a7b9948576b2e151c9985 \ + --hash=sha256:b223d1f5493530777475fc40e4a47b6854a5ac56ea3211196d7a91809fa565f3 \ + --hash=sha256:b35b3c7e2c91f67dbf49de4513adf80ee052b06f15dcb9e7e5c6cd6f37373114 \ + --hash=sha256:b35ff4e825c4ad912a30909f2922eddd684c84bffc48e713c8bf22a4f3d7794f \ + --hash=sha256:b45368872b3770b20d101a87364ffeec5c0cf02d8aaee1834c30167fe29ddaaa \ + --hash=sha256:b47233bf36749ab63561ece99b8b32684043558415f1e4ca6c540f1793fa12f3 \ + --hash=sha256:b497a46082c3b0e0f9a2571d573e745686ed1a6f7a9c631ebe2b9d6f55ecc87a \ + --hash=sha256:b528e71c3f4b867e207418ea4ed465a111306ac6c2838bf75ff1e465c74ea933 \ + --hash=sha256:b5c66316296044bcdda0fa37296322973c73b708eac737565d5bbc2f6fd51037 \ + --hash=sha256:b6bbca74b7d39d4f259c0eebb6d62fd970999c0beae553db7232319d151fa533 \ + --hash=sha256:b6ff61cd6e3a60ae9bd559aa5ab5a7018e8d26067e7f80ca0ac30e08c76bf983 \ + --hash=sha256:b97376c559d90d80976a2b3c2d1f7699b6e3ae69ffd2bfdefaacf1eb4bc45f8e \ + --hash=sha256:bca06cdbd6d90a939af253ddeed232e7e122a1e027942c2ebd431307e6471be6 \ + --hash=sha256:bd1247b5138e23824b62f96aa03f1d45084dee6c76c46019784546cc432a85ee \ + --hash=sha256:c1726465626bcad9518ff878be9edb6897b42d57c1bfb9e4a00ffd4000980c48 \ + --hash=sha256:c267e531392cbdd900e46796d410dda380c7b311434bf5090ee261bb05650bcc \ + --hash=sha256:c2960742693ee19663bc448328b6b7035f6ae4ad28f57379568d22180911c7d5 \ + --hash=sha256:c55787b0274b1e06530817fe6d375a5443a0e32d5ee55071244fe5af3483fcbc \ + --hash=sha256:c5fb03df1d641d19cec53ee9eb5b89f659d0087d03ae94f06e78e2663824d013 \ + --hash=sha256:c7aa354a62e727b592cfa181a5d435d9a946aba4dd2349bb18fc52c869d470f1 \ + --hash=sha256:c7b849fa2ed07cb59ed5e76d3cf0e3527b7d7bfa2e70d4fcb6df048a9c9177ee \ + --hash=sha256:cac7477518b8cfd53e78527a873be7de5a69183397124f7ebcae295cc39187c1 \ + --hash=sha256:cdc2933960f9b1b160551ff4a0cc543ec3866550ad13f35f1881c22f08b5ad82 \ + --hash=sha256:ce576c6e9a548e09c853e47cb88a95bb29363586c6ec7778ead517e61449b275 \ + --hash=sha256:d698d1354d7e30d3a3fbfb91b7b6c904e13875b4ed2dc40c726ca23d82b5089a \ + --hash=sha256:d6ec69bd053def14e4538b15dcd28bc9528c820b644687c0d38afc38e81fe8e8 \ + --hash=sha256:d717dc455632ab75284969106c4f40cc1533709f852c50d6db643b20e903b23d \ + --hash=sha256:d7d9b2602cccbb92fc6a8b8ab2b1f0f03c77c126e089f22f7747b19499cb3e1d \ + --hash=sha256:de06759a2b223599a98a200b01b9fdafec7e346b513ce6a31632f7089234eca3 \ + --hash=sha256:de7f4782b4381ae5b0dfa36ce1e4b0a925ccecd4f52330fcc50bcd73430b99fd \ + --hash=sha256:df0a3aa46c78e56ebed8c5be33da34c0408d4114c6b782103208fecbd3b6cac0 \ + --hash=sha256:e0fe5c41dac834dfbf1f93f29438393fef13ce250e699d67d2c066da6a0eb8af \ + --hash=sha256:e13dc08bcf7ef257d0635400e3377d3a776ec57ea25e985e903b00bf5ea06911 \ + --hash=sha256:e2e81871fa3353376a35260bf0313e631624eac6997d8fa4d60f38beee3f633f \ + --hash=sha256:e4871a8955ba6c4d80eaffc0f44af6ab724a99f4ec2ad6499243fe542027494f \ + --hash=sha256:e65f8b3029e64af05323cc630550b27649d8b1b612387c2e88411ae32c6a5b59 \ + --hash=sha256:e75704f210e8fbcfbe9546f33d4ef86ff9932830d74726108b45dad72d5c1b55 \ + --hash=sha256:e7f1fa876d3b7c09c1c6be627338502e78d3cc6e9b21ea94f8eeec6ad4157afa \ + --hash=sha256:edec736cfe6b5421e6c0fbf3e4fc70b5db30263d22e070526c7c540f5895f9fb \ + --hash=sha256:f3386c4370515f7acb3372ca49b4bd6652b65c381f50e772b5de96da7df2dbad \ + --hash=sha256:f53dbcc5b1ab75ee593f9ccdd474f9091e21b2051ade79db9930540188f3c9e3 \ + --hash=sha256:f6dad7fe7f004900a45b04ab2ef51dd11a46c7be4b182c2e533810435e197249 \ + --hash=sha256:f6e8fca537eb348409549b75f8721fe911cc001124cc7cbfa1a4722e641584c3 \ + --hash=sha256:f6fb6b3fef1b611841f50688c46d722ad5bd9bb5b9beec9d7c51885519f6026c \ + --hash=sha256:fc012f8738e21462b8b173278ef9278a822373a64f558ac1bfa36eceb56296df \ + --hash=sha256:fedf838627e262a5a3b9312a144582e7c81ff3be986a3b0ecd51b9d904747c0b \ + --hash=sha256:ff693056db843b5e4de6d8e50b4847c116481406492d10517dfe4d7c573c8f82 # via easyocr python-dateutil==2.9.0 \ --hash=sha256:78e73e19c63f5b20ffa567001531680d939dc042bf7850431877645523c66709 \ @@ -4478,10 +5087,12 @@ python-dateutil==2.9.0 \ # botocore # elasticsearch # google-cloud-bigquery + # graphene # great-expectations # ibis-framework # jupyter-client # kubernetes + # matplotlib # moto # openlineage-python # pandas @@ -4494,31 +5105,31 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via + # mlflow-skinny # pydantic-settings # pymilvus # testcontainers # uvicorn -python-json-logger==4.0.0 \ - --hash=sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2 \ - --hash=sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f +python-json-logger==4.1.0 \ + --hash=sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2 \ + --hash=sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195 # via jupyter-events python-keycloak==4.2.2 \ --hash=sha256:1d43a1accd4a038ed39317fcb3eb78211df6c75bbcbc4c482c99ee76327136f2 \ --hash=sha256:5137fd87c69031a372a578df96bae96b9aead2c9dad976613bc978e9e0246a1e # via feast (pyproject.toml) -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ --hash=sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095 # via docling -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via - # clickhouse-connect # great-expectations # pandas # snowflake-connector-python @@ -4607,6 +5218,7 @@ pyyaml==6.0.3 \ # huggingface-hub # jupyter-events # kubernetes + # mlflow-skinny # openlineage-python # openshift-client # pre-commit @@ -4712,30 +5324,30 @@ pyzmq==27.1.0 \ # ipykernel # jupyter-client # jupyter-server -qdrant-client==1.17.0 \ - --hash=sha256:47eb033edb9be33a4babb4d87b0d8d5eaf03d52112dca0218db7f2030bf41ba9 \ - --hash=sha256:f5b452c68c42b3580d3d266446fb00d3c6e3aae89c916e16585b3c704e108438 +qdrant-client==1.18.0 \ + --hash=sha256:093aa8cf8a420ee3ad2a68b007e1378d7992b2600e0b53c193fc172674f659cd \ + --hash=sha256:52e8ece1a7d40519801bf0b70713bfa0f6b7ae28c7275bbe0b0286fbed7f6db4 # via feast (pyproject.toml) -ray[data, default]==2.52.1 \ - --hash=sha256:08eb8f5fd55292ba6bee363a32491136a5e54af54e007f81e0603986fbea41a4 \ - --hash=sha256:24694e60cdc7770b90f123cc578cabb9d1a231c1fe673b5da0027b118de45846 \ - --hash=sha256:2b57ef272a2a0a0dbae6d18d70aa541eab620b4fe3b44d50466d3a533c16f9d9 \ - --hash=sha256:4e8478544fef69a17d865431c0bebdcfeff7c0f76a306f29b73c3bc3cbb0bdb9 \ - --hash=sha256:65bf461fdfe4ffa667c46f9455f8740b2ad6c1fa471b461d5f5cf6b7baf177b5 \ - --hash=sha256:6831592fedf0a122016f5dab4b67d85fa3d4db3b21f588d18834b5c031396d1c \ - --hash=sha256:8045172ad3fcff62b9dab9a4cd2e0991ad0e27fc814fe625a8d3a120306651d6 \ - --hash=sha256:843c0108ad72bb7fc6c23a22e29e6099546a5eaad3ad675c78a146d9080f6ec6 \ - --hash=sha256:993194a8be70540e0f819862031bbf19a64401fbe6c31b42065fd313ba466d34 \ - --hash=sha256:a5a3c268d45060c50cd029979ecc5f1eaaec040b19fa88dd4fe9e927d19ff13e \ - --hash=sha256:b3f9e61b799fb3cc8fd7077a3d2eb676ddfef7db644f6b6a2b657c5c3214cf19 \ - --hash=sha256:b5bc29548abb0a0a7ae9e6ff3b0ccca2824edaf011a4336e15a32793d574fbfd \ - --hash=sha256:bbe492c780a39a64bd3d0766cad10d54cf12222df88d287ec2d8f2d52de37c79 \ - --hash=sha256:e3826aeb4e4399de0c6885bd8be7ce2f629fa0010f0013f1183e0726b3d25e40 \ - --hash=sha256:f59e3b2d1a1466ac0778f2c6fac9ccb5f30107d77e3dddd1d60167248d268474 +ray[data, default]==2.54.1 \ + --hash=sha256:054985194bd32f4464c93f9318d247fac61e1f32ac221565ecfdc81ab8c75d0b \ + --hash=sha256:0c3ae2943176e7b239c78b825a5b2bf4135d90280083a0e19c0a75a5db4d836f \ + --hash=sha256:2766f0230806480c38a9a94502087f1d4aea919f38521a28781690613b0290a4 \ + --hash=sha256:2ea650e648acc6e76edd98c694657fd1fcb1cd97700d944a7d20da90269e9810 \ + --hash=sha256:4c6f7e23dda62a32f94083141c3f97e9c4246e3ae4ae2bc488bcd8fd0311f54a \ + --hash=sha256:512587412e2f5e1753adabfdfa4dd9cff1dc509601e36fd5fab671e448ae4dac \ + --hash=sha256:6425f15cfe6a298366b53c8658350f94ced2c548802ca3b69f94b87db16e97c5 \ + --hash=sha256:645ebfb73cfd32bd510a05ed9f2738a18d6db69929cae9701d749f2740dbfd9a \ + --hash=sha256:673a895c0c4a716ed772552baa3f5b8d7d1f7a4b34e04787fdfe6fe3049ed0d8 \ + --hash=sha256:86c51eafd3e84dad59c1ef4cf97b3ac8c088af0705782ee915e31bca5880597a \ + --hash=sha256:c0240496af274af7cd3b1b1d015f23b88e5fdafe59bfdc040e5f229e0aff5dff \ + --hash=sha256:cd452b61ae2e0daf9271f5a554614397429cc2731681bae10fe72316dadc2749 \ + --hash=sha256:d05f477d1518a00fd5880644e889a7a3eaf64ae5d1f8f239a682d052ad2a383d \ + --hash=sha256:e095dfe9c521a04e5930520b4a82ea82d61903d4cd2f3270fbc5dfbdb41b9c72 \ + --hash=sha256:ea90bed0110e0ce3ff6571e7a0c800920a3c6d299d29b8eac020dac362667169 # via codeflare-sdk -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4744,131 +5356,132 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.2.28 \ - --hash=sha256:00945d007fd74a9084d2ab79b695b595c6b7ba3698972fadd43e23230c6979c1 \ - --hash=sha256:00f2b8d9615aa165fdff0a13f1a92049bfad555ee91e20d246a51aa0b556c60a \ - --hash=sha256:01d65fd24206c8e1e97e2e31b286c59009636c022eb5d003f52760b0f42155d4 \ - --hash=sha256:02473c954af35dd2defeb07e44182f5705b30ea3f351a7cbffa9177beb14da5d \ - --hash=sha256:03a83cc26aa2acda6b8b9dfe748cf9e84cbd390c424a1de34fdcef58961a297a \ - --hash=sha256:09500be324f49b470d907b3ef8af9afe857f5cca486f853853f7945ddbf75911 \ - --hash=sha256:0b1d2b07614d95fa2bf8a63fd1e98bd8fa2b4848dc91b1efbc8ba219fdd73952 \ - --hash=sha256:0d25a10811de831c2baa6aef3c0be91622f44dd8d31dd12e69f6398efb15e48b \ - --hash=sha256:0d5bef2031cbf38757a0b0bc4298bb4824b6332d28edc16b39247228fbdbad97 \ - --hash=sha256:10d28e19bd4888e4abf43bd3925f3c134c52fdf7259219003588a42e24c2aa25 \ - --hash=sha256:180e08a435a0319e6a4821c3468da18dc7001987e1c17ae1335488dfe7518dd8 \ - --hash=sha256:195237dc327858a7721bf8b0bbbef797554bc13563c3591e91cd0767bacbe359 \ - --hash=sha256:19a9c9e0a8f24f39d575a6a854d516b48ffe4cbdcb9de55cb0570a032556ecff \ - --hash=sha256:1c2c95e1a2b0f89d01e821ff4de1be4b5d73d1f4b0bf679fa27c1ad8d2327f1a \ - --hash=sha256:1d367257cd86c1cbb97ea94e77b373a0bbc2224976e247f173d19e8f18b4afa7 \ - --hash=sha256:1e496956106fd59ba6322a8ea17141a27c5040e5ee8f9433ae92d4e5204462a0 \ - --hash=sha256:1f8b17be5c27a684ea6759983c13506bd77bfc7c0347dff41b18ce5ddd2ee09a \ - --hash=sha256:2234059cfe33d9813a3677ef7667999caea9eeaa83fef98eb6ce15c6cf9e0215 \ - --hash=sha256:25b6eb660c5cf4b8c3407a1ed462abba26a926cc9965e164268a3267bcc06a43 \ - --hash=sha256:2954379dd20752e82d22accf3ff465311cbb2bac6c1f92c4afd400e1757f7451 \ - --hash=sha256:2afa673660928d0b63d84353c6c08a8a476ddfc4a47e11742949d182e6863ce8 \ - --hash=sha256:2b2b23587b26496ff5fd40df4278becdf386813ec00dc3533fa43a4cf0e2ad3c \ - --hash=sha256:2fb950ac1d88e6b6a9414381f403797b236f9fa17e1eee07683af72b1634207b \ - --hash=sha256:3935174fa4d9f70525a4367aaff3cb8bc0548129d114260c29d9dfa4a5b41692 \ - --hash=sha256:39bb5727650b9a0275c6a6690f9bb3fe693a7e6cc5c3155b1240aedf8926423e \ - --hash=sha256:3b24bd7e9d85dc7c6a8bd2aa14ecd234274a0248335a02adeb25448aecdd420d \ - --hash=sha256:4390c365fd2d45278f45afd4673cb90f7285f5701607e3ad4274df08e36140ae \ - --hash=sha256:481df4623fa4969c8b11f3433ed7d5e3dc9cec0f008356c3212b3933fb77e3d8 \ - --hash=sha256:4f5c0b182ad4269e7381b7c27fdb0408399881f7a92a4624fd5487f2971dfc11 \ - --hash=sha256:50c2fc924749543e0eacc93ada6aeeb3ea5f6715825624baa0dccaec771668ae \ - --hash=sha256:511f7419f7afab475fd4d639d4aedfc54205bcb0800066753ef68a59f0f330b5 \ - --hash=sha256:516604edd17b1c2c3e579cf4e9b25a53bf8fa6e7cedddf1127804d3e0140ca64 \ - --hash=sha256:52b017b35ac2214d0db5f4f90e303634dc44e4aba4bd6235a27f97ecbe5b0472 \ - --hash=sha256:5a932ea8ad5d0430351ff9c76c8db34db0d9f53c1d78f06022a21f4e290c5c18 \ - --hash=sha256:5cdcc17d935c8f9d3f4db5c2ebe2640c332e3822ad5d23c2f8e0228e6947943a \ - --hash=sha256:5d10303dd18cedfd4d095543998404df656088240bcfd3cd20a8f95b861f74bd \ - --hash=sha256:5e68192bb3a1d6fb2836da24aa494e413ea65853a21505e142e5b1064a595f3d \ - --hash=sha256:64e7c6ad614573e0640f271e811a408d79a9e1fe62a46adb602f598df42a818d \ - --hash=sha256:6591f281cb44dc13de9585b552cec6fc6cf47fb2fe7a48892295ee9bc4a612f9 \ - --hash=sha256:69fc560ccbf08a09dc9b52ab69cacfae51e0ed80dc5693078bdc97db2f91ae96 \ - --hash=sha256:6d63a07e5ec8ce7184452cb00c41c37b49e67dc4f73b2955b5b8e782ea970784 \ - --hash=sha256:6db7bfae0f8a2793ff1f7021468ea55e2699d0790eb58ee6ab36ae43aa00bc5b \ - --hash=sha256:71a911098be38c859ceb3f9a9ce43f4ed9f4c6720ad8684a066ea246b76ad9ff \ - --hash=sha256:73cdcdbba8028167ea81490c7f45280113e41db2c7afb65a276f4711fa3bcbff \ - --hash=sha256:78454178c7df31372ea737996fb7f36b3c2c92cccc641d251e072478afb4babc \ - --hash=sha256:7900157786428a79615a8264dac1f12c9b02957c473c8110c6b1f972dcecaddf \ - --hash=sha256:7ab218076eb0944549e7fe74cf0e2b83a82edb27e81cc87411f76240865e04d5 \ - --hash=sha256:7c1b34dfa72f826f535b20712afa9bb3ba580020e834f3c69866c5bddbf10098 \ - --hash=sha256:851fa70df44325e1e4cdb79c5e676e91a78147b1b543db2aec8734d2add30ec2 \ - --hash=sha256:864cdd1a2ef5716b0ab468af40139e62ede1b3a53386b375ec0786bb6783fc05 \ - --hash=sha256:8710d61737b0c0ce6836b1da7109f20d495e49b3809f30e27e9560be67a257bf \ - --hash=sha256:9036b400b20e4858d56d117108d7813ed07bb7803e3eed766675862131135ca6 \ - --hash=sha256:9185cc63359862a6e80fe97f696e04b0ad9a11c4ac0a4a927f979f611bfe3768 \ - --hash=sha256:948c12ef30ecedb128903c2c2678b339746eb7c689c5c21957c4a23950c96d15 \ - --hash=sha256:94d63db12e45a9b9f064bfe4800cefefc7e5f182052e4c1b774d46a40ab1d9bb \ - --hash=sha256:96f6269a2882fbb0ee76967116b83679dc628e68eaea44e90884b8d53d833881 \ - --hash=sha256:97054c55db06ab020342cc0d35d6f62a465fa7662871190175f1ad6c655c028f \ - --hash=sha256:98adf340100cbe6fbaf8e6dc75e28f2c191b1be50ffefe292fb0e6f6eefdb0d8 \ - --hash=sha256:99985a2c277dcb9ccb63f937451af5d65177af1efdeb8173ac55b61095a0a05c \ - --hash=sha256:9b65d33a17101569f86d9c5966a8b1d7fbf8afdda5a8aa219301b0a80f58cf7d \ - --hash=sha256:9dd450db6458387167e033cfa80887a34c99c81d26da1bf8b0b41bf8c9cac88e \ - --hash=sha256:a25c7701e4f7a70021db9aaf4a4a0a67033c6318752146e03d1b94d32006217e \ - --hash=sha256:a448af01e3d8031c89c5d902040b124a5e921a25c4e5e07a861ca591ce429341 \ - --hash=sha256:a5dac14d0872eeb35260a8e30bac07ddf22adc1e3a0635b52b02e180d17c9c7e \ - --hash=sha256:a729e47d418ea11d03469f321aaf67cdee8954cde3ff2cf8403ab87951ad10f2 \ - --hash=sha256:aaffaecffcd2479ce87aa1e74076c221700b7c804e48e98e62500ee748f0f550 \ - --hash=sha256:b059e71ec363968671693a78c5053bd9cb2fe410f9b8e4657e88377ebd603a2e \ - --hash=sha256:b387a0d092dac157fb026d737dde35ff3e49ef27f285343e7c6401851239df27 \ - --hash=sha256:b389c61aa28a79c2e0527ac36da579869c2e235a5b208a12c5b5318cda2501d8 \ - --hash=sha256:b42f7466e32bf15a961cf09f35fa6323cc72e64d3d2c990b10de1274a5da0a59 \ - --hash=sha256:b49eb78048c6354f49e91e4b77da21257fecb92256b6d599ae44403cab30b05b \ - --hash=sha256:b5acd4b6a95f37c3c3828e5d053a7d4edaedb85de551db0153754924cb7c83e3 \ - --hash=sha256:b8b3f1be1738feadc69f62daa250c933e85c6f34fa378f54a7ff43807c1b9117 \ - --hash=sha256:b8cf76f1a29f0e99dcfd7aef1551a9827588aae5a737fe31442021165f1920dc \ - --hash=sha256:ba55c50f408fb5c346a3a02d2ce0ebc839784e24f7c9684fde328ff063c3cdea \ - --hash=sha256:bba2b18d70eeb7b79950f12f633beeecd923f7c9ad6f6bae28e59b4cb3ab046b \ - --hash=sha256:bbb882061f742eb5d46f2f1bd5304055be0a66b783576de3d7eef1bed4778a6e \ - --hash=sha256:bcb399ed84eabf4282587ba151f2732ad8168e66f1d3f85b1d038868fe547703 \ - --hash=sha256:bd477d5f79920338107f04aa645f094032d9e3030cc55be581df3d1ef61aa318 \ - --hash=sha256:bec23c11cbbf09a4df32fe50d57cbdd777bc442269b6e39a1775654f1c95dee2 \ - --hash=sha256:c0b5ccbb8ffb433939d248707d4a8b31993cb76ab1a0187ca886bf50e96df952 \ - --hash=sha256:c15af43c72a7fb0c97cbc66fa36a43546eddc5c06a662b64a0cbf30d6ac40944 \ - --hash=sha256:c7815afb0ca45456613fdaf60ea9c993715511c8d53a83bc468305cbc0ee23c7 \ - --hash=sha256:cb3b1db8ff6c7b8bf838ab05583ea15230cb2f678e569ab0e3a24d1e8320940b \ - --hash=sha256:d0b02e8b7e5874b48ae0f077ecca61c1a6a9f9895e9c6dfb191b55b242862033 \ - --hash=sha256:d6b08a06976ff4fb0d83077022fde3eca06c55432bb997d8c0495b9a4e9872f4 \ - --hash=sha256:d6cfe798d8da41bb1862ed6e0cba14003d387c3c0c4a5d45591076ae9f0ce2f8 \ - --hash=sha256:d8511a01d0e4ee1992eb3ba19e09bc1866fe03f05129c3aec3fdc4cbc77aad3f \ - --hash=sha256:dc8ed8c3f41c27acb83f7b6a9eb727a73fc6663441890c5cb3426a5f6a91ce7d \ - --hash=sha256:dd8847c4978bc3c7e6c826fb745f5570e518b8459ac2892151ce6627c7bc00d5 \ - --hash=sha256:de0cf053139f96219ccfabb4a8dd2d217c8c82cb206c91d9f109f3f552d6b43d \ - --hash=sha256:dee50f1be42222f89767b64b283283ef963189da0dda4a515aa54a5563c62dec \ - --hash=sha256:e1e7b24cb3ae9953a560c563045d1ba56ee4749fbd05cf21ba571069bd7be81b \ - --hash=sha256:e59bc8f30414d283ae8ee1617b13d8112e7135cb92830f0ec3688cb29152585a \ - --hash=sha256:e61eea47230eba62a31f3e8a0e3164d0f37ef9f40529fb2c79361bc6b53d2a92 \ - --hash=sha256:e621fb7c8dc147419b28e1702f58a0177ff8308a76fa295c71f3e7827849f5d9 \ - --hash=sha256:e71dcecaa113eebcc96622c17692672c2d104b1d71ddf7adeda90da7ddeb26fc \ - --hash=sha256:e7ce83654d1ab701cb619285a18a8e5a889c1216d746ddc710c914ca5fd71022 \ - --hash=sha256:e8c8cb2deba42f5ec1ede46374e990f8adc5e6456a57ac1a261b19be6f28e4e6 \ - --hash=sha256:ec0c608b7a7465ffadb344ed7c987ff2f11ee03f6a130b569aa74d8a70e8333c \ - --hash=sha256:ec6f5674c5dc836994f50f1186dd1fafde4be0666aae201ae2fcc3d29d8adf27 \ - --hash=sha256:edb1b1b3a5576c56f08ac46f108c40333f222ebfd5cf63afdfa3aab0791ebe5b \ - --hash=sha256:ef77bdde9c9eba3f7fa5b58084b29bbcc74bcf55fdbeaa67c102a35b5bd7e7cc \ - --hash=sha256:f2791948f7c70bb9335a9102df45e93d428f4b8128020d85920223925d73b9e1 \ - --hash=sha256:f467cb602f03fbd1ab1908f68b53c649ce393fde056628dc8c7e634dab6bfc07 \ - --hash=sha256:f8ed9a5d4612df9d4de15878f0bc6aa7a268afbe5af21a3fdd97fa19516e978c \ - --hash=sha256:fa539be029844c0ce1114762d2952ab6cfdd7c7c9bd72e0db26b94c3c36dcc5a \ - --hash=sha256:fb1c4ff62277d87a7335f2c1ea4e0387b8f2b3ad88a64efd9943906aafad4f33 \ - --hash=sha256:fb4db2f17e6484904f986c5a657cec85574c76b5c5e61c7aae9ffa1bc6224f95 \ - --hash=sha256:fb66e5245db9652abd7196ace599b04d9c0e4aa7c8f0e2803938377835780081 \ - --hash=sha256:fc48c500838be6882b32748f60a15229d2dea96e59ef341eaa96ec83538f498d \ - --hash=sha256:fcf26c3c6d0da98fada8ae4ef0aa1c3405a431c0a77eb17306d38a89b02adcd7 \ - --hash=sha256:fd0ce43e71d825b7c0661f9c54d4d74bd97c56c3fd102a8985bcfea48236bacb \ - --hash=sha256:fd63453f10d29097cc3dc62d070746523973fb5aa1c66d25f8558bebd47fed61 +regex==2026.5.9 \ + --hash=sha256:002205cafd2a9e78c6290c7d1df277bf3277b3b7a30e0b4bb0dac2e2e3f7cb2d \ + --hash=sha256:01f0f5f55f4b64dacec85dc116d3c05fd23ad3ff037bbc73a2085775953c2611 \ + --hash=sha256:01f28d868834624c934b8d2e0aa1c8341337e37831f4a012f18a5afcba4cbaf3 \ + --hash=sha256:075160bf16658e16d35233300b8453aac25de4cbea808d22348b6979668e924d \ + --hash=sha256:0de5cf193997384ed2ca6f1cd4f78055b255d93d82d5a8cd6ba0d11c10b167e4 \ + --hash=sha256:0e1b1b4e496afbb24f4a62aba855ee4f88f25578927697b340702e48c9ee6bc2 \ + --hash=sha256:0f03aa6898aaaac4592479821df16e68e8d0e29e903e65d8f2dfb2f19028a989 \ + --hash=sha256:0f9eede6a5cbdc02d4978090186390936e1776a7d1359b21e41014c609880bcf \ + --hash=sha256:1268eddd8486dc561d08eee1156e40aa3a8fe10f4bdec8fa653b455fcbffd12c \ + --hash=sha256:15ee42209947f4ca045412eae98416317238163618ace2a8e54f99586a466733 \ + --hash=sha256:164eba9b755ea6f244b0d881196fbc1fac09714e9782c9e2732b813142033c8e \ + --hash=sha256:19c16ceb4a267a8789e25733e583983eeab9f0f8664e66b0bd1c5d21f14c2d4b \ + --hash=sha256:1bd7587a2948b4085195d5a3374eaf4a425dc3e55784c038175355ecf3bbbf8a \ + --hash=sha256:1e6da47d679b7010ef27556b6e0f99771b744936db1792a10ceac6547ae1503e \ + --hash=sha256:205109e96b3cf5adf8f4cd62bedde9487feb282b9497a3535451e5a24cd706a0 \ + --hash=sha256:2099f7e7ff7b6aa3192312650a56e91cc091e49d50b04e4f6f8b6e28b3b27f1c \ + --hash=sha256:246de9d60aa3f8538b519834dd95cbf276ea263d6a7bd5a3666dc3fa0230505b \ + --hash=sha256:24b2355ef5cc9aa5b8f07d17704face1c166fdcc2290fa7bd6e6c925655a8346 \ + --hash=sha256:2a661a7d270a61f7cf460caee8b9fa2d5ef9e5c681234bcb9e0fe14f488e7dfc \ + --hash=sha256:2acfb48634f64996b57f90f39afa692ff362162722581921fe92239a59960f3c \ + --hash=sha256:2efa205e6d98b24d1f3ab395c11aa15cdf10935bca283d0285e0499c284fba21 \ + --hash=sha256:31037c82eccb44b7ea2e9e221d7c01429430e989a1f4b91ea5a855f6017b509a \ + --hash=sha256:3527bb4942d2c14552155406cdedd906567456821848aed1cb4933a391bf5eca \ + --hash=sha256:39617fb0cde9c0e6306dc70e3bfc096f3da793219879f7ae7aa341a69fbdcf6d \ + --hash=sha256:398c521292f4c7fb807001dcd54694d3a1fcafc179a36ad9cc56f98df85930b6 \ + --hash=sha256:3b1e39888c5e0c7d92cea4fc777396c4a90363b05de75d02eb459a4752200808 \ + --hash=sha256:3dd4a3ff360dfb836fecdb93a4598f9d6e2ac81e3e397125145c6221bf58cf4c \ + --hash=sha256:3ddd90103f9e5c471c49c7852ecc1fe27c7e45eb99e977aefe7caa4e779f4f58 \ + --hash=sha256:446ddd671e43ab535810c4b21cff7104945c701d4a14d1e6d1cd6f4e445a8bea \ + --hash=sha256:45375819235558a4ff1c4971dc32881f022613abdb180128f5cb4768c1765a1c \ + --hash=sha256:46f1326ca6e65b0879d23ca302c0f2415aad42ff0309b9c818e7949fe19a41d8 \ + --hash=sha256:48036f6374aaa79eb3b754ec29c61d1c6b1606749d705a13f8854fa2539671f6 \ + --hash=sha256:4ebe8f0b5ec5a5024dc4a4c59f444c4e9afc5f2abdbb8962065b75d27fb971f9 \ + --hash=sha256:4eeb011098fcb77af513dcef521a3dbecbf8849b1e38940759d293b7a93f5026 \ + --hash=sha256:508f56a89ba9cb26e4168cbc37dbd60a28d82430a9e18ad1d25fe0883c314ca2 \ + --hash=sha256:5604dfd046dc37eca90250fc3be938b076c8059fa772ac0ed6f499b0f0fb0415 \ + --hash=sha256:56a33f191f17d8c417f99945ebdc1e691d3af9605d86ec68c7e54a57e3e17af6 \ + --hash=sha256:57e8915c7986aa33d25e4d3629cef711cd2863f2961b10409f0c04cb8b7d9020 \ + --hash=sha256:57eeeb05db7979413dec5438f2db21d7ecbba787cde7a711df1a6f6df672aa06 \ + --hash=sha256:5b73ab8afcf66c622db143d1c6fda4e58e4d537ee4f125229ad47b1ab80f34c0 \ + --hash=sha256:5e41809d2683fcde7d5a8c87a6567ba1fb1ce0de9f31bff578de00a4b2d76daa \ + --hash=sha256:6351571c8a42b505eb555c0dc47d740d0fb66977dc142919eea6f4325b7c56a0 \ + --hash=sha256:6441cc660d76107934a09c22167200839a0e89604a6297f78a974e66e931d2c0 \ + --hash=sha256:65c8c8c37377794bd5b2f3ebe51919042bf17aec802e23c833d89782ed0c78af \ + --hash=sha256:6ba42b2e7e7f46cf68cc6a5ca36fa07959f9bbd9c6bdcc47b6ee76549a590248 \ + --hash=sha256:71b61c5bfe1c806332defc42ad6c780b3c55f661986d7f40283a3a88274b4c00 \ + --hash=sha256:728d8bfd28a8845c8b6bc5dc7ce010453d206396786c0765c2740cb65f37791e \ + --hash=sha256:7b92817338591505f282cf3864c145244b1edcf5381d237038df955001091538 \ + --hash=sha256:7e30b874d341fac767d7df5a0870540541c2c054b80cfaac116e8d367a8a7ff2 \ + --hash=sha256:7e87577720152d2caae19fe2baaf1f8d5ca12091e9e229f03915c37d1e4b9178 \ + --hash=sha256:83d0ee4a57d1c87cb549e195ec300b8f0ec3a82eba66d835e4e2ed8634fe4499 \ + --hash=sha256:8676474c07469d6f33dd1085ca2cd45f65785f32518f2b20e36d9953ca07f994 \ + --hash=sha256:86f40a5d6444db30a125c9c9177e6b25dad981cbc37451fd838f145e6edac92e \ + --hash=sha256:872acc074bd29ffc9913ecdfedf6ea77502312ca44a4aa0d3779089c6069d8de \ + --hash=sha256:8abd33fef90b2a9efac5557d6033ca82d1195ed3a15fea5af15ba7b463c6a63b \ + --hash=sha256:8c6e4218fbdfbcd4f6c19efca40930d24a621bf4b48cb76bc6640543bd28ef20 \ + --hash=sha256:8e76e8161ad00694cfce6767d5dea860c6391ac5b83e5c3a39661e696f11fc7e \ + --hash=sha256:8f3af7a4903c5c04a11a196a5aa75cdd7dd3f8508132f9fb3259d9f5908e3b88 \ + --hash=sha256:91328f1c23d47595ca3ef0a7557fa129c5a23404b775c770697d2f35b33e0107 \ + --hash=sha256:916714069da19329ef7de197dcbc77bb3104145c7c2c864dbfbe318f46b88b14 \ + --hash=sha256:93a7860539414dddaefba2b40f8771765ae17949d4c7182b876ce429e11a8309 \ + --hash=sha256:954cc214c04663ee6d266fc61739cad83054683048de65c5bd1d640ad28098ac \ + --hash=sha256:96f5f58b54a063d7ea9dca08e1cf57bfe10499c4d579ee672da284f57f5f0070 \ + --hash=sha256:97cf3bc1b7d7d2306772ec07366c80d9df00ff79e79cea32898883a646d2fae2 \ + --hash=sha256:98bd73080e8756255137e1bd3f3f00295bbc5aa383c0e0f973920e9134d7c4ad \ + --hash=sha256:992604d02e6d9c6d786c24a706a71ecffe1020fc1ef264044474cd81fa2c3919 \ + --hash=sha256:a24852d3c29ad9e47593593d8a247c44ccc3d0548ef12c822d6ed0810affe676 \ + --hash=sha256:a6a563446a41adc451393dc6b8e6ad87979efaee3c8738690a8d1b08ebead1b4 \ + --hash=sha256:a8234aa23ec39894bfe4a3f1b85616a7032481964a13ac6fc9f10de4f6fca270 \ + --hash=sha256:a8820737949116ffff55fe18f9fc644530063ba6ebfcb8314239416e78f1347c \ + --hash=sha256:a9e1328e17c84c1a5d22ec9f785ecef4a967fab9a42b6a8dc3bcbebd0a0c9e44 \ + --hash=sha256:aa0fbdbac82cb3e4450d0ccde7d7a35607f4cb2dd9fba4b8b69bfaf8c9fa6aed \ + --hash=sha256:b310768746dd314ea6e2ff4cc89ef215426813396ff4e94ee8e6f7096c8b6e03 \ + --hash=sha256:b46b0f094dc1d3b90356c85a0bd2c9bafc4a6a190b9d6f8ddd5a033b6e088ed4 \ + --hash=sha256:b4bb445ff3f725f59df8f6014edb547ee928ec7023a774f6a39a3f953038cbb2 \ + --hash=sha256:b6d189041f15691cfa2b6c4290448ec221244d225b3f5fe9e7771b34ffcdf6e2 \ + --hash=sha256:b96350aa424e79d4fd6b567b344dcbe2b2d6bfc48dfe7717587e1fa6d43da6ff \ + --hash=sha256:be3372b9df6ddecff6486d37e19095a7b4973137caf5512407a89f4455361f41 \ + --hash=sha256:bfe1ce50cbfb569d74e1e4337da6468961f31dbea55fd85aa5de59c0947a805a \ + --hash=sha256:c010eb8caca74bdb40c07498d7ece26b4428fd3f04aa8a72c9ac6f79e8faaac6 \ + --hash=sha256:c8b9b9d294cfea3cd19c718ade7cc93492b2c4991abd9a68d0b3477ae6d8e100 \ + --hash=sha256:c9411dd64ca95477225734a93dfc8583b51916b8d5942f99d6cac21e09965451 \ + --hash=sha256:ca518ed29c46eecba6010b15f1b9a479314d2de409536e71b6a13aa04e3b8a77 \ + --hash=sha256:ccf5249114cc3e772ecdd88a98a86eca0fd74c61ce32a94743758c083fc05d48 \ + --hash=sha256:cd2846168eb9ee3c513902bc8225409cb1caab31d04728b145171fa1625d9621 \ + --hash=sha256:d29eebfc9525db68cad3c97eedd7f754fa265aa5cd0cf4f863b2421e1b48fc9f \ + --hash=sha256:d3d7eb5c9a7f6df82ed3cfac9beb93882a5cbcb5b8b157b56cb2b3b276574ac1 \ + --hash=sha256:d626b84406444b165fc0ba981604edea39f0588ff1f92baa23fe50799ea9afdb \ + --hash=sha256:d641a8c9a61618047796d572a39a79b26167b0411d2c3031937b2fe2d081e2cf \ + --hash=sha256:d659eee77986549c9ea45b861c7567e44d6287c3dc9a4565478853f7b9fe2ff6 \ + --hash=sha256:d6b8a143aca6c39b446ea8092cde25cc8fe9304d4f5fecfbc1a9dbb0282703c2 \ + --hash=sha256:d726ca3f0d76969bf1e8e477d160d3d666bbf999f6860bd314889e5345782046 \ + --hash=sha256:d7bdc0ab8f3dd7e1b4f9ab88634e13374669db86bb3c72e8292f07ae313f539f \ + --hash=sha256:daff2bdbaf1d23e52fdff7c0b7bc2048b68f978df6a4d107ac981f94caef2e66 \ + --hash=sha256:dd2810d22146b6d838acc5ec15602cb6b47920aa4e33015df3868eedfd20bab8 \ + --hash=sha256:ddda5340e6c01a293027dd46232fa79eaff1b48058ce7a98f572b6445b088041 \ + --hash=sha256:dea2e88e1cce4522496cce630e11e67b98b7076620bc4336c3f674bc21a375f4 \ + --hash=sha256:debb893095e944091c16e641a6e33c1b0f4cb61ab945ec5afbf53ce7068834d8 \ + --hash=sha256:dfbe4579b9f08036aa7d101d1835437a20783574ac66327e6b29b4018a138081 \ + --hash=sha256:e1d93bf647916292e8edcec150c07ddf3dc50179ccaf770c04a7f9e452155372 \ + --hash=sha256:e82db382b44d0111b22601c509c89f64434816c9e0eef9d1989cda8cc6ff1c04 \ + --hash=sha256:ea9c8ecfa1b73c73b626534d6626e5340d429630943672b8480724f44e84b962 \ + --hash=sha256:ead4b163ac30a29574510cd4b3e2e985ac5290c05fc7095557d6a5f403fc31b5 \ + --hash=sha256:ecd353045824e4477562a2ac718c25799cdaaa41f7aa925a806a8a3e6848a5b9 \ + --hash=sha256:ed2c9e8068b614c574d8d30e543d617cf5379b0535d46f97ef00e904745a08b5 \ + --hash=sha256:ed457d8e98ae812ed7732bef7bf78de78e834eae0372a74e23ca90ef21d910f9 \ + --hash=sha256:ef31cbfe458e21c6122ba8150ff060e0c7789ed0d26eb423f25472584920b555 \ + --hash=sha256:f079e50a0d3cc3cd5091fa9ff45869a2e6b2cd35895731edafb0327901a8d86d \ + --hash=sha256:f3844f134e834076677dd369976e9f5068679fcb8e50102fdf6b7ac96a3ec127 \ + --hash=sha256:f7a7c26137296beba7784de6eba69c6a93a63ccebc385e4962fe67e267a91225 \ + --hash=sha256:fa411799ca8da32a8d38d020a88faa5b6f91657d284761352940ecf9f7c3bbdd \ + --hash=sha256:fd03c4f0e33280d15cae17159b899245d6b7c53d21def19b263b39655061f5ce \ + --hash=sha256:fd190e88a895a8901325fad284a3f74ea52b1da8525b76cc811fa9b1edf0ce2b \ + --hash=sha256:ff8d372ac2acdc048d1c19916f27ee61bc5722728458ba6ca5052f2c72d51763 # via # feast (pyproject.toml) # parsimonious # transformers -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # azure-core + # databricks-sdk # datasets # docker # docling @@ -4879,10 +5492,13 @@ requests==2.32.5 \ # great-expectations # huggingface-hub # jupyterlab-server + # kube-authkit # kubernetes + # mlflow-skinny # moto # msal # openlineage-python + # pymilvus # python-keycloak # ray # requests-oauthlib @@ -4903,9 +5519,9 @@ requests-toolbelt==1.0.0 \ --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \ --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 # via python-keycloak -responses==0.26.0 \ - --hash=sha256:03ec4409088cd5c66b71ecbbbd27fe2c58ddfad801c66203457b3e6a04868c37 \ - --hash=sha256:c7f6923e6343ef3682816ba421c006626777893cb0d5e1434f674b649bac9eb4 +responses==0.26.1 \ + --hash=sha256:2eb3218553cc8f79b57d257bac23af5e1bf381f5b9390b1767816f0843e01dc2 \ + --hash=sha256:8aacc4586eb08fb2208ef64a9eb4258d9b0c6e6f4260845f2f018ab847495345 # via moto rfc3339-validator==0.1.4 \ --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ @@ -4923,137 +5539,148 @@ rfc3987-syntax==1.1.0 \ --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d # via jsonschema -rich==13.9.4 \ - --hash=sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098 \ - --hash=sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90 +rich==14.3.4 \ + --hash=sha256:07e7adb4690f68864777b1450859253bed81a99a31ac321ac1817b2313558952 \ + --hash=sha256:817e02727f2b25b40ef56f5aa2217f400c8489f79ca8f46ea2b70dd5e14558a9 # via # codeflare-sdk # fastapi-mcp # ibis-framework # typer -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth rtree==1.4.1 \ --hash=sha256:12de4578f1b3381a93a655846900be4e3d5f4cd5e306b8b00aa77c1121dc7e8c \ --hash=sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0 \ @@ -5071,29 +5698,29 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.5 \ - --hash=sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752 \ - --hash=sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681 \ - --hash=sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204 \ - --hash=sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c \ - --hash=sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd \ - --hash=sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080 \ - --hash=sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74 \ - --hash=sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2 \ - --hash=sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe \ - --hash=sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010 \ - --hash=sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8 \ - --hash=sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca \ - --hash=sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2 \ - --hash=sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b \ - --hash=sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65 \ - --hash=sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a \ - --hash=sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d \ - --hash=sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440 +ruff==0.15.16 \ + --hash=sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a \ + --hash=sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3 \ + --hash=sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071 \ + --hash=sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec \ + --hash=sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628 \ + --hash=sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8 \ + --hash=sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e \ + --hash=sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2 \ + --hash=sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb \ + --hash=sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123 \ + --hash=sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121 \ + --hash=sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951 \ + --hash=sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf \ + --hash=sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb \ + --hash=sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d \ + --hash=sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78 \ + --hash=sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a \ + --hash=sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4 # via feast (pyproject.toml) -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 safetensors[torch]==0.7.0 \ --hash=sha256:0071bffba4150c2f46cae1432d31995d77acfd9f8db598b5d1a2ce67e8440ad2 \ @@ -5175,45 +5802,43 @@ scikit-image==0.26.0 \ --hash=sha256:f775f0e420faac9c2aa6757135f4eb468fb7b70e0b67fa77a5e79be3c30ee331 \ --hash=sha256:fac96a1f9b06cd771cbbb3cd96c5332f36d4efd839b1d8b053f79e5887acde62 # via easyocr -scikit-learn==1.8.0 \ - --hash=sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2 \ - --hash=sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a \ - --hash=sha256:146b4d36f800c013d267b29168813f7a03a43ecd2895d04861f1240b564421da \ - --hash=sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9 \ - --hash=sha256:2838551e011a64e3053ad7618dda9310175f7515f1742fa2d756f7c874c05961 \ - --hash=sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6 \ - --hash=sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271 \ - --hash=sha256:35c007dedb2ffe38fe3ee7d201ebac4a2deccd2408e8621d53067733e3c74809 \ - --hash=sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242 \ - --hash=sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4 \ - --hash=sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7 \ - --hash=sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76 \ - --hash=sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6 \ - --hash=sha256:5e30adb87f0cc81c7690a84f7932dd66be5bac57cfe16b91cb9151683a4a2d3b \ - --hash=sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e \ - --hash=sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7 \ - --hash=sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e \ - --hash=sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57 \ - --hash=sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735 \ - --hash=sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb \ - --hash=sha256:8c497fff237d7b4e07e9ef1a640887fa4fb765647f86fbe00f969ff6280ce2bb \ - --hash=sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e \ - --hash=sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd \ - --hash=sha256:a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a \ - --hash=sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9 \ - --hash=sha256:ada8121bcb4dac28d930febc791a69f7cb1673c8495e5eee274190b73a4559c1 \ - --hash=sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde \ - --hash=sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3 \ - --hash=sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f \ - --hash=sha256:c57b1b610bd1f40ba43970e11ce62821c2e6569e4d74023db19c6b26f246cb3b \ - --hash=sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3 \ - --hash=sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e \ - --hash=sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702 \ - --hash=sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c \ - --hash=sha256:f984ca4b14914e6b4094c5d52a32ea16b49832c03bd17a110f004db3c223e8e1 \ - --hash=sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4 \ - --hash=sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd - # via feast (pyproject.toml) +scikit-learn==1.9.0 \ + --hash=sha256:051075bda8b7aab87b1906ab3d4740a1e1224a19d7b3781a576736edc94e76aa \ + --hash=sha256:056c92bb67ad4c28463c2f2653d9701449201e7e7a9e94e321be0f71c4fef2b8 \ + --hash=sha256:147e9329ef0e39f75d4cffa02b2aa48d827832684926cd5210d9a2cb5c57246b \ + --hash=sha256:1b944b6db288f6b926e3650026ddafb988929de95d11fc2cc5fa117773c9ba42 \ + --hash=sha256:1fea2cc5677ab49d6f5bade978c866da44957b712d92e9635e8b4f723013c3cb \ + --hash=sha256:24360002ae845e7866522b0a5bbf690802e7bc388cac8663502e78aa98598aa2 \ + --hash=sha256:26e22435f63bcdcf396b574273f29f13dd531f5ea035801f5be10ba1540a4e60 \ + --hash=sha256:2bd41b0d201bc81575531b96b713d3eb5e5f50fb0b82101ff0f92294fdc236ac \ + --hash=sha256:366652351f092b219c248f1e72821e841960a63d8f358f1dcfd54dc1cbdbbc28 \ + --hash=sha256:38c3dcb9a1ffb85505ec53d54c7b4aea0cff70050425a7760c2af661ac85df05 \ + --hash=sha256:4306775fad04cc4b472a1b15af1ae9cede1540fbfcc17fbce3767cd8dc7ae283 \ + --hash=sha256:4ccacf04ca5f4b492158a5f28afe0ace43f81b2571e4b9a66d34848b46128949 \ + --hash=sha256:5162ad10a418c8a282dde04c9aa06965de3e9a65f33c1440c0ae69bb1a09d913 \ + --hash=sha256:5808d98f15c6bf6d9d96d2348c1997392a5888ce7097e664105f930c4bca1277 \ + --hash=sha256:5b934c45c252844a91d69fda3a34cff5e7307e1db10d77cb10a3980312c74713 \ + --hash=sha256:5bad8f8b9950321b54c965fdcbac6c6c55e79e16646b49977bcf3668d3870a1a \ + --hash=sha256:5be45aa4a42a68a533913a6ed736cf309de2226411c79ef8d609a5456f1939b1 \ + --hash=sha256:5dc1818c77575d149e25fce9ef82dd7b7263ae372f03494158668ad632a69759 \ + --hash=sha256:5e50ed4da51974e86e940690e9a3d82e729b62b5a49f7c9bac534d515d39d86f \ + --hash=sha256:64fa347efc1c839c487433e40c5144d38c336e8a2b59c81aa8660373945c2673 \ + --hash=sha256:78fc56eafd4edb9575d2d8950d1dd152061abb573341a1cb7e099fc40f6c6666 \ + --hash=sha256:80746d63bd4b6eaca54d36fe5feaf4d28bb38dc6f9470f81c7cad7c40155f119 \ + --hash=sha256:8833266989d3a5110178a9fae30783675460724d0e1efb13b14901d2c660c557 \ + --hash=sha256:9656acd4e93f74e0b66c8a36c88830a99252dfa900044d36bc2212ae89a47162 \ + --hash=sha256:9db6f4d34e68c8899e4cab27fdf8eafe6ed21f2ba52ceb25ea250cd237f8e47b \ + --hash=sha256:d77f54c017633791bc0225a43e2f8d03745fdcfe4880268fcc4df15f505dec2e \ + --hash=sha256:da76d09304a4706db7cc1e3ebaa3b6b98a67365cc11d2996c4f1e58ba47df714 \ + --hash=sha256:ee1a8db2c18c08e34c7412d4b10be1cac214cd4ea7dc9715a6a327eb49a37c96 \ + --hash=sha256:f401448645a3e7bc115aa3c094097865155b34bff1cba8101857d9104e99074c \ + --hash=sha256:f7e254636164090da847715a27f8e5478feb98c40a9e0ee90cbd277de9e5ceb8 \ + --hash=sha256:fd3a8ef0c758555a3b23c03adaa858af32f7736785ded50ad5991f59c4ed03fa + # via + # feast (pyproject.toml) + # mlflow + # sentence-transformers + # skops scipy==1.17.1 \ --hash=sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0 \ --hash=sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458 \ @@ -5280,8 +5905,11 @@ scipy==1.17.1 \ # docling # easyocr # great-expectations + # mlflow # scikit-image # scikit-learn + # sentence-transformers + # skops semchunk==3.2.5 \ --hash=sha256:ee15e9a06a69a411937dd8fcf0a25d7ef389c5195863140436872a02c95b0218 \ --hash=sha256:fd09cc5f380bd010b8ca773bd81893f7eaf11d37dd8362a83d46cedaf5dae076 @@ -5290,6 +5918,10 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server +sentence-transformers==5.5.1 \ + --hash=sha256:02b7740dfc60bdbbcb6061625f5d97a5c1a4e2d3baac5f9391b912bb5eae2290 \ + --hash=sha256:4fe11d433badc5282d32f7fc08bc714216b7a5aca426f9df77a45a554756deb7 + # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ --hash=sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173 @@ -5301,8 +5933,8 @@ setuptools==80.10.2 \ # pbr # pip-tools # pydata-google-auth - # pymilvus # singlestoredb + # torch shapely==2.1.2 \ --hash=sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9 \ --hash=sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b \ @@ -5387,10 +6019,18 @@ six==1.17.0 \ # python-dateutil # rfc3339-validator # thriftpy2 -smart-open==7.5.1 \ - --hash=sha256:3e07cbbd9c8a908bcb8e25d48becf1a5cbb4886fa975e9f34c672ed171df2318 \ - --hash=sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7 +skops==0.14.0 \ + --hash=sha256:60a5db78a9db46ccee2139a0ba13ab5afb1c96f4749b382e75a371291bbe3e36 \ + --hash=sha256:6c8c0e047f691a3a582c3258943eecafcbfd79c8c7eef66260f3703e363254f0 + # via mlflow +smart-open==7.6.1 \ + --hash=sha256:4347996e7ba21db7cd1e059632e0b30395407e4f6c660d2ddffc8f2a9ae5f990 \ + --hash=sha256:b4de6aebef023aca91cc9fb372052e1343ba3f152de215bd22391a663e3ddd21 # via ray +smmap==5.0.3 \ + --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ + --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f + # via gitdb sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc @@ -5398,45 +6038,45 @@ sniffio==1.3.1 \ # elastic-transport # elasticsearch # httpx -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.0.0 \ - --hash=sha256:0c0204f639fddc58452b0362ba8821cd5153bd7aaa89434d59104bc39f4fa176 \ - --hash=sha256:1ca2503f705627f7e045da6254d97c37210a3b0a18b43d0f1b29616d0c7aaa01 \ - --hash=sha256:1fea301e3d1e8022b9f2ff87dc3be139d5ed7be5e85fab8a6c59d400a02e6d58 \ - --hash=sha256:2c3e0f6d103fe67c975550ed424f579d3e7ae503d56467e5549f3a1a1e0e8f24 \ - --hash=sha256:4106a66e770e564b3037457b7b01b15ca28aee61afb88560b664aa8af439b533 \ - --hash=sha256:4b10a865c4a5e1fa60c365c7fe41e0433605e6e5edc824e8730a9038f330b3a6 \ - --hash=sha256:4e8c3d2ea4055dd4aecc93514030341e300f557f2e86ca21eb47568c461a6f56 \ - --hash=sha256:54e648bbd506a0f2f8076f9eafe231b2d4284b1a884528c3a0690391ab2bb54e \ - --hash=sha256:5ad5d0f1ebcb2c6b7a7859ee3d4e02203087e40faae539a336bbcb45a3660777 \ - --hash=sha256:65e4e36dd1b0c7235d84cddef8a3c97c5ea0dc8fea85e31e45fc485000b77a83 \ - --hash=sha256:7789df78f7c7abfb351f2709258d05a94652cfe3c2c617fb15f15a11fc1b7b25 \ - --hash=sha256:79b4e7a58e600419f083a63f99e5da89d438faddae1d344e9f9b003754fa231b \ - --hash=sha256:835161dd46ef8f5fc9d2f135ca654c2f3fbdf57b035d3e1980506aa8eac671dc \ - --hash=sha256:985cd2f8b6b2e663ef30dc59f1ba8c1becff7683ebc51bd7f14b962407a9fa88 \ - --hash=sha256:a790f06808e4481c23cfed1396d2c9a786060ddd62408b1fda1a63e1e6bc4b07 \ - --hash=sha256:af89a9e1355ea4dac7927d2f9bc15b2c81e381ad8bcdf8954ba3dd457a4d51d6 \ - --hash=sha256:b95b29589293ad14d0367428518141995524cfc7dc47d8f3d0c47010f5d974da \ - --hash=sha256:bfd3b8523d7adc830f99c5c4c635689ceca61700a05368d5bbb34c6811f2ec54 \ - --hash=sha256:cd23bff2abc74e34c6123a181c004ead9e6cc8ef2661250892afd64bad24533c \ - --hash=sha256:e376bad497c7932448cc29058e75737f02b3f0e25569de9e4ff0616944b4ceba \ - --hash=sha256:e6132986d6965e4005b0167270612fbc7fa4bc4ef42726a40b85a8f57475a78d \ - --hash=sha256:e8d5b66f283967c700fff2303ac5e52d1a3cf41990a634f121ac8b1f1cd9af10 \ - --hash=sha256:eb1bb9729fd3bfaae22364491cec4816dda380376ac3be4559a6f6949c6d2833 \ - --hash=sha256:ebbdeec0d65c2e3f648c8b05839001c062984959417902717f7fc6eed983211d \ - --hash=sha256:f67d844241a6fed764a8f04d32c0273aedf9159d5162b764748526277c7f8831 \ - --hash=sha256:fd0d2d2c5cfd15f041e8522f5f8bdad0be4de7d805dd1646377fccd6bd404fa8 +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -soupsieve==2.8.3 \ - --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ - --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 +soupsieve==2.8.4 \ + --hash=sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e \ + --hash=sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65 # via beautifulsoup4 sphinx==6.2.1 \ --hash=sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b \ @@ -5466,77 +6106,98 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb - # via feast (pyproject.toml) -sqlglot[rs]==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb + # via + # feast (pyproject.toml) + # alembic + # mlflow +sqlglot[rs]==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via # feast (pyproject.toml) # ibis-framework +sqlglotc==30.9.0 \ + --hash=sha256:197f30830a4c40d39655e9d97c91b179dcd1c88635d34d5281a15536cb04030e \ + --hash=sha256:3f132418f0facde6319611dbaf4d47b6f8a7ca37527cda5337f7253ddbd0f62d \ + --hash=sha256:45e65c77a2a3887934d16421db019a1081403ddc4d2ec359d61971d0ace8f48a \ + --hash=sha256:46f004fda92af8676577171e2172892aced1ec7baa1388b26b25be37e980164f \ + --hash=sha256:54788de9eac748135afc322e0385a040296fb6e35fabd213f3387e09821eab50 \ + --hash=sha256:65a84bc3cca32acef23f3b7366cd85eece18536eac41bd364a87d64fcee97470 \ + --hash=sha256:7848eb58afdf74e056cf3fbbc8ea4c70b94e6a106d967c7abc628ed8f2acefc8 \ + --hash=sha256:8060a9446768b810d4f89e1263b04ffdacc67a2c1711aa4af9e7d22be4ac59ed \ + --hash=sha256:88c98db55e0f673f4bd80f2662a07bc234e9a37d321a1044ca6ff2f3598d42db \ + --hash=sha256:955c58c5fe0b555304fed58c5bf960a27211cfba2fb0ff0ead6a8253a35b6e17 \ + --hash=sha256:ab1763090f60581bdabf304c86ef465d3b019244c0b7610db15562bb52688d70 \ + --hash=sha256:b7d8aff3f33f2930dbdc6b7de875d3c22414528755631f3183d1e982fd7ae255 \ + --hash=sha256:c4879678e5bca435245951669ce8790651e9806760fbbbe48772440c9f392b43 \ + --hash=sha256:d57133358daec2003a86f533ca5c38306680cdc60d71e3d25174b182da667b45 \ + --hash=sha256:d98f26796bc4ab5f0fc2c9ac5eae9dc6ca2d8793abcdffab0a3f8937f9d27ff0 \ + --hash=sha256:e1829f6d77b1de1c7481ea289ee1615c1ca9e37149cbd20663742bd42f1cfe2a \ + --hash=sha256:e1c79d46e1733a53c97a78fea76cad6e45e922058afa948e60b796b3546182a3 \ + --hash=sha256:ee104e4781b4ee656c7461056e8a1ca34dcd0256ade5db5bb8d5eaf4b470ac12 \ + --hash=sha256:f932992dea9fbdf797cc40da1752e2df423867d0e5de98663f0136822224293e \ + --hash=sha256:faa3ec4c15894d70341390db2a0b890c92f57c79a0398f7f954f345aea59060a \ + --hash=sha256:fcea2b7d0dca702f2c0f0af41da8552c39a749f2e63d66757c947f97344ab11f + # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ --hash=sha256:ad1ad158234af0f8ba5054ca51bd17a7c1e3f81b4798c7970ebf7953fe08ddcb @@ -5552,20 +6213,26 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sqlparse==0.5.5 \ + --hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \ + --hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e + # via mlflow-skinny +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 # via ipython -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp + # mlflow-skinny # sse-starlette sympy==1.14.0 \ --hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \ @@ -5588,9 +6255,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc3 \ + --hash=sha256:2a9dad9a10ef1aff91c3df43b7387768ed16616d83bc591b92cefd54d3426faf \ + --hash=sha256:9e8a1ca7b15d3cbd907dec45d5823f512a01b67cc22d9db6af86fa41b47e561b # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -5605,14 +6272,18 @@ thriftpy2==0.6.0 \ --hash=sha256:1245c36b82f34aa26f049e6529f40ad34d9be8d12bd0131559847c8476b98ce0 \ --hash=sha256:151d299e8e3694a6cc0f2f2cda01d5744080742649de958c5cdcbebb4306205f \ --hash=sha256:16eecfd34bd541b75172ba0d69ea90b874611a7361d18906fb6d95955089cc30 \ + --hash=sha256:182f54a7248c8ecf1320cf26d1fc9115765df6b1f2589c1d2d0df7049a5b27d4 \ --hash=sha256:210345281d41b3a76d263b555d3e3cc482103738441bdb92a73033a4e9a042e1 \ --hash=sha256:265588b8cdb3fe1097db43bf35fb208edc69d9350a2bec3a737d6357d0a5650d \ --hash=sha256:28fd55960a6d42207060536109928a4615fbbd6874c0ddd8a705b47075f1d2d0 \ --hash=sha256:29ff125e40c8016b4d3bf48e6d727bd93d2892451b47bfe57ba896944ecbdb0c \ --hash=sha256:2ae866adf9b112c7ab30c1a90d878a5d6f2d40244fbc46ec8477425d802f4ac5 \ --hash=sha256:2bf891c2d441b1edddfc62f16ab3031ac7506cba5b77680654179dbe93d8b7ec \ + --hash=sha256:2c88b0d356ea18ce026a52aa7c2110693db77fd52d5ac7553616635a7f165bbd \ --hash=sha256:3090d9cabc2c31c92ae943f36d539a20adfd82697f50e996ce94f0b279e9e1e4 \ + --hash=sha256:3359a7c4eb4c281bf54bd760dcc03c43299f0d529dd2a5018be2f1fbebf0cbbd \ --hash=sha256:375cca06f36f54339838c7f8251b64a777d5ff1277f8b91999487fad1a8e2d73 \ + --hash=sha256:386d8c4a5677fd94fd16c1af2adf39f59698af1e4ef0c3c026083f278540e352 \ --hash=sha256:44365bb5098d0a91c44382e7df0ad44d5b9a588d29d9071aca4a2867f704aaf1 \ --hash=sha256:443e502b428d325c57aec0947991857e8dc0589d0464181f35bd48f870cd5d18 \ --hash=sha256:4550cbb6629c9f6186ab22cb497f262408e1a90ae10b8653599f2717f518f0df \ @@ -5629,6 +6300,7 @@ thriftpy2==0.6.0 \ --hash=sha256:851981ded8bb42da66213cf95d1dd5eaf06c5d6b3a95725a18eddd58ec992b6b \ --hash=sha256:852e538b4866ed776126349161d9fdc37387b1e15ab46805f98dcdee25fee4b5 \ --hash=sha256:8b19d19661fc9a71f19b7c432c413ab65025e5dd11fbd192bd9169afb13b9ce0 \ + --hash=sha256:8e62d9c36bcfe6b85bec7b754accb97e2fa7b6a7c9a0c37f824d85eba699e7b8 \ --hash=sha256:8eb0566b4501c27ea51f2e593531122703946969564fe526a5ff1b18be0ad49a \ --hash=sha256:8f393607d54091e8976e297f8fd7399606d12cd8c2b8852353f07ad5ddac4224 \ --hash=sha256:91df1fa70a99ac08dc449d6fda24a14992a1836d571928f217c40c66fd63fcc8 \ @@ -5643,14 +6315,17 @@ thriftpy2==0.6.0 \ --hash=sha256:b361152c24fd5c791220de9966b00696578c9884a2bb67e4759d4dfe05fd7049 \ --hash=sha256:b51b5259dc344482ab21b768dfc7f54d51d9133665e72890831725068f69f24a \ --hash=sha256:b57f367d7b0e1bc9e5c9b0ff34febdb3fe440f1fe8d75903ae71301bc06072c0 \ + --hash=sha256:b8dc65d2e7951b7e81c17b92857db7c19d6b3dd442d2d8600b5bd5040aa43ce6 \ --hash=sha256:bc320e960347e5f9d27e8b4a9fc7044b2b26bfe4522bb4957e741fc1d1ebd2f0 \ --hash=sha256:bdf77ba7a8987a239eb57cf840d62669741f8b92b61a617e63898caed31da898 \ --hash=sha256:bf96b64400da2f411b43c4c81c2e20b09e3300d86766a52f42393696c8962f11 \ --hash=sha256:c37f5dbfe95579549485c33167854784358f559feda703ccc058719ca0efd8aa \ --hash=sha256:c41312c6edad5e875613719236f1ca6bba9310df40b1adc9308248e1bdb7a1ea \ + --hash=sha256:cafa1d43bcc69129a4855fd3973ab7983bb2274c407e5ff572af5dc196e00313 \ --hash=sha256:cb98556e919be3e6ba9bca629dbddccfaa33b95a0fe7503052849b124e4f88cd \ --hash=sha256:cd2e2c4dcc30c373e317d39b044afa6d9a090bec11d186f25841f70bc520bbb5 \ --hash=sha256:e6c4fb1e7f51f8858f348ed9c31bb408b61274942d18b549ec163bb480c987a0 \ + --hash=sha256:eccab0281667caab0c055882b3bbb8e346bb0181e55f37477e3e5e3f5b7a96dd \ --hash=sha256:f59f74c3779aa47223ba0a9e23ef10d2af5a873ed3624c78303f62a679d1b63e \ --hash=sha256:f6b86112cca7bd04151ce248d781763ea5f74cc18d148476c6d16cee32db81ac \ --hash=sha256:f837ab85ae93b118766b8b28a1cec47a1daddee303e1f986a595c56379062a5c @@ -5659,13 +6334,13 @@ tifffile==2026.3.3 \ --hash=sha256:d9a1266bed6f2ee1dd0abde2018a38b4f8b2935cb843df381d70ac4eac5458b7 \ --hash=sha256:e8be15c94273113d31ecb7aa3a39822189dd11c4967e3cc88c178f1ad2fd1170 # via scikit-image -timm==1.0.25 \ - --hash=sha256:47f59fc2754725735cc81bb83bcbfce5bec4ebd5d4bb9e69da57daa92fcfa768 \ - --hash=sha256:bef7f61dd717cb2dbbb7e326f143e13d660a47ecbd84116e6fe33732bed5c484 +timm==1.0.27 \ + --hash=sha256:315dfe63186ca9fb7ff941268941231fd5be259f2b4bb4afa28560ae1015cb9a \ + --hash=sha256:5ff07c9ddf53cbada88eab1c93ff175c64cab683b5a2fddf863bcee985926f89 # via feast (pyproject.toml) -tinycss2==1.4.0 \ - --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ - --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 +tinycss2==1.5.1 \ + --hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \ + --hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957 # via bleach tokenizers==0.22.2 \ --hash=sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113 \ @@ -5697,60 +6372,60 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via # coverage # fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -5760,94 +6435,89 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -torch==2.10.0 \ - --hash=sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574 \ - --hash=sha256:233aed0659a2503b831d8a67e9da66a62c996204c0bba4f4c442ccc0c68a3f60 \ - --hash=sha256:29b7009dba4b7a1c960260fc8ac85022c784250af43af9fb0ebafc9883782ebd \ - --hash=sha256:2b980edd8d7c0a68c4e951ee1856334a43193f98730d97408fbd148c1a933313 \ - --hash=sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547 \ - --hash=sha256:3202429f58309b9fa96a614885eace4b7995729f44beb54d3e4a47773649d382 \ - --hash=sha256:3282d9febd1e4e476630a099692b44fdc214ee9bf8ee5377732d9d9dfe5712e4 \ - --hash=sha256:35e407430795c8d3edb07a1d711c41cc1f9eaddc8b2f1cc0a165a6767a8fb73d \ - --hash=sha256:418997cb02d0a0f1497cf6a09f63166f9f5df9f3e16c8a716ab76a72127c714f \ - --hash=sha256:5276fa790a666ee8becaffff8acb711922252521b28fbce5db7db5cf9cb2026d \ - --hash=sha256:5c4d217b14741e40776dd7074d9006fd28b8a97ef5654db959d8635b2fe5f29b \ - --hash=sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf \ - --hash=sha256:6021db85958db2f07ec94e1bc77212721ba4920c12a18dc552d2ae36a3eb163f \ - --hash=sha256:6528f13d2a8593a1a412ea07a99812495bec07e9224c28b2a25c0a30c7da025c \ - --hash=sha256:682497e16bdfa6efeec8cde66531bc8d1fbbbb4d8788ec6173c089ed3cc2bfe5 \ - --hash=sha256:6b71486353fce0f9714ca0c9ef1c850a2ae766b409808acd58e9678a3edb7738 \ - --hash=sha256:6d3707a61863d1c4d6ebba7be4ca320f42b869ee657e9b2c21c736bf17000294 \ - --hash=sha256:71283a373f0ee2c89e0f0d5f446039bdabe8dbc3c9ccf35f0f784908b0acd185 \ - --hash=sha256:716b01a176c2a5659c98f6b01bf868244abdd896526f1c692712ab36dbaf9b63 \ - --hash=sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb \ - --hash=sha256:a2f9edd8dbc99f62bc4dfb78af7bf89499bca3d753423ac1b4e06592e467b763 \ - --hash=sha256:a4be6a2a190b32ff5c8002a0977a25ea60e64f7ba46b1be37093c141d9c49aeb \ - --hash=sha256:aae1b29cd68e50a9397f5ee897b9c24742e9e306f88a807a27d617f07adb3bd8 \ - --hash=sha256:aaf663927bcd490ae971469a624c322202a2a1e68936eb952535ca4cd3b90444 \ - --hash=sha256:b7bd80f3477b830dd166c707c5b0b82a898e7b16f59a7d9d42778dd058272e8b \ - --hash=sha256:bf0d9ff448b0218e0433aeb198805192346c4fd659c852370d5cc245f602a06a \ - --hash=sha256:c2ee399c644dc92ef7bc0d4f7e74b5360c37cdbe7c5ba11318dda49ffac2bc57 \ - --hash=sha256:cdf2a523d699b70d613243211ecaac14fe9c5df8a0b0a9c02add60fb2a413e0f \ - --hash=sha256:d8f5912ba938233f86361e891789595ff35ca4b4e2ac8fe3670895e5976731d6 \ - --hash=sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e \ - --hash=sha256:f5ab4ba32383061be0fb74bda772d470140a12c1c3b58a0cfbf3dae94d164c28 \ - --hash=sha256:ff43db38af76fda183156153983c9a096fc4c78d0cd1e07b14a2314c7f01c2c8 +torch==2.12.0 \ + --hash=sha256:10802fd383bbfed646212e765a72c37d2185205d4f26eb197a254e8ac7ddcb25 \ + --hash=sha256:10ee1448a9f304d3b987eb4656f664ba6e4d7b410ca7a5a7c642199777a2cf88 \ + --hash=sha256:1834bd984f8a2f4f16bdfbeecca9146184b220aa46276bf5756735b5dae12812 \ + --hash=sha256:2140e373e9a51a3e22ef62e8d14366d0b470d18f0adf19fdc757368077133a34 \ + --hash=sha256:3fee918902090ade827643e758e98363278815de583c75d111fdd665ebffde9f \ + --hash=sha256:415c1b8d0412f67551c8e89a2daca0fb3e56694af0281ba155eaa9da481f58b4 \ + --hash=sha256:4b4f64c2c2b11f7510d93dd6412b87025ff6eddd6bb61c3b5a3d892ea20c4756 \ + --hash=sha256:5d6b560dfa7d56291c07d615c3bb73e8d9943d9b6d87f76cd0d9d570c4797fa6 \ + --hash=sha256:5f96b63f8287f66a005dd1b5a6abba2920f11156c5e5c4d815f3e2050fd1aa16 \ + --hash=sha256:6a7512adfdd7f6732e40de1c620831e3c75b39b98cef60b11d0c5f0a76473ec5 \ + --hash=sha256:864392c73b7654f4d2b3ae712f607937d0dbb1101c4555fbb41848106b297f39 \ + --hash=sha256:891c769072637c74e9a5a77a3bc782894696d8ffec83b938df8536dee7f0ba78 \ + --hash=sha256:8b958caff4a14d3a3b0b2dfc6a378f64dda9728a9dad28c08a0db9ce4dafb549 \ + --hash=sha256:8fbef9f108a863e7722a73740998967e3b074742a834fc5be3a535a2befa7057 \ + --hash=sha256:90dd587a5f61bfe1307148b581e2084fc5bc4a06e2b90a20e9a36b81087ff16b \ + --hash=sha256:a43ac605a5e13116c72b64c359644cce0229f213dde48d2ae0ae5eb5becf7feb \ + --hash=sha256:a6a2eebb237d3b1d9ad3b378e86d9b9e0782afdea8b1e0eba6a13646b9b49c07 \ + --hash=sha256:af68dbf403439cae9ceaeaaf92f8352b460787dcd27b92aa05c40dd4a19c0f1e \ + --hash=sha256:b41339df93d491435e790ff8bcbae1c0ce777175889bfd1281d119862793e6a2 \ + --hash=sha256:b4556715c8572758625d62b6e0ae3b1f76c440221913a6fb5e100f321fb4fb02 \ + --hash=sha256:c12592630aef72feaf18bd3f197ef587bbfa21131b31c38b23ab2e55fce92e36 \ + --hash=sha256:c66696857e987efb8bc1777a37357ec4f60ab5e8af6250b83d6034437fa2d8f3 \ + --hash=sha256:cf9839790285dd472e7a16aafcb4a4e6bf58ec1b494045044b0eefb0eb4bd1f2 \ + --hash=sha256:d47e7dee68ac4cd7a068b26bcd6b989935427709fae1c8f7bd0019978f829e15 \ + --hash=sha256:d4d029801cb7b6df858804a2a21b00cc2aa0bf0ee5d2ab18d343c9e9e5681f35 \ + --hash=sha256:dd37188ea325042cb1f6cafa56822b11ada2520c04791a52629b0af25bdfbfd9 \ + --hash=sha256:e2ad3eb85d39c3cab62dfa93ed5a73516e6a53c6713cb97d004004fe089f0f1f \ + --hash=sha256:f7dfae4a519197dfa050e98d8e36378a0fb5899625a875c2b54445005a2e404e # via # feast (pyproject.toml) # accelerate # docling-ibm-models # easyocr # safetensors + # sentence-transformers # timm # torchvision -torchvision==0.25.0 \ - --hash=sha256:0b5e7f50002a8145a98c5694a018e738c50e2972608310c7e88e1bd4c058f6ce \ - --hash=sha256:0d9a3f925a081dd2ebb0b791249b687c2ef2c2717d027946654607494b9b64b6 \ - --hash=sha256:146d02c9876858420adf41f3189fe90e3d6a409cbfa65454c09f25fb33bf7266 \ - --hash=sha256:153c0d2cbc34b7cf2da19d73450f24ba36d2b75ec9211b9962b5022fb9e4ecee \ - --hash=sha256:24e11199e4d84ba9c5ee7825ebdf1cd37ce8deec225117f10243cae984ced3ec \ - --hash=sha256:40a122c3cf4d14b651f095e0f672b688dde78632783fc5cd3d4d5e4f6a828563 \ - --hash=sha256:5e6b449e9fa7d642142c0e27c41e5a43b508d57ed8e79b7c0a0c28652da8678c \ - --hash=sha256:5f271136d2d2c0b7a24c5671795c6e4fd8da4e0ea98aeb1041f62bc04c4370ef \ - --hash=sha256:620a236288d594dcec7634c754484542dc0a5c1b0e0b83a34bda5e91e9b7c3a1 \ - --hash=sha256:632db02300e83793812eee4f61ae6a2686dab10b4cfd628b620dc47747aa9d03 \ - --hash=sha256:846890161b825b38aa85fc37fb3ba5eea74e7091ff28bab378287111483b6443 \ - --hash=sha256:855c0dc6d37f462482da7531c6788518baedca1e0847f3df42a911713acdfe52 \ - --hash=sha256:a8f8061284395ce31bcd460f2169013382ccf411148ceb2ee38e718e9860f5a7 \ - --hash=sha256:a95c47abb817d4e90ea1a8e57bd0d728e3e6b533b3495ae77d84d883c4d11f56 \ - --hash=sha256:acc339aba4a858192998c2b91f635827e40d9c469d9cf1455bafdda6e4c28ea4 \ - --hash=sha256:ad9a8a5877782944d99186e4502a614770fe906626d76e9cd32446a0ac3075f2 \ - --hash=sha256:b57430fbe9e9b697418a395041bb615124d9c007710a2712fda6e35fb310f264 \ - --hash=sha256:b75deafa2dfea3e2c2a525559b04783515e3463f6e830cb71de0fb7ea36fe233 \ - --hash=sha256:c2abe430c90b1d5e552680037d68da4eb80a5852ebb1c811b2b89d299b10573b \ - --hash=sha256:c4d395cb2c4a2712f6eb93a34476cdf7aae74bb6ea2ea1917f858e96344b00aa \ - --hash=sha256:cef0196be31be421f6f462d1e9da1101be7332d91984caa6f8022e6c78a5877f \ - --hash=sha256:d1abd5ed030c708f5dbf4812ad5f6fbe9384b63c40d6bd79f8df41a4a759a917 \ - --hash=sha256:db74a551946b75d19f9996c419a799ffdf6a223ecf17c656f90da011f1d75b20 \ - --hash=sha256:ea580ffd6094cc01914ad32f8c8118174f18974629af905cea08cb6d5d48c7b7 \ - --hash=sha256:f07f01d27375ad89d72aa2b3f2180f07da95dd9d2e4c758e015c0acb2da72977 \ - --hash=sha256:f25aa9e380865b11ea6e9d99d84df86b9cc959f1a007cd966fc6f1ab2ed0e248 \ - --hash=sha256:f49964f96644dbac2506dffe1a0a7ec0f2bf8cf7a588c3319fed26e6329ffdf3 \ - --hash=sha256:f9c55ae8d673ab493325d1267cbd285bb94d56f99626c00ac4644de32a59ede3 +torchvision==0.27.0 \ + --hash=sha256:0822b58d2c5d325cd0c7152b744acbd15f898c07572e2cfb70b075a865a4f6f9 \ + --hash=sha256:1a6dd742a150645126df9e0b2e449874c1d635897c773b322c2e067e98382dfe \ + --hash=sha256:1c01f0d1091ae22b9dfc082b0a0fe5faaf053686a29b4fb082ba7691375c73cf \ + --hash=sha256:1c2db4bde82bc48ebff73436a6adf34d4f809448268a70d9a1285f5c8f92313d \ + --hash=sha256:2664d06acd64d328aa7689b0d0c81ee31e240e9977d8768816b4be7c66c03211 \ + --hash=sha256:2c037709072ca9b19750c0cbe9e8bb6f91c9a1be1befa26df33e281deccbd8c7 \ + --hash=sha256:2c4099a15150143b9b034730b404a56d572efe0b79489b4c765d929cb4eac7f3 \ + --hash=sha256:419c98a9275b27660cdce6d09080fd5974d1ec1d4a225f71439ebacb3b0c4e64 \ + --hash=sha256:41d6dae73e1af09fa82ded597ae57f2a2314285acde54b25890a8f8e51b999d7 \ + --hash=sha256:5bb82fc3c55daf1788621e504310b0a286f1069627a8742f692aebb075ef25a7 \ + --hash=sha256:65772ff3ec4f4f5d680e30019835555dd239e7fefee4b0a846375fe1cb1592ef \ + --hash=sha256:70f071c6f74b60d5fe8851636d8d4cd5f4fa29d57fd9348a87a6f17b990b95ba \ + --hash=sha256:72bf547e58ddb948689734eed6f4b6a2031f979dba4fb08e3690688b392e929f \ + --hash=sha256:7a9966a088d06b4cf6c610e03be62de469efa6f2cd2e7c7eed8e925ed6af59ac \ + --hash=sha256:91f61b9865423037c327eb56afa207cc72de874e458c361840db9dcf5ce0c0eb \ + --hash=sha256:9bb9251f64b854124efed95d02953a89f7e2726c3ca662d7ea0151129157297f \ + --hash=sha256:a49e55055a39a8506fe7e59850522cab004efb2c3839f6057658889c1d69c815 \ + --hash=sha256:aaafa6962c9d91f42503de1957d6fa349907d028c06f335bd95da7a5bc57147d \ + --hash=sha256:aee384a2782c89517c4ab9061d2720ba59fd2ffe5ef89d0a149cc2d43abdf521 \ + --hash=sha256:b4aacff70ea4b7377f996f9048989c850d221fef33658ddbcae42aa5bd4ca11a \ + --hash=sha256:b4c6bb0a670dcba017b3643e21902c9b8a1cc1c127d602f1488fa29ec3c6e865 \ + --hash=sha256:c1fac0fc2a7adf29481fc1938a0e7845c57ba1147a986784109c4d98f434ea8c \ + --hash=sha256:c5121f1b9ab09a7f73e837871deb8321551f7eaeb19d87aa00de9191968eae44 \ + --hash=sha256:c9f44e35e6ec01caedacce9e941a5bf21fe424403321efac2507a201273653c5 \ + --hash=sha256:cbf89764fc76f3f17fbf80c12d5a89c691e91cb9d82c38412aaf0568655ffb19 \ + --hash=sha256:dadea3c5ecfd05bbb2a3312ab0374f213c58bf6459cb059122e2f4dfe13d10ed \ + --hash=sha256:df0c166b6bdf7c47f88e81e8b43bc085451d5c50d0c5d1691bc474c1227d6fed \ + --hash=sha256:f44453f107c296d5446a79f7ac59733ad8bf5ddfa04c53805dfbae298a42a798 # via # feast (pyproject.toml) # docling-ibm-models # easyocr # timm -tornado==6.5.4 \ - --hash=sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1 \ - --hash=sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1 \ - --hash=sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 \ - --hash=sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335 \ - --hash=sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8 \ - --hash=sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f \ - --hash=sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84 \ - --hash=sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7 \ - --hash=sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17 \ - --hash=sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 \ - --hash=sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f \ - --hash=sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc +tornado==6.5.6 \ + --hash=sha256:1c34cfab7ad6d104f052f55de06d39bbafc5885cfeb4da688803308dbcfa90b7 \ + --hash=sha256:2543597b24a695d72338a9a77818362d72387c03ae173f1f169eadc5c91466ac \ + --hash=sha256:385f35e4e22fb52551dfcda4cdc8c30c61c2c001aef5ddad99cdfe116952efd3 \ + --hash=sha256:38bc01b4acacded2de63ae78023548e41ebe6fbed3ec05a796d7ae3ad893887e \ + --hash=sha256:65fcfaafb079435c2c19dc9e07c0f1cf0fa9051759ed0a7d0a3ba7ea7f64919c \ + --hash=sha256:6739bf1e8eb09230f1280ddbd3236f0309db70f2c551a8dbc40f62babdf82f79 \ + --hash=sha256:8666946e70171b8c3f1fc9b7876fac492e84822c4c7f3746f4e8f8bc9ac92a79 \ + --hash=sha256:9a365179fe8ff6b8766f602c0f67c185d778193e9bdd828b19f0b6ed7764177d \ + --hash=sha256:b942e6a137fda31ff54bf8e6e2c8d1c37f1f50583f3ed53fb840b53b9601d104 \ + --hash=sha256:db475f1b67b2809b10bb16264829087724ca8d24fe4ed47f7b8675cae453ef86 # via # ipykernel # jupyter-client @@ -5855,9 +6525,9 @@ tornado==6.5.4 \ # jupyterlab # notebook # terminado -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # datasets @@ -5868,10 +6538,11 @@ tqdm==4.67.3 \ # milvus-lite # mpire # semchunk + # sentence-transformers # transformers -traitlets==5.14.3 \ - --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ - --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f +traitlets==5.15.1 \ + --hash=sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92 \ + --hash=sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722 # via # ipykernel # ipython @@ -5892,6 +6563,7 @@ transformers==4.57.6 \ # feast (pyproject.toml) # docling-core # docling-ibm-models + # sentence-transformers tree-sitter==0.25.2 \ --hash=sha256:0628671f0de69bb279558ef6b640bcfc97864fe0026d840f872728a86cd6b6cd \ --hash=sha256:0c8b6682cac77e37cfe5cf7ec388844957f48b7bd8d6321d0ca2d852994e10d5 \ @@ -5930,15 +6602,16 @@ tree-sitter==0.25.2 \ --hash=sha256:fbb1706407c0e451c4f8cc016fec27d72d4b211fdd3173320b1ada7a6c74c3ac \ --hash=sha256:fe43c158555da46723b28b52e058ad444195afd1db3ca7720c59a254544e9c20 # via docling-core -tree-sitter-c==0.24.1 \ - --hash=sha256:290bff0f9c79c966496ebae45042f77543e6e4aea725f40587a8611d566231a8 \ - --hash=sha256:789781afcb710df34144f7e2a20cd80e325114b9119e3956c6bd1dd2d365df98 \ - --hash=sha256:7d2d0cda0b8dda428c81440c1e94367f9f13548eedca3f49768bde66b1422ad6 \ - --hash=sha256:942bcd7cbecd810dcf7ca6f8f834391ebf0771a89479646d891ba4ca2fdfdc88 \ - --hash=sha256:9a74cfd7a11ca5a961fafd4d751892ee65acae667d2818968a6f079397d8d28c \ - --hash=sha256:9c06ac26a1efdcc8b26a8a6970fbc6997c4071857359e5837d4c42892d45fe1e \ - --hash=sha256:a6a807705a3978911dc7ee26a7ad36dcfacb6adfc13c190d496660ec9bd66707 \ - --hash=sha256:d46bbda06f838c2dcb91daf767813671fd366b49ad84ff37db702129267b46e1 +tree-sitter-c==0.24.2 \ + --hash=sha256:1628584df0299b5a340aa63f8e67b6c97c91517f52fa7e7a4c557e40adb330a9 \ + --hash=sha256:4a2f4371cd816cc3153458f69062135ebb2ea5f275ddd90494e5c823d778204a \ + --hash=sha256:4d4579a8b54f0a442f903d88d3304cab77cd5c2031d4015baa4f2f8e15d6dcb7 \ + --hash=sha256:5041ef67eb68ce6bc8bb0b1f8ef3a5585ce523dae0c7eec109ab0627dd75aede \ + --hash=sha256:82842c5a5f2acd93f4de10038c33ac179c8979defc39376f990348d6289e933b \ + --hash=sha256:97bc80a224d48215d4e6e6376bf30d114f4c317b8145ff1b02afe785d4ba7bdd \ + --hash=sha256:abb549225091f7b25df2dd3a0143ece6e208f7055d8bcb4700b41ee79b9ef1e1 \ + --hash=sha256:c098bedcd5ac86ff93fa734d51d1dd86aed40fd5ed7d634c7af11380a0469969 \ + --hash=sha256:e2b42e8e22202c251f8629306f9321233542e07a6e01611b5fe83489272143eb # via docling-core tree-sitter-javascript==0.25.0 \ --hash=sha256:199d09985190852e0912da2b8d26c932159be314bc04952cf917ed0e4c633e6b \ @@ -5976,9 +6649,9 @@ trino==0.337.0 \ --hash=sha256:3a0bd03a09b7ea5dccd41ca6e58abfb127c6303f3a48a258ff794d411dd83a3c \ --hash=sha256:868f2b8137d4d1baa84c9bc341f2cdf29039462aa69d7c089a0b821b5a91f29c # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typer==0.12.5 \ --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ @@ -5987,9 +6660,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==1.17.0.20260307 \ - --hash=sha256:1a4f1168d43ed8cd2b0ed40a3eb870cda685a154d98478b0a65862084f190a02 \ - --hash=sha256:89b5b2c798d32fc6e3304903ed99af93fd608b741483ce7d57fa69eda40430e5 +types-cffi==2.0.0.20260518 \ + --hash=sha256:5b68a215a95d0eac4203b58e766ff7fe40c2e091b1fa1a9e54111f04cc560084 \ + --hash=sha256:f9707e66c13454789a58f8843d1ded4a66f1e9c8b10bd24d5eb5e0f25c0c5472 # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -5997,25 +6670,25 @@ types-protobuf==3.19.22 \ # via # feast (pyproject.toml) # mypy-protobuf -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) types-pyopenssl==24.1.0.20240722 \ --hash=sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39 \ --hash=sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54 # via types-redis -types-python-dateutil==2.9.0.20260305 \ - --hash=sha256:389717c9f64d8f769f36d55a01873915b37e97e52ce21928198d210fbd393c8b \ - --hash=sha256:a3be9ca444d38cadabd756cfbb29780d8b338ae2a3020e73c266a83cc3025dd7 +types-python-dateutil==2.9.0.20260518 \ + --hash=sha256:51f02dc03b61c7f6a07df45797d4dfe8a1aa47f0b7db9ad89f6fd3a1a70e1b51 \ + --hash=sha256:d6a9c5bd0de61460c8fdef8ab2b400f956a1a1075cce08d4e2b4434e478c50b8 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260304 \ - --hash=sha256:0c3542d8e9b0160b424233440c52b83d6f58cae4b85333d54e4f961cf013e117 \ - --hash=sha256:175332c1cf7bd6b1cc56b877f70bf02def1a3f75e5adcc05385ce2c3c70e6500 +types-pytz==2026.2.0.20260518 \ + --hash=sha256:3a12eaa38f476bd650902a9c9bb442f03f3c7dee2be5c5848bce61bd708d205a \ + --hash=sha256:e5d254329e9c4e91f0781b22c43a4bb2d10bb044d97b24c4b05d45567b0eae16 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260518 \ + --hash=sha256:d2150f75a231c9fe9c7463bd29487d93e60bac90400287351384bc2284eba7cd \ + --hash=sha256:d917f83fb38462550338c1297faedd860b3ec83912b96b1e3d73255f7473e466 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -6025,15 +6698,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260508 \ + --hash=sha256:8e51f159e8b24976849706ae2ed1dc9adba8ebbd080b17e494ebb66a8cc92c74 \ + --hash=sha256:b1e1a2d0456fbd655a71690b09a7aaeffdf2978d32049184ea436492aa51d20a # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -6043,7 +6716,9 @@ typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal + # alembic # anyio # azure-core # azure-identity @@ -6052,13 +6727,17 @@ typing-extensions==4.15.0 \ # docling-core # elasticsearch # fastapi + # graphene # great-expectations + # grpcio # huggingface-hub # ibis-framework # ipython + # jupyter-client # jwcrypto # mcp # minio + # mlflow-skinny # mypy # opentelemetry-api # opentelemetry-sdk @@ -6072,6 +6751,7 @@ typing-extensions==4.15.0 \ # python-docx # python-pptx # referencing + # sentence-transformers # snowflake-connector-python # sqlalchemy # starlette @@ -6088,9 +6768,9 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # arrow # ibis-framework @@ -6101,99 +6781,13 @@ tzlocal==5.3.1 \ # via # great-expectations # trino -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus uri-template==1.3.0 \ --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # via jsonschema -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # feast (pyproject.toml) # botocore @@ -6201,6 +6795,7 @@ urllib3==2.6.3 \ # docker # elastic-transport # great-expectations + # kube-authkit # kubernetes # minio # qdrant-client @@ -6214,6 +6809,7 @@ uvicorn[standard]==0.34.0 \ # feast (pyproject.toml) # fastapi-mcp # mcp + # mlflow-skinny # uvicorn-worker uvicorn-worker==0.3.0 \ --hash=sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b \ @@ -6277,121 +6873,121 @@ virtualenv==20.23.0 \ # feast (pyproject.toml) # pre-commit # ray -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn -wcwidth==0.6.0 \ - --hash=sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad \ - --hash=sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159 - # via prompt-toolkit +wcwidth==0.7.0 \ + --hash=sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2 \ + --hash=sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0 + # via + # prettytable + # prompt-toolkit webcolors==25.10.0 \ --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf @@ -6471,13 +7067,16 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -werkzeug==3.1.6 \ - --hash=sha256:210c6bede5a420a913956b4791a7f4d6843a43b6fcee4dfa08a65e93007d0d25 \ - --hash=sha256:7ddf3357bb9564e407607f988f683d72038551200c704012bb9a4c523d42f131 - # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +werkzeug==3.1.8 \ + --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ + --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 + # via + # flask + # flask-cors + # moto +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6485,90 +7084,100 @@ widgetsnbextension==4.0.15 \ --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 # via ipywidgets -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via # aiobotocore + # deprecated # smart-open # testcontainers xlsxwriter==3.2.9 \ @@ -6579,281 +7188,304 @@ xmltodict==1.0.4 \ --hash=sha256:6d94c9f834dd9e44514162799d344d815a3a4faec913717a9ecbfa5be1bb8e61 \ --hash=sha256:a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a # via moto -xxhash==3.6.0 \ - --hash=sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad \ - --hash=sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c \ - --hash=sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3 \ - --hash=sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004 \ - --hash=sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b \ - --hash=sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796 \ - --hash=sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f \ - --hash=sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c \ - --hash=sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1 \ - --hash=sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1 \ - --hash=sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0 \ - --hash=sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec \ - --hash=sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d \ - --hash=sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919 \ - --hash=sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67 \ - --hash=sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360 \ - --hash=sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799 \ - --hash=sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679 \ - --hash=sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef \ - --hash=sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d \ - --hash=sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7 \ - --hash=sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8 \ - --hash=sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa \ - --hash=sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e \ - --hash=sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa \ - --hash=sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec \ - --hash=sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4 \ - --hash=sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad \ - --hash=sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7 \ - --hash=sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5 \ - --hash=sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11 \ - --hash=sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae \ - --hash=sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d \ - --hash=sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4 \ - --hash=sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6 \ - --hash=sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df \ - --hash=sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058 \ - --hash=sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850 \ - --hash=sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2 \ - --hash=sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d \ - --hash=sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89 \ - --hash=sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e \ - --hash=sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa \ - --hash=sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6 \ - --hash=sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb \ - --hash=sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3 \ - --hash=sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b \ - --hash=sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4 \ - --hash=sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db \ - --hash=sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119 \ - --hash=sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec \ - --hash=sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518 \ - --hash=sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296 \ - --hash=sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033 \ - --hash=sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729 \ - --hash=sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca \ - --hash=sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063 \ - --hash=sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5 \ - --hash=sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d \ - --hash=sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f \ - --hash=sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8 \ - --hash=sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42 \ - --hash=sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e \ - --hash=sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392 \ - --hash=sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222 \ - --hash=sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f \ - --hash=sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd \ - --hash=sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77 \ - --hash=sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802 \ - --hash=sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d \ - --hash=sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1 \ - --hash=sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41 \ - --hash=sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374 \ - --hash=sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263 \ - --hash=sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71 \ - --hash=sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13 \ - --hash=sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8 \ - --hash=sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc \ - --hash=sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62 \ - --hash=sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11 \ - --hash=sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65 \ - --hash=sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0 \ - --hash=sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b \ - --hash=sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2 \ - --hash=sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788 \ - --hash=sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6 \ - --hash=sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f \ - --hash=sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc \ - --hash=sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e \ - --hash=sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702 \ - --hash=sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 \ - --hash=sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f \ - --hash=sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6 \ - --hash=sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87 \ - --hash=sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3 \ - --hash=sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a \ - --hash=sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b \ - --hash=sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b \ - --hash=sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b \ - --hash=sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8 \ - --hash=sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db \ - --hash=sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99 \ - --hash=sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a \ - --hash=sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2 \ - --hash=sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204 \ - --hash=sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b \ - --hash=sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546 \ - --hash=sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95 \ - --hash=sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9 \ - --hash=sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54 \ - --hash=sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06 \ - --hash=sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c \ - --hash=sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152 \ - --hash=sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86 \ - --hash=sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4 \ - --hash=sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93 \ - --hash=sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd \ - --hash=sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd \ - --hash=sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a \ - --hash=sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2 \ - --hash=sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248 \ - --hash=sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd \ - --hash=sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6 \ - --hash=sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf \ - --hash=sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7 \ - --hash=sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490 \ - --hash=sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0 \ - --hash=sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536 \ - --hash=sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb \ - --hash=sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829 \ - --hash=sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746 \ - --hash=sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07 \ - --hash=sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292 \ - --hash=sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6 \ - --hash=sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd \ - --hash=sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7 \ - --hash=sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d \ - --hash=sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0 \ - --hash=sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee \ - --hash=sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6 +xxhash==3.7.0 \ + --hash=sha256:01cf5c5333aed26cc8d5eea33b8d6398e085e365a704b7372fabdf7ab06441a9 \ + --hash=sha256:030c0fd688fce3569fbb49a2feefd4110cbb0b650186fb4610759ecfac677548 \ + --hash=sha256:03f8ff4474ee61c845758ce00711d7087a770d77efb36f7e74a6e867301000b8 \ + --hash=sha256:040ea63668f9185b92bc74942df09c7e65703deed71431333678fc6e739a9955 \ + --hash=sha256:05ece0fe4d9c9c2728912d1981ae1566cfc83a011571b24732cbf76e1fb70dca \ + --hash=sha256:05fd1254268c59b5cb2a029dfc204275e9fc52de2913f1e53aa8d01442c96b4d \ + --hash=sha256:073c23900a9fbf3d26616c17c830db28af9803677cd5b33aea3224d824111514 \ + --hash=sha256:082c87bfdd2b9f457606c7a4a53457f4c4b48b0cdc48de0277f4349d79bb3d7a \ + --hash=sha256:0c36f89ba026ccc6fde8f48479a2fd9fc450a736cc7c0d5650acfcff8636282e \ + --hash=sha256:0c72fe9c7e3d6dfd7f1e21e224a877917fa09c465694ba4e06464b9511b65544 \ + --hash=sha256:0d23fd49fdc5c8af61fb7104f1ad247954499140f6cb6045b3aa5c99dadbbf28 \ + --hash=sha256:0ff71596bd79816975b3de7130ab1ff4541410285a3c084584eeb1c8239996fd \ + --hash=sha256:1061bc6cec00adf75347b064ee62b220d66d9bc506acaad1418c79eec45a318c \ + --hash=sha256:11dd69b1a34b7b9af29012f390825b0cdb0617c0966560e227ca74daa7478ba9 \ + --hash=sha256:1295325c5a98d552333fa53dc2b026b0ef0ec9c8e73ca3a952990b4c7d65d459 \ + --hash=sha256:12c249621af6d50a05d9f10af894b404157b15819878e18f75fcbb0213a77d07 \ + --hash=sha256:12eca820a5d558633d423bf8bb78ce72a55394823f64089247f788a7e0ae691e \ + --hash=sha256:13805f0461cba0a857924e70ff91ae6d52d2598f79a884e788db80532614a4a1 \ + --hash=sha256:14bf7a54e43825ec131ee7fe3c60e142e7c2c1e676ad0f93fc893432d15414af \ + --hash=sha256:151d7520838d4465461a0b7f4ae488b3b00de16183dd3214c1a6b14bf89d7fb6 \ + --hash=sha256:153c3a4f73563101d4c8102cbff6a5b46f7aa9dbe374eedf1cd3b15fda750566 \ + --hash=sha256:157c49475b34ecea8809e51123d9769a534e139d1247942f7a4bc67710bb2533 \ + --hash=sha256:178959906cb1716a1ce08e0d69c82886c70a15a6f2790fc084fdd146ca30cd49 \ + --hash=sha256:17f8ae90c8e00f225be4899c3023704f23ee6d5638a00c54d6cbe9980068e6f9 \ + --hash=sha256:1910df4756a5ab58cfad8744fc2d0f23926e3efcc346ee76e87b974abab922f4 \ + --hash=sha256:1ad86695c19b1d46fe106925db3c7a37f16be37669dcf58dcc70a9dd6e324676 \ + --hash=sha256:1cc07c639e3a77ef1d32987464d3e408565b8a3be57b545d3542b191054d9923 \ + --hash=sha256:1d398f372496152f1c6933a33566373f8d1b37b98b8c9d608fa6edc0976f23b2 \ + --hash=sha256:2220af08163baf5fa36c2b8af079dc2cbe6e66ae061385267f9472362dfd53c6 \ + --hash=sha256:24cc22070880cc57b830a65cde4e65fa884c6d9b28ae4803b5ee05911e7bafba \ + --hash=sha256:2524a1e20d4c231d13b50f7cf39e44265b055669a64a7a4b9a2a44faa03f19b6 \ + --hash=sha256:2a61e2a3fb23c892496d587b470dee7fa1b58b248a187719c65ea8e94ec13257 \ + --hash=sha256:2d415f18becf6f153046ab6adc97da77e3643a0ee205dae61c4012604113a020 \ + --hash=sha256:31ab1461c77a11461d703c88eb949e132a1c6515933cf675d97ec680f4bd18de \ + --hash=sha256:31e3516a0f829d06ded4a2c0f3c7c5561993256bfa1c493975fb9dc7bfa828a1 \ + --hash=sha256:322b2f0622230f526aeb1738149948a7ae357a9e2ceb1383c6fd1fdaecdafa16 \ + --hash=sha256:3281ba1d1e60ee7a382a7b958513ba03c2c0d5fcbd9a6f7517c0a81251a23422 \ + --hash=sha256:3409b50ddbc76377d938f40a7a4662cd449f743f2c6178fd6162b875bf9b0d4f \ + --hash=sha256:347a93f2b4ce67ce61959665e32a7447c380f8347e55e100daa23766baacf0e5 \ + --hash=sha256:3573a651d146912da9daa9e29e5fbc45994420daaa9ef1e2fa5823e1dc485513 \ + --hash=sha256:363c139bf15e1ac5f136b981d3c077eb551299b1effede7f12faa010b8590a60 \ + --hash=sha256:37d994d0ffe81ef087bb330d392caa809bb5853c77e22ea3f71db024a0543dba \ + --hash=sha256:3afec3a336a2286601a437cb07562ab0227685e6fbb9ec17e8c18457ff348ecf \ + --hash=sha256:3b6b3d28228af044ebcded71c4a3dd86e1dbd7e2f4645bf40f7b5da65bb5fb5a \ + --hash=sha256:3bb5fd680c038fd5229e44e9c493782f90df9bef632fd0499d442374688ff70b \ + --hash=sha256:3beb1de3b1e9694fcdd853e570ee64c631c7062435d2f8c69c1adf809bc086f0 \ + --hash=sha256:3e1860f1e43d40e9d904cf22d93e587ea42e010ebce4160877e46bcab4bc232a \ + --hash=sha256:418a463c3e6a590c0cdc890f8be19adb44a8c8acd175ca5b2a6de77e61d0b386 \ + --hash=sha256:421da671f43a0189b57a4b8be694576308395f92f55ed3badcde67ab95acef81 \ + --hash=sha256:43475925a766d01ca8cd9a857fd87f3d50406983c8506a4c07c4df12adcc867f \ + --hash=sha256:44909f79fb7a4950ec7d96059398f46f634534cd95be9330a3827210af5aaebe \ + --hash=sha256:44fba4a5f1d179b7ddc7b3dc40f56f9209046421679b57025d4d8821b376fd8d \ + --hash=sha256:468f0fc114faaa4b36699f8e328bbc3bb11dc418ba94ac52c26dd736d4b6c637 \ + --hash=sha256:48b542c347c2089f43dc5a6db31d2a6f3cdb04ee33505ec6e9f653834dbb0bde \ + --hash=sha256:496736f86a9bedaf64b0dc70e3539d0766df01c71ea22032698e88f3f04a1ce9 \ + --hash=sha256:49a88183a3e5ab0b69d9bbfc0180cbdb247e8bada19fd9403c538b3aa3c24176 \ + --hash=sha256:49e556558eee5c8c9b2d5da03fd36cfa6c99cae95b3c3887ec64ee1a49ed517a \ + --hash=sha256:4b6d6b33f141158692bd4eafbb96edbc5aa0dabdb593a962db01a91983d4f8fa \ + --hash=sha256:4c2454448ce847c72635827bb75c15c5a3434b03ee1afd28cb6dc6fb2597d830 \ + --hash=sha256:4e15cc9e2817f6481160f930c62842b3ff419e20e13072bcbab12230943092bc \ + --hash=sha256:503722d52a615f2604f5e7611de7d43878df010dc0053094ef91cb9a9ac3d987 \ + --hash=sha256:506a0b488f190f0a06769575e30caf71615c898ed93ab18b0dbcb6dec5c3713c \ + --hash=sha256:50846b9b01f461ee0250d7a701a3d881e9c52ebce335d6e38e0224adc3369f50 \ + --hash=sha256:50e879ebbac351c81565ca108db766d7832f5b8b6a5b14b8c0151f7190028e3d \ + --hash=sha256:54876a4e45101cec2bf8f31a973cda073a23e2e108538dad224ba07f85f22487 \ + --hash=sha256:54a675cb300dda83d71daae2a599389d22db8021a0f8db0dd659e14626eb3ecc \ + --hash=sha256:565df64437a9390f84465dcca33e7377114c7ede8d05cd2cf20081f831ea788e \ + --hash=sha256:5886ad85e9e347911783760a1d16cb6b393e8f9e3b52c982568226cb56927bdc \ + --hash=sha256:5a6ddec83325685e729ca119d1f5c518ec39294212ecd770e60693cdc5f7eb79 \ + --hash=sha256:5b1bde10324f4c31812ae0d0502e92d916ae8917cad7209353f122b8b8f610c3 \ + --hash=sha256:5bf2f1940499839b39fef1561b5ecb6ede9ac34ef4457474e1337fc7ef07c2f3 \ + --hash=sha256:5de686e73690cdaf72b96d4fa083c230ec9020bcc2627ce6316138e2cf2fe2d1 \ + --hash=sha256:5e7ce913b61f35b0c1c839a49ac9c8e75dd8d860150688aed353b0ce1bf409d8 \ + --hash=sha256:5ec1e080a3d02d94ea9335bfab0e3374b877e25411422c18f51a943fa4b46381 \ + --hash=sha256:6318d8b6f6c6c21058928c23289686fc74f37d794170f14b35fecceb515d5e37 \ + --hash=sha256:646a69b56d8145d85f7fd2289d14fba07880c8a5bda406aa256b407481a61f35 \ + --hash=sha256:646b8aa66cf0cec9295dfc4e3ac823ee52e338bada9547f5cf2d674212d04b58 \ + --hash=sha256:6741564a923f082f3c2941c8bb920462ed5b25eaebdd1e161f162233c9a10bc5 \ + --hash=sha256:693d02c6dc7d1aa0a45921d54cd8c1ff629e09dfdc2238471507af1f7a1c6f04 \ + --hash=sha256:6be4d70d9ab76c9f324ead9c01af6ff52c324745ea0c3731682a0cf99720f1fe \ + --hash=sha256:6cc4eefbb542a5d6ffd6d70ea9c502957c925e800f998c5630ecc809d6702bae \ + --hash=sha256:6e83179bbb208fb72774c06ba227d6e410fa3797de33d0d4c00e3935f81da7d2 \ + --hash=sha256:6e934bbae1e0ec74e27d5f0d7f37ef547ce5ff9f0a7e63fb39e559fc99526734 \ + --hash=sha256:6f31143e18e6db136455b16f0e4e6eba943e1889127dd7c649b46a50d54dd836 \ + --hash=sha256:7426ff0dfa76eb47efc2cc59d4a717bfa9dc9938bff5e49e748bca749f6aa616 \ + --hash=sha256:74bbd92f8c7fcc397ba0a11bfdc106bc72ad7f11e3a60277753f87e7532b4d81 \ + --hash=sha256:7553816512c0abb75329c163a1eee77b0802c3757054b910d6e547bd0dbd16b7 \ + --hash=sha256:79f9efdbc828b02c681a7cefc6d4108d63811b20a8fb8518a40cb2c13ed15452 \ + --hash=sha256:7ab9a49c410d8c6c786ab99e79c529938d894c01433130353dd0fe999111077a \ + --hash=sha256:7bd7bc82dd4f185f28f35193c2e968ef46131628e3cac62f639dadf321cba4d1 \ + --hash=sha256:7c4d596b7676f811172687ec567cbafb9e4dea2f9be1bbb4f622410cb7f40f40 \ + --hash=sha256:7c76f18d1268d3dc1c8b8facef5b48a9c6172d4a49113afa2d91745f555c75ff \ + --hash=sha256:7d7148180ec99ba36585b42c8c5de25e9b40191613bc4be68909b4d25a77a852 \ + --hash=sha256:7fbec49f5341bbdea0c471f7d1e2fb41ae8925af9b6f28025c28defd8eb94274 \ + --hash=sha256:84415265192072d8638a3afc3c1bc5995e310570cd9acb54dc46d3939e364fe0 \ + --hash=sha256:845d347df254d6c619f616afa921331bada8614b8d373d58725c663ba97c3605 \ + --hash=sha256:84710b4e449596a6565ab67293858d2d93a54eeec55722d55c8f0a08b6e6de24 \ + --hash=sha256:85f5c0e26d945b5bb475e0a3d95193117498130baa7619357bdc7869c2391b5a \ + --hash=sha256:8653dd7c2eda020545bb2c71c7f7039b53fe7434d0fc1a0a9deb79ab3f1a4fc1 \ + --hash=sha256:875811ba23c543b1a1c3143c926e43996eb27ebb8f52d3500744aa608c275aed \ + --hash=sha256:8c5fcfd806c335bfa2adf1cd0b3110a44fc7b6995c3a648c27489bae85801465 \ + --hash=sha256:8d09dfd2ab135b985daf868b594315ebe11ad86cd9fea46e6c69f19b28f7d25a \ + --hash=sha256:8d4dea659b57443989ef32f4295104fd6912c73d0bf26d1d148bb88a9f159b02 \ + --hash=sha256:8e7edb98dd4721a2694542a35a0bdb989b42892086fd0216f7c48762dfe20844 \ + --hash=sha256:8f4608a06e4d61b7a3425665a46d00e0579122e1a2fae97a0c52953a3aad9aa3 \ + --hash=sha256:8ff00fcc3eb436617ed8556cf15daf76c2b501248361a065625a588af78a0a02 \ + --hash=sha256:90b9d1a8bd37d768ffc92a1f651ec69afc532a96fa1ac2ea7abbed5d630b3237 \ + --hash=sha256:9122ad6f867c4a0f5e655f5c3bdf89103852009dbb442a3d23e688b9e699e800 \ + --hash=sha256:91c3b07cf3362086d8f126c6aecd8e5e9396ad8b2f2219ea7e49a8250c318acd \ + --hash=sha256:921c14e93817842dd0dd9f372890a0f0c72e534650b6ab13c5be5cd0db11d47e \ + --hash=sha256:970f9f8c50961d639cbd0d988c96f80ddf66006de93641719282c4fe7a87c5e6 \ + --hash=sha256:9e6c0d843f1daf85ea23aeb053579135552bde575b7b98af20bfc667b6e4548d \ + --hash=sha256:9f1563fdc8abfc389748e6932c7e4e99c89a53e4ec37d4563c24fc06f5e5644b \ + --hash=sha256:9fd17f14ac0faa12126c2f9ca774a8cf342957265ec3c8669c144e5e6cdb478c \ + --hash=sha256:a04a6cab47e2166435aaf5b9e5ee41d1532cc8300efdef87f2a4d0acb7db19ed \ + --hash=sha256:a169a036bed0995e090d1493b283cc2cc8a6f5046821086b843abefff80643bc \ + --hash=sha256:a2eae53197c6276d5b317f75a1be226bbf440c20b58bf525f36b5d0e1f657ca6 \ + --hash=sha256:a3b19a42111c4057c1547a4a1396a53961dca576a0f6b82bfa88a2d1561764b2 \ + --hash=sha256:a6545e6b409e3d5cbafc850fb84c55a1ca26ed15a6b11e3bf07a0e0cd84517c8 \ + --hash=sha256:a6d73a830b17ef49bc04e00182bd839164c1b3c59c127cd7c54fcb10c7ed8ee8 \ + --hash=sha256:a778b25874cb0f862eaab5986bff4ca49ffb0def7c0a34c237b948b3c6c775b2 \ + --hash=sha256:a7f25baec4c5d851d40718d6fae52285b31683093d4ff5207e63ab306ccf14a5 \ + --hash=sha256:a845a59664d5c531525a467470220f8edc37959e0a6f8e734ffb6654da5c4bee \ + --hash=sha256:a999771ff97bec27d18341be4f3a36b163bb1ac41ec17bef6d2dabd84acd33c7 \ + --hash=sha256:ab9dd2c83c4bbd63e422181a76f13502d049d3ddcac9a1bdc29196263d692bb8 \ + --hash=sha256:abb65b4e947e958f7b3b0d71db3ce447d1bc5f37f5eab871ce7223bda8768a04 \ + --hash=sha256:acbb48679ddf3852c45280c10ff10d52ca2cd1da2e552fb81db1ff786c75d0e4 \ + --hash=sha256:ad37c7792479e49cf96c1ab25517d7003fe0d93687a772ba19a097d235bbe41e \ + --hash=sha256:ad3aa71e12ee634f22b39a0ff439357583706e50765f17f05550f92dbf128a23 \ + --hash=sha256:ae3a39a4d96bdb6f8d154fd7f490c4ad06f0532fcd2bb656052a9a7762cf5d31 \ + --hash=sha256:b081119a6115d2db49e24ab6316b7dcd74651271e9630c7b979999bd0c11973d \ + --hash=sha256:b4e6fe5c6f4e6ad67c1374a7c85c944ca1a8d9672f0a1628201ea5c58e0d4596 \ + --hash=sha256:b59ee2ac81de57771a09ecad09191e840a1d2fae1ef684208320591055768f83 \ + --hash=sha256:b5cd29840505631c6f7dbb8a5d34b742b5e6bbda38fe0b9f54e825f3ea6b61dc \ + --hash=sha256:b7ffeaada9f8699be63d639536b0b60dff73b7d3325b7475c5bc8fdbf4eed47f \ + --hash=sha256:bb16aa13ed175bc9be5c2491ba031b85a9b51c4ed90e0b3d4ebe63cf3fb54f8e \ + --hash=sha256:bfe6f92e3522dcbe8c4281efd74fa7542a336cb00b0e3272c4ec0edabeaeaf67 \ + --hash=sha256:c21625d710f971dd58ae92c5b0c2ca109d2ceba939becc937c5cff9268cd451b \ + --hash=sha256:c3c0059e642b2e7e15c77341a8946f670a403fcd57feecc9e47d68555b9b1c08 \ + --hash=sha256:c40a8ad7d42fe779ac429fe245ed44c54f30e2549173559d70b7167922431701 \ + --hash=sha256:c4fd8acc6e32596350619896feb372033c0920975992d29837c32853bb1feacd \ + --hash=sha256:c50269d0055ac1faecfd559886d2cbe4b730de236585aba0e873f9d9dadbe585 \ + --hash=sha256:c72500a3b6d6c30ebfc135035bcace9eb5884f2dc220804efcaaba43e9f611dd \ + --hash=sha256:c7741c7524961d8c0cb4d4c21b28957ff731a3fd5b5cd8b856dc80a40e9e5acc \ + --hash=sha256:c9b31ab1f28b078a6a1ac1a54eb35e7d5390deddd56870d0be3a0a733d1c321c \ + --hash=sha256:ca12a6d683957a651e3203c1458ff8ab4119aae7363e202e2e820cbfe02df244 \ + --hash=sha256:cb5a888a968b2434abf9ecda357b5d43f10d7b5a6da6fdbbe036208473aff0e2 \ + --hash=sha256:cce1e2782efaf0f595c17fe331cf295882a268c04d5887956e2fc0d262b0fb3a \ + --hash=sha256:cd8ab85c916a58d5c8656ea15e3ce9df836fe2f120a74c296e01d69fab2614b4 \ + --hash=sha256:cee88dfaa6b1b2bfadd3c031fa5f05584870e62fb05dc500942e9900c44fcfda \ + --hash=sha256:cf7424a11a81f59b6f0abdccfbe27c87d552f059ef761471f98245b46b71b5c9 \ + --hash=sha256:d006faf3b491957efcb433489be3c149efe4787b7063d5cddb8ddaefdc60e0c1 \ + --hash=sha256:d1442628c84afa453a9a06a10d74d890d3c1b1e4da313b48b16e1001895fdac4 \ + --hash=sha256:d33fcd60f5546e4b7538a8ae2b2027b51e9905b9a264c32df56de32202997155 \ + --hash=sha256:d41fcda2fa8ca682ebca134a2f2dc02575ba549267585597e73061565795f475 \ + --hash=sha256:d610aa62cdb7d4d497740741772a24a794903bf3e79eaa51d2e800082abe11e5 \ + --hash=sha256:d798c1e291bffb8e37b5bbe0dda77fc767cd19e89cadaf66e6ed5d0ff88c9fe6 \ + --hash=sha256:d7d9110d0c3fb02679972837a033251fd186c529aa62f19c132fc909c74052b8 \ + --hash=sha256:da5b373b1dfce210b8620bdb5d9dae668fe549de67948465dcc39e833d4bbe28 \ + --hash=sha256:dbcd969178d417c2bbd60076f8e407a0e2baf90976eed21c1b818ff8292b902f \ + --hash=sha256:dc026e3b89d98e30a8288c95cb696e77d150b3f0fb7a51f73dcd49ee6b5577fa \ + --hash=sha256:dea2fd4ae84b14aa883ac713faffbb5c26764ec623e00ed34737895be523d1fa \ + --hash=sha256:e64a7c9d7dfca3e0fafcbc5e455519090706a3e36e95d655cec3e04e79f95aaa \ + --hash=sha256:e8ff6ec73110f610425caef3ea875afbfc34caa542f01df3a80f45aadeb9f906 \ + --hash=sha256:ea6daa712f4e094a30830cf01e9b47d03b24d05cc9dab8609f0d9a9db8454712 \ + --hash=sha256:ea85a647fd33d5cf2840027c2e0b7da8868b220d3f05e3866efdda78c440d499 \ + --hash=sha256:ec101643395d7f21405b640f728f6f627e6986557027d740f2f9b220955edafe \ + --hash=sha256:ec68dbba21532c0173a9872298e65c89749f7c9d21538c3a78b5bb6105871568 \ + --hash=sha256:ed4a6efe2dee1655adb73e7ad40c6aa955a6892422b1e3b95de6a34de56e3cbb \ + --hash=sha256:f13319fb8e6ef636f71db3c254d01cbf1543786e10a945a3ff180144618e25b6 \ + --hash=sha256:f14bb8b22a4a91325813e3d553b8963c10cf8c756cff65ee50c194431296c655 \ + --hash=sha256:f1598916cb197681e03e601901e4ab96a9a963de398c59d0964f8a6f44a2b361 \ + --hash=sha256:f1e65d52c2d526734abecb98372c256b7eacce8fdc42e0df8570417fb39e2772 \ + --hash=sha256:f262b8f7599516567e070abf607b9af649052b2c4bd6f9be02b0cb41b7024805 \ + --hash=sha256:f3e7b689c3bce16699efcf736066f5c6cc4472c3840fe4b22bd8279daf4abdac \ + --hash=sha256:f420ad3d41e38194353a498bbc9561fd5a9973a27b536ce46d8583479cf44335 \ + --hash=sha256:f749e52b539e2934171a3718cbf061dc12d74719eddde2d0f025c99637ddbe01 \ + --hash=sha256:f99a15867cbf9fcf753ea72b82a1d6fe6552e6feea3b4842c86a951525685bbb \ + --hash=sha256:f9fd595f1e5941b3d7863e4774e4b30caa6731fc34b9277da032295aa5656ee5 \ + --hash=sha256:fa77e7ec1450d415d20129961814787c9abd9a07f98872f070b1fe96c5084611 \ + --hash=sha256:fc84bf7aa7592f31ec63a3e7b11d624f468a3f19f5238cec7282a42e838ab1d7 \ + --hash=sha256:fd880353cf1ffaf321bc18dd663e111976dbd0d3bbd8a66d58d2b470dfa7f396 \ + --hash=sha256:fdc7d06929ae28dda98297a18eef7b0fd38991a3b405d8d7b55c9ef24c296958 \ + --hash=sha256:fddbbb69a6fff4f421e7a0d1fa28f894b20112e9e3fab306af451e2dfd0e459b \ + --hash=sha256:fe14c356f8b23ad811dc026077a6d4abccdaa7bce5ca98579605550657b6fcfb \ + --hash=sha256:fe32736295ea38e43e7d9424053c8c47c9f64fecfc7c895fb3da9b30b131c9ee \ + --hash=sha256:fe820f104473d1516ecd628993690bc1f79b0e699f32711d42a5a70b3d0f8170 # via datasets -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata zstandard==0.25.0 \ --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ diff --git a/sdk/python/requirements/py3.11-minimal-requirements.txt b/sdk/python/requirements/py3.11-minimal-requirements.txt index dcfc05d895b..546644c76c6 100644 --- a/sdk/python/requirements/py3.11-minimal-requirements.txt +++ b/sdk/python/requirements/py3.11-minimal-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.11 --no-strip-extras pyproject.toml --extra minimal --generate-hashes --output-file sdk/python/requirements/py3.11-minimal-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -148,9 +149,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -161,6 +162,41 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy async-timeout==5.0.1 \ --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 @@ -169,34 +205,38 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -291,130 +331,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -424,68 +479,68 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt # pyopenssl # snowflake-connector-python -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -493,50 +548,50 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -544,9 +599,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -682,15 +737,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -700,9 +755,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -714,37 +769,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -788,84 +843,82 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -873,21 +926,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -897,150 +950,175 @@ h11==0.16.0 \ # via # httpcore # uvicorn -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1056,18 +1134,18 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx # requests # snowflake-connector-python # yarl -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1090,109 +1168,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1285,9 +1363,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1298,9 +1376,7 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -1561,123 +1637,129 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask @@ -1689,85 +1771,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1841,9 +1923,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1853,163 +1935,162 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2048,68 +2129,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2122,12 +2203,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2136,141 +2215,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2278,30 +2356,30 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2320,13 +2398,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2409,9 +2487,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2419,9 +2497,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2429,6 +2507,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python requests-oauthlib==2.0.0 \ @@ -2437,139 +2516,150 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework # typer -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -2578,7 +2668,6 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de @@ -2589,115 +2678,111 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2713,58 +2798,58 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -2773,31 +2858,33 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal # anyio # fastapi + # grpcio # ibis-framework # mcp # mypy @@ -2820,101 +2907,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -2982,116 +2983,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3160,220 +3159,205 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata diff --git a/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt b/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt index 58cad984f6b..8304e0a864c 100644 --- a/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt @@ -4,6 +4,41 @@ # # pybuild-deps compile --generate-hashes --output-file=sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt sdk/python/requirements/py3.11-minimal-sdist-requirements.txt # +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 @@ -171,52 +206,116 @@ cython==3.0.12 \ # pyyaml # snowflake-connector-python # sqlalchemy -cython==3.2.4 \ - --hash=sha256:02cb0cc0f23b9874ad262d7d2b9560aed9c7e2df07b49b920bda6f2cc9cb505e \ - --hash=sha256:03893c88299a2c868bb741ba6513357acd104e7c42265809fd58dce1456a36fc \ - --hash=sha256:14dae483ca2838b287085ff98bc206abd7a597b7bb16939a092f8e84d9062842 \ - --hash=sha256:1a64a112a34ec719b47c01395647e54fb4cf088a511613f9a3a5196694e8e382 \ - --hash=sha256:28b1e363b024c4b8dcf52ff68125e635cb9cb4b0ba997d628f25e32543a71103 \ - --hash=sha256:28e8075087a59756f2d059273184b8b639fe0f16cf17470bd91c39921bc154e0 \ - --hash=sha256:2b1f12c0e4798293d2754e73cd6f35fa5bbdf072bdc14bc6fc442c059ef2d290 \ - --hash=sha256:31a90b4a2c47bb6d56baeb926948348ec968e932c1ae2c53239164e3e8880ccf \ - --hash=sha256:35ab0632186057406ec729374c737c37051d2eacad9d515d94e5a3b3e58a9b02 \ - --hash=sha256:36bf3f5eb56d5281aafabecbaa6ed288bc11db87547bba4e1e52943ae6961ccf \ - --hash=sha256:3b6e58f73a69230218d5381817850ce6d0da5bb7e87eb7d528c7027cbba40b06 \ - --hash=sha256:3b8e62049afef9da931d55de82d8f46c9a147313b69d5ff6af6e9121d545ce7a \ - --hash=sha256:55b6c44cd30821f0b25220ceba6fe636ede48981d2a41b9bbfe3c7902ce44ea7 \ - --hash=sha256:55eb425c0baf1c8a46aa4424bc35b709db22f3c8a1de33adb3ecb8a3d54ea42a \ - --hash=sha256:64d7f71be3dd6d6d4a4c575bb3a4674ea06d1e1e5e4cd1b9882a2bc40ed3c4c9 \ - --hash=sha256:67922c9de058a0bfb72d2e75222c52d09395614108c68a76d9800f150296ddb3 \ - --hash=sha256:6d5267f22b6451eb1e2e1b88f6f78a2c9c8733a6ddefd4520d3968d26b824581 \ - --hash=sha256:72e6c0bbd978e2678b45351395f6825b9b8466095402eae293f4f7a73e9a3e85 \ - --hash=sha256:732fc93bc33ae4b14f6afaca663b916c2fdd5dcbfad7114e17fb2434eeaea45c \ - --hash=sha256:767b143704bdd08a563153448955935844e53b852e54afdc552b43902ed1e235 \ - --hash=sha256:83266c356c13c68ffe658b4905279c993d8a5337bb0160fa90c8a3e297ea9a2e \ - --hash=sha256:84226ecd313b233da27dc2eb3601b4f222b8209c3a7216d8733b031da1dc64e6 \ - --hash=sha256:869487ea41d004f8b92171f42271fbfadb1ec03bede3158705d16cd570d6b891 \ - --hash=sha256:90f43be4eaa6afd58ce20d970bb1657a3627c44e1760630b82aa256ba74b4acb \ - --hash=sha256:983f9d2bb8a896e16fa68f2b37866ded35fa980195eefe62f764ddc5f9f5ef8e \ - --hash=sha256:b362819d155fff1482575e804e43e3a8825332d32baa15245f4642022664a3f4 \ - --hash=sha256:b84d4e3c875915545f77c88dba65ad3741afd2431e5cdee6c9a20cefe6905647 \ - --hash=sha256:ca2399dc75796b785f74fb85c938254fa10c80272004d573c455f9123eceed86 \ - --hash=sha256:ca578c9cb872c7ecffbe14815dc4590a003bc13339e90b2633540c7e1a252839 \ - --hash=sha256:d4b4fd5332ab093131fa6172e8362f16adef3eac3179fd24bbdc392531cb82fa \ - --hash=sha256:e3b5ac54e95f034bc7fb07313996d27cbf71abc17b229b186c1540942d2dc28e \ - --hash=sha256:e65e4773021f8dc8532010b4fbebe782c77f9a0817e93886e518c93bd6a44e9d \ - --hash=sha256:e71efb20048358a6b8ec604a0532961c50c067b5e63e345e2e359fff72feaee8 \ - --hash=sha256:f136f379a4a54246facd0eb6f1ee15c3837cb314ce87b677582ec014db4c6845 \ - --hash=sha256:f583cad7a7eed109f0babb5035e92d0c1260598f53add626a8568b57246b62c3 \ - --hash=sha256:f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 \ - --hash=sha256:f8d685a70bce39acc1d62ec3916d9b724b5ef665b0ce25ae55e1c85ee09747fc \ - --hash=sha256:fdfdd753ad7e18e5092b413e9f542e8d28b8a08203126090e1c15f7783b7fe57 \ - --hash=sha256:ff9af2134c05e3734064808db95b4dd7341a39af06e8945d05ea358e1741aaed +cython==3.1.1 \ + --hash=sha256:011cdcbf7725f0cfc1abc55ec83d326e788050711272131daf3cc24a19c34bb2 \ + --hash=sha256:020089f9c9f10269181f17660a2cada7d4577bd8eea24b7d2b14e6b64b6996be \ + --hash=sha256:07621e044f332d18139df2ccfcc930151fd323c2f61a58c82f304cffc9eb5280 \ + --hash=sha256:0de7adff5b42d2556d073e9f321c2faa639a17fb195ec1de130327f60ec209d8 \ + --hash=sha256:0e3ccec55e2a534a712db14c6617b66f65ad149c014fad518fc3920f6edde770 \ + --hash=sha256:0f7954b0b4b3302655d3caa6924261de5907a4e129bc22ace52fe9ae0cd5a758 \ + --hash=sha256:10f0434916994fe213ea7749268b88d77e3ebcbd1b99542cf64bb7d180f45470 \ + --hash=sha256:12e00b88147b03c148a95365f89dc1c45a0fc52f9c35aa75ff770ef65b615839 \ + --hash=sha256:141ffd6279411c562f6b707adc56b63e965a4fd7f21db83f5d4fcbd8c50ac546 \ + --hash=sha256:16d9870654946375b28280371d370d541641d1071da123d0d64d2c7ebba0cc56 \ + --hash=sha256:23b886a6c8a50b1101ccef2f2f3dc9c699b77633ef5bb5007090226c2ad3f9c2 \ + --hash=sha256:24c640c0746d984789fe2787a098f06cda456ef2dd78b90164d17884b350839a \ + --hash=sha256:263cb0e497910fb5e0a361ad1393b6d728b092178afecc56e8a786f3739960c3 \ + --hash=sha256:268420b92307ae6c5a16e3cf0e2ba1ae3c861650e992893922a0ce08db07cfdb \ + --hash=sha256:28b174f41718a7041cfbe0f48913020875ff1aaa4793942b2451ac6d2baf3f07 \ + --hash=sha256:307f216ed319ea07644f2ef9974406c830f01bc8e677e2147e9bfcdf9e3ca8ad \ + --hash=sha256:3192a61c2a532d3faccdff508bc8427de9530b587888218bfc0226eb33a84e11 \ + --hash=sha256:3fa4bd840de63509c74867b4b092541720a01db1e07351206011c34e0777dc96 \ + --hash=sha256:402f86c00b08f875cd0990f0c4dc52eb3e0bc5d630066cdf3c798631976f1937 \ + --hash=sha256:40f50b07c479eaf33981d81cad274c68cf9fb81dbe79cbf991f59491c88a4705 \ + --hash=sha256:426d78565eb91d3366569b20e92b8f14bffef5f57b2acd05b60bbb9ce5c056a1 \ + --hash=sha256:505ccd413669d5132a53834d792c707974248088c4f60c497deb1b416e366397 \ + --hash=sha256:50ad80e2f438e9127a87c10927e6ac16a987df39c248b19ab2cd31330129be3c \ + --hash=sha256:54a8934cb3bf13b1f8f6cbdae8e382e25a26e67de08ea6ebfd0a467131b67227 \ + --hash=sha256:56c6768a6f601f93daab7c2487f9f110548a896a91e00a6e119445ada2575323 \ + --hash=sha256:64915259276482fa23417b284d1fdc7e3a618ee2f819bb6ea7f974c075633df6 \ + --hash=sha256:689c1aad373556bd2ab1aa1c2dad8939a2891465a1fbd2cbbdd42b488fb40ec8 \ + --hash=sha256:6ea77ad1e649cec38f8622ba28dcdfbe7bf519bc132abbcf5df759b3975b5a73 \ + --hash=sha256:7489559e6c5ecbba49d535c2e03cf77c2594a3190b6aca7da5b508ba1664a89a \ + --hash=sha256:755a991601b27dd3555310d0f95b19a05e622a80d7b4e7a91fa6f5f3ef3f3b80 \ + --hash=sha256:7da069ca769903c5dee56c5f7ab47b2b7b91030eee48912630db5f4f3ec5954a \ + --hash=sha256:7e5cad896af896482240979b996bf4136b0d18dc40c56c72c5641bf0ea085dfb \ + --hash=sha256:7fff6526bb6f4eea615663117b86de6ede0d17c477b600d3d8302be3502bd3c3 \ + --hash=sha256:83b2af5c327f7da4f08afc34fddfaf6d24fa0c000b6b70a527c8125e493b6080 \ + --hash=sha256:873aac4ac0b0fb197557c0ac15458b780b9221daa4a716881cbd1a9016c8459f \ + --hash=sha256:8aaa29e763adf3496ab9d371e3caed8da5d3ce5ff8fb57433e2a2f2b5036e5c8 \ + --hash=sha256:953046c190fa9ab9a09a546a909b847cdbb4c1fe34e9bfa4a15b6ee1585a86aa \ + --hash=sha256:9b61b99205308c96b1162de59bd67ecadcad3d166a4a1f03a3d9e826c39cd375 \ + --hash=sha256:9d7dc0e4d0cd491fac679a61e9ede348c64ca449f99a284f9a01851aa1dbc7f6 \ + --hash=sha256:a19188ecd385cdc649e3fec370f38d5fd7f1651aeed0b3fb403180f38fc88e8a \ + --hash=sha256:a585796939b09b3205b1980e4a55e745c0251e45a5c637afbcac3c6cc9ad6f90 \ + --hash=sha256:a92f6bd395eadea6eed722a8188d3bdd49db1c9fa3c38710456d6148ab71bad7 \ + --hash=sha256:ab644415458d782c16ba7252de9cec1e3125371641cafea2e53a8c1cf85dd58d \ + --hash=sha256:af8f62cc9339b75fe8434325083e6a7cae88c9c21efd74bbb6ba4e3623219469 \ + --hash=sha256:b181158b5761bdaf40f6854f016ab7ddff64d3db4fca55cb3ca0f73813dd76d6 \ + --hash=sha256:b194a65a0fd91f305d2d1e7010f44111774a28533e1e44dd2a76e7de81a219b9 \ + --hash=sha256:b68f1bc80387554eb43f2b62795c173bed9e37201f39dc5084ac437c90a79c9f \ + --hash=sha256:c360823e1063784efc2335617e0f28573d7a594c5a8a05d85e850a9621cccb1f \ + --hash=sha256:c5cb6c054daadaf01a88c8f49f3edd9e829c9b76a82cbb4269e3f9878254540b \ + --hash=sha256:c740a10cd0f50321d048c8ca318eefb4c42b8bffef982dcd89c946d374192702 \ + --hash=sha256:c8b8be01fd40b3e38a76c60a524f956548a3a7566e5530a833a48a695f3d6c12 \ + --hash=sha256:cb5661941707bd41ec7a9c273d698113ac50392444f785088e9d9706c6a5937b \ + --hash=sha256:cd748fab8e4426dbcb2e0fa2979558333934d24365e0de5672fbabfe337d880c \ + --hash=sha256:cdf53dc4b2a13bd072d6c2c18ac073dbf0f798555bc27ba4f7546a275eb16a0f \ + --hash=sha256:ce82070ccf92c3599d331b9eaaefd9d4562976fb86a8d6bccf05c4a0b8389f2a \ + --hash=sha256:d14186bd96783d13b8fd0e5b289f2e137a8a25479638b73a1c7e4a99a8d70753 \ + --hash=sha256:dee554f0a589377bdaea0eb70e212bf3f35dc6a51a2aa86c9351345e21fd2f07 \ + --hash=sha256:dfa500fd7ae95ca152a5f8062b870532fa3e27efcef6d00612e1f28b9f72615f \ + --hash=sha256:dff0e7dd53a0ca35b64cda843253d5cac944db26663dc097b3a1adf2c49514ad \ + --hash=sha256:e000f0533eedf3d6dfbe30bb3c58a054c58f0a7778390342fa577a0dc47adab3 \ + --hash=sha256:e851ab66a31794e40df1bc6f649cdc56c998c637f5a1b9410c97a90f6b6cb855 \ + --hash=sha256:fd689910002adfac8734f237cdea1573e38345f27ed7fd445482813b65a29457 + # via grpcio +cython==3.2.5 \ + --hash=sha256:05c22cd606ac8d14a9cf17e48668bb37734c803978bf4d793c7f11ef54c4451f \ + --hash=sha256:0a81220817ff954eddf4512a5b82089094a2f523eb1dc4ad555efd6f07b009b4 \ + --hash=sha256:0bc29c7f870b09efdb1f583fbec9592b33af81a7ce273b89c8f5163d7572d5c1 \ + --hash=sha256:220e8b160b2a4ddc362ad8a8c2ab885aa7156099702cdc48f6518a5de921b553 \ + --hash=sha256:224149d18d980e6ea5001b70fc7ce096c1891d59035dfa9cc5ede50f55804913 \ + --hash=sha256:268aecadcabcdad9f773b8a5694746e0b9ee7894b56b84e2e3a2ccb6c929ea79 \ + --hash=sha256:29243859d6824e2d33bae92fc83d591c3671b6d9ac1b757fa264b894ae906c2b \ + --hash=sha256:34d21aeb08477c9173e8be7a566b19e880a7c8109ec6bb47a4b20cb680141114 \ + --hash=sha256:3795237ab49753647e329181b140c424e8aa97543074f171f8d2c45e5014a06e \ + --hash=sha256:382122de8d6b6024fc374fabc3a2b14ba5860ed981c25055ed14fe44278b9dc7 \ + --hash=sha256:3864da4ca2ebe4660d8f672f2143b02840bf3045655222f6090486171c84298f \ + --hash=sha256:39acb30eba78ba6d995d5cf3d97d57d450663d93aac6f8b93753d2b89d768c60 \ + --hash=sha256:3dd42e4cf36ad15f265bdfec2337cc00c688c8eb6d374ffd13bb19437c27bba1 \ + --hash=sha256:3e5e519bad217a0b96fc281666720ed7d339da618acaa012bea712980b8fe6c9 \ + --hash=sha256:45baf00cb8b222a2ca7e9c48add5dac3ceb6e65be4f591150a6b6767ce1f86b0 \ + --hash=sha256:4d00e2c976ee96da4deff50506c7882ccebb4a932fc178ef27eb42bfde959839 \ + --hash=sha256:561613ddd1ee83088eb126e80a5a7d73ee6eb82e0b1aea09afbe170287e5e27f \ + --hash=sha256:56c97c5e43782ec9d9e66c465e253d2ccde0c578c364c46445efe484965524f0 \ + --hash=sha256:5887c24ebd19604b7a76d8ea57446cb562a590f7f2557e5954a69aae38b3195e \ + --hash=sha256:605c447188aecf2941709f53a2ce44862be256e54601c01b38ab710d83db8047 \ + --hash=sha256:677bb60fd8f5949e26c0a7898983967dbbb65f7628481d8480956b85ca766554 \ + --hash=sha256:69cd71b90d4e0f142fd15b2353982c3f9171fc5e613001f16bcb366ffb29004b \ + --hash=sha256:6e5d7a60835345a8bd29d3aa57070880cc3ce017ea0ade7b9f771ce4bf539b1f \ + --hash=sha256:75f5295dc1b32d084fec598f9507e6f264311d78c07da640bc9a05dc47f7ac2c \ + --hash=sha256:85b2944c3eddfc230f9082720195a2e9f869908e5a8b3185be1be832755ee7fc \ + --hash=sha256:8d7b81e6a52a84a02993f01aa5873786ba1dd593c892d93d5fe9866da0bad297 \ + --hash=sha256:91cb5b9ff599612737b3fd0dddcd401acdf904b78c2caf8cd1049501d0a53f2d \ + --hash=sha256:992a50e90d01813333752f374a4405863113059ec67102ab8d6a431a171ee328 \ + --hash=sha256:a3a423468ee77c3c5b26494f57d9c52e9318991fb7142f4c49fb01b99373e8d6 \ + --hash=sha256:a636c8b7824f3cb587eb2fdde59d8f4a14d433565508081cc290198e37567910 \ + --hash=sha256:b4bfb00baef07106a1e5e7252ace18de91225322f7fa29970995aea7c380fa21 \ + --hash=sha256:b8bc1325cf3e4394cc08a3c1ea7fa24f02f405eef0e8c156d5055f6f9a7a1565 \ + --hash=sha256:c4c79e697db55f082a2d3ba97702e71881d5bb1f56f0a80fa338e69101e4c59b \ + --hash=sha256:c80e1e5cba5b4b9890364e9360939fc298c474f25754bb4bb861270d24bda6d6 \ + --hash=sha256:cce98a9011ac6a2560b3587db22912bd0138267669ec567b0d57eddd2d741b8b \ + --hash=sha256:dc1c8cebb7df5bce37f5f8dc1e5bf04313272a5973d50a55c0ec76c83812911b \ + --hash=sha256:eb38b89e5a8eb2508a1a0832063826b0703dfb02be84e4aa34b8818ce0ca50fe \ + --hash=sha256:f4e722ceab6d795b4682d693656218671c873d4aa74119c54a2b62de0e7c48ce \ + --hash=sha256:f9b564f67b01bffa2521f475794b49f2787709cec1f91d5935a38eba37f2b359 # via # pyarrow # uvloop -dunamai==1.26.0 \ - --hash=sha256:5396ac43aa20ed059040034e9f9798c7464cf4334c6fc3da3732e29273a2f97d \ - --hash=sha256:f584edf0fda0d308cce0961f807bc90a8fe3d9ff4d62f94e72eca7b43f0ed5f6 +dunamai==1.26.1 \ + --hash=sha256:2727d939c5b4257cb01ea404372803b477f5176e5a347c43beaf89cd5072e853 \ + --hash=sha256:3b46007bd65b00b4824ead0a1aee365fd22d0ec2b9c219497d4fd48f52860c8b # via uv-dynamic-versioning expandvars==1.1.2 \ --hash=sha256:6c5822b7b756a99a356b915dd1267f52ab8a4efaa135963bd7f4bd5d368f71d7 \ @@ -253,14 +352,6 @@ flit-core==3.12.0 \ # tomli # typing-extensions # wheel -gitdb==4.0.12 \ - --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ - --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf - # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 - # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ --hash=sha256:ce0134c40d63d874ac48f48ccc678b8f3b62b8e50e9318520d2bffc752eedaf3 @@ -287,9 +378,13 @@ hatch-vcs==0.5.0 \ # via # filelock # platformdirs -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.27.0 \ + --hash=sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6 \ + --hash=sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b + # via pymilvus +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # annotated-types # atpublic @@ -314,6 +409,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -326,97 +422,164 @@ jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # via uv-dynamic-versioning -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +libcst==1.8.6 \ + --hash=sha256:04030ea4d39d69a65873b1d4d877def1c3951a7ada1824242539e399b8763d30 \ + --hash=sha256:06fc56335a45d61b7c1b856bfab4587b84cfe31e9d6368f60bb3c9129d900f58 \ + --hash=sha256:089c58e75cb142ec33738a1a4ea7760a28b40c078ab2fd26b270dac7d2633a4d \ + --hash=sha256:08bd63a8ce674be431260649e70fca1d43f1554f1591eac657f403ff8ef82c7a \ + --hash=sha256:0c13d5bd3d8414a129e9dccaf0e5785108a4441e9b266e1e5e9d1f82d1b943c9 \ + --hash=sha256:0cbe17067055829607c5ba4afa46bfa4d0dd554c0b5a583546e690b7367a29b6 \ + --hash=sha256:16cfe0cfca5fd840e1fb2c30afb628b023d3085b30c3484a79b61eae9d6fe7ba \ + --hash=sha256:1a3a5e4ee870907aa85a4076c914ae69066715a2741b821d9bf16f9579de1105 \ + --hash=sha256:1dc3b897c8b0f7323412da3f4ad12b16b909150efc42238e19cbf19b561cc330 \ + --hash=sha256:203ec2a83f259baf686b9526268cd23d048d38be5589594ef143aee50a4faf7e \ + --hash=sha256:207481197afd328aa91d02670c15b48d0256e676ce1ad4bafb6dc2b593cc58f1 \ + --hash=sha256:25eaeae6567091443b5374b4c7d33a33636a2d58f5eda02135e96fc6c8807786 \ + --hash=sha256:25fc7a1303cad7639ad45ec38c06789b4540b7258e9a108924aaa2c132af4aca \ + --hash=sha256:2f04d3672bde1704f383a19e8f8331521abdbc1ed13abb349325a02ac56e5012 \ + --hash=sha256:351ab879c2fd20d9cb2844ed1ea3e617ed72854d3d1e2b0880ede9c3eea43ba8 \ + --hash=sha256:36473e47cb199b7e6531d653ee6ffed057de1d179301e6c67f651f3af0b499d6 \ + --hash=sha256:3649a813660fbffd7bc24d3f810b1f75ac98bd40d9d6f56d1f0ee38579021073 \ + --hash=sha256:375965f34cc6f09f5f809244d3ff9bd4f6cb6699f571121cebce53622e7e0b86 \ + --hash=sha256:3a926a4b42015ee24ddfc8ae940c97bd99483d286b315b3ce82f3bafd9f53474 \ + --hash=sha256:3f4fbb7f569e69fd9e89d9d9caa57ca42c577c28ed05062f96a8c207594e75b8 \ + --hash=sha256:42a4f68121e2e9c29f49c97f6154e8527cd31021809cc4a941c7270aa64f41aa \ + --hash=sha256:44f38139fa95e488db0f8976f9c7ca39a64d6bc09f2eceef260aa1f6da6a2e42 \ + --hash=sha256:455f49a93aea4070132c30ebb6c07c2dea0ba6c1fde5ffde59fc45dbb9cfbe4b \ + --hash=sha256:4d7bbdd35f3abdfb5ac5d1a674923572dab892b126a58da81ff2726102d6ec2e \ + --hash=sha256:4fc3fef8a2c983e7abf5d633e1884c5dd6fa0dcb8f6e32035abd3d3803a3a196 \ + --hash=sha256:536567441182a62fb706e7aa954aca034827b19746832205953b2c725d254a93 \ + --hash=sha256:5432e785322aba3170352f6e72b32bea58d28abd141ac37cc9b0bf6b7c778f58 \ + --hash=sha256:55ec021a296960c92e5a33b8d93e8ad4182b0eab657021f45262510a58223de1 \ + --hash=sha256:59a7e388c57d21d63722018978a8ddba7b176e3a99bd34b9b84a576ed53f2978 \ + --hash=sha256:5dcaaebc835dfe5755bc85f9b186fb7e2895dda78e805e577fef1011d51d5a5c \ + --hash=sha256:6366ab2107425bf934b0c83311177f2a371bfc757ee8c6ad4a602d7cbcc2f363 \ + --hash=sha256:6421a930b028c5ef4a943b32a5a78b7f1bf15138214525a2088f11acbb7d3d64 \ + --hash=sha256:6609291c41f7ad0bac570bfca5af8fea1f4a27987d30a1fa8b67fe5e67e6c78d \ + --hash=sha256:6a65f844d813ab4ef351443badffa0ae358f98821561d19e18b3190f59e71996 \ + --hash=sha256:6aa11df6c58812f731172b593fcb485d7ba09ccc3b52fea6c7f26a43377dc748 \ + --hash=sha256:6b23d14a7fc0addd9795795763af26b185deb7c456b1e7cc4d5228e69dab5ce8 \ + --hash=sha256:6cad63e3a26556b020b634d25a8703b605c0e0b491426b3e6b9e12ed20f09100 \ + --hash=sha256:6d8b67874f2188399a71a71731e1ba2d1a2c3173b7565d1cc7ffb32e8fbaba5b \ + --hash=sha256:72cca15800ffc00ba25788e4626189fe0bc5fe2a0c1cb4294bce2e4df21cc073 \ + --hash=sha256:7445479ebe7d1aff0ee094ab5a1c7718e1ad78d33e3241e1a1ec65dcdbc22ffb \ + --hash=sha256:7f04febcd70e1e67917be7de513c8d4749d2e09206798558d7fe632134426ea4 \ + --hash=sha256:8066f1b70f21a2961e96bedf48649f27dfd5ea68be5cd1bed3742b047f14acde \ + --hash=sha256:819c8081e2948635cab60c603e1bbdceccdfe19104a242530ad38a36222cb88f \ + --hash=sha256:85b7025795b796dea5284d290ff69de5089fc8e989b25d6f6f15b6800be7167f \ + --hash=sha256:87e74f7d7dfcba9efa91127081e22331d7c42515f0a0ac6e81d4cf2c3ed14661 \ + --hash=sha256:8a434c521fadaf9680788b50d5c21f4048fa85ed19d7d70bd40549fbaeeecab1 \ + --hash=sha256:98fa1ca321c81fb1f02e5c43f956ca543968cc1a30b264fd8e0a2e1b0b0bf106 \ + --hash=sha256:a20c5182af04332cc94d8520792befda06d73daf2865e6dddc5161c72ea92cb9 \ + --hash=sha256:b0d8c364c44ae343937f474b2e492c1040df96d94530377c2f9263fb77096e4f \ + --hash=sha256:b188e626ce61de5ad1f95161b8557beb39253de4ec74fc9b1f25593324a0279c \ + --hash=sha256:b6c1248cc62952a3a005792b10cdef2a4e130847be9c74f33a7d617486f7e532 \ + --hash=sha256:ba9ab2b012fbd53b36cafd8f4440a6b60e7e487cd8b87428e57336b7f38409a4 \ + --hash=sha256:bb9b4077bdf8857b2483879cbbf70f1073bc255b057ec5aac8a70d901bb838e9 \ + --hash=sha256:bdb14bc4d4d83a57062fed2c5da93ecb426ff65b0dc02ddf3481040f5f074a82 \ + --hash=sha256:bff00e1c766658adbd09a175267f8b2f7616e5ee70ce45db3d7c4ce6d9f6bec7 \ + --hash=sha256:c0a0cc80aebd8aa15609dd4d330611cbc05e9b4216bcaeabba7189f99ef07c28 \ + --hash=sha256:c188d06b583900e662cd791a3f962a8c96d3dfc9b36ea315be39e0a4c4792ebf \ + --hash=sha256:c41c76e034a1094afed7057023b1d8967f968782433f7299cd170eaa01ec033e \ + --hash=sha256:c9d7aeafb1b07d25a964b148c0dda9451efb47bbbf67756e16eeae65004b0eb5 \ + --hash=sha256:cb2679ef532f9fa5be5c5a283b6357cb6e9888a8dd889c4bb2b01845a29d8c0b \ + --hash=sha256:da95b38693b989eaa8d32e452e8261cfa77fe5babfef1d8d2ac25af8c4aa7e6d \ + --hash=sha256:e00e275d4ba95d4963431ea3e409aa407566a74ee2bf309a402f84fc744abe47 \ + --hash=sha256:f1472eeafd67cdb22544e59cf3bfc25d23dc94058a68cf41f6654ff4fcb92e09 \ + --hash=sha256:f729c37c9317126da9475bdd06a7208eb52fcbd180a6341648b45a56b4ba708b \ + --hash=sha256:fea5c7fa26556eedf277d4f72779c5ede45ac3018650721edd77fd37ccd4a2d4 + # via pyarrow +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -509,22 +672,23 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -maturin==1.12.6 \ - --hash=sha256:06fc8d089f98623ce924c669b70911dfed30f9a29956c362945f727f9abc546b \ - --hash=sha256:2cb41139295eed6411d3cdafc7430738094c2721f34b7eeb44f33cac516115dc \ - --hash=sha256:351f3af1488a7cbdcff3b6d8482c17164273ac981378a13a4a9937a49aec7d71 \ - --hash=sha256:3f32e0a3720b81423c9d35c14e728cb1f954678124749776dc72d533ea1115e8 \ - --hash=sha256:6892b4176992fcc143f9d1c1c874a816e9a041248eef46433db87b0f0aff4278 \ - --hash=sha256:6dbddfe4dc7ddee60bbac854870bd7cfec660acb54d015d24597d59a1c828f61 \ - --hash=sha256:75133e56274d43b9227fd49dca9a86e32f1fd56a7b55544910c4ce978c2bb5aa \ - --hash=sha256:8fdb0f63e77ee3df0f027a120e9af78dbc31edf0eb0f263d55783c250c33b728 \ - --hash=sha256:977290159d252db946054a0555263c59b3d0c7957135c69e690f4b1558ee9983 \ - --hash=sha256:bae91976cdc8148038e13c881e1e844e5c63e58e026e8b9945aa2d19b3b4ae89 \ - --hash=sha256:c0c742beeeef7fb93b6a81bd53e75507887e396fd1003c45117658d063812dad \ - --hash=sha256:d37be3a811a7f2ee28a0fa0964187efa50e90f21da0c6135c27787fa0b6a89db \ - --hash=sha256:e90dc12bc6a38e9495692a36c9e231c4d7e0c9bfde60719468ab7d8673db3c45 \ - --hash=sha256:fa84b7493a2e80759cacc2e668fa5b444d55b9994e90707c42904f55d6322c1e +maturin==1.13.3 \ + --hash=sha256:0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b \ + --hash=sha256:1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3 \ + --hash=sha256:2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b \ + --hash=sha256:3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c \ + --hash=sha256:3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018 \ + --hash=sha256:4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f \ + --hash=sha256:49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff \ + --hash=sha256:4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0 \ + --hash=sha256:53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323 \ + --hash=sha256:771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079 \ + --hash=sha256:a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11 \ + --hash=sha256:b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273 \ + --hash=sha256:c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a \ + --hash=sha256:def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6 # via + # ast-serialize # cryptography # orjson # pydantic-core @@ -548,85 +712,85 @@ mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # pandas # pyarrow -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # hatchling # meson-python @@ -634,17 +798,18 @@ packaging==26.0 \ # scikit-build-core # setuptools-git-versioning # setuptools-scm + # vcs-versioning # wheel -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -pdm-backend==2.4.7 \ - --hash=sha256:1599e3afa6f229b30cb4d3bd9caeca42229c42eb5730abd13e0b5256ec93c9f7 \ - --hash=sha256:a509d083850378ce919d41e7a2faddfc57a1764d376913c66731125d6b14110f +pdm-backend==2.4.9 \ + --hash=sha256:8d1064751dadb0c40b1026b46826a448d85c8228a564985c62fb53d4aba538a1 \ + --hash=sha256:c41a852ccbf4b567b033db9b2ae78660d7a4ea49307719959ab88a01f0aabb2e # via # annotated-doc # fastapi @@ -657,23 +822,22 @@ pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -poetry-core==2.3.1 \ - --hash=sha256:96f791d5d7d4e040f3983d76779425cf9532690e2756a24fd5ca0f86af19ef82 \ - --hash=sha256:db1cf63b782570deb38bfba61e2304a553eef0740dc17959a50cc0f5115ee634 +poetry-core==2.4.1 \ + --hash=sha256:89dceb6c10e9c6d8650a16183400e3c9ff9ddee13b0a81023b5575334a2b3744 \ + --hash=sha256:acf06f9537cd2625bdaec926d95d90b557ba15353bc71d27a3a8a441042b5316 # via # aiohappyeyeballs # dunamai # pkgconfig # rich - # rsa # tomlkit -pybind11-global==3.0.2 \ - --hash=sha256:00a26be4cd65974133eaae7e7532e7141ccb7a88cd131995bc8d1f652852aaf9 \ - --hash=sha256:e183b4456459c35fbbbc8296eb29e241f6cf0774c0bbc3fc8349789611c6df4b +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.2 \ - --hash=sha256:432f01aeb68e361a3a7fc7575c2c7f497595bf640f747acd909ff238dd766e06 \ - --hash=sha256:f8a6500548919cc33bcd220d5f984688326f574fa97f1107f2f4fdb4c6fb019f +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -683,40 +847,116 @@ pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ --hash=sha256:c72fa49418bb7c5a10f25e050c418009898d1c051721d19f98a6fb6da59a66cf # via meson-python +pyyaml==6.0.3 \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ + --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ + --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ + --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ + --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ + --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ + --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ + --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ + --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ + --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ + --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ + --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ + --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ + --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ + --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ + --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ + --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via libcst scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ --hash=sha256:6ea4730da400f9a998ec3287bd3ebc1d751fe45ad0a93451bead8618adbc02b1 # via # duckdb # patchelf + # pyarrow # pybind11 # pybind11-global semantic-version==2.10.0 \ --hash=sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c \ --hash=sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177 # via setuptools-rust -setuptools-git-versioning==3.0.1 \ - --hash=sha256:737c4d17e848edd46e28764a19dc424d8537fcb2257022e5f4f5c0c8e9b64c80 \ - --hash=sha256:c8a599bacf163b5d215552b5701faf5480ffc4d65426a5711a010b802e1590eb +setuptools-git-versioning==3.1.0 \ + --hash=sha256:3a68f3fd58a2a5e86b0792435cfa9d8e569ab60ee5e4c29228c09da9b637bf18 \ + --hash=sha256:612dfcf184addac9e1c2216f4f229724b2390e5bf613fb925ae80b84f2529172 # via toolz -setuptools-rust==1.12.0 \ - --hash=sha256:7e7db90547f224a835b45f5ad90c983340828a345554a9a660bdb2de8605dcdd \ - --hash=sha256:d94a93f0c97751c17014565f07bdc324bee45d396cd1bba83d8e7af92b945f0c - # via maturin -setuptools-scm==7.1.0 \ - --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ - --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e - # via python-dateutil -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-rust==1.12.1 \ + --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ + --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 + # via + # libcst + # maturin +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via # anyio + # cachetools # dask # duckdb # hatch-vcs # httpx-sse # importlib-metadata + # libcst # pluggy # pyarrow # pybindgen @@ -727,77 +967,76 @@ setuptools-scm==9.2.2 \ # tenacity # tqdm # typeguard - # ujson # urllib3 # zipp -smmap==5.0.3 \ - --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ - --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f - # via gitdb -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +setuptools-scm==7.1.0 \ + --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ + --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e + # via python-dateutil +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -805,23 +1044,32 @@ typing-extensions==4.15.0 \ # via # mypy # setuptools-scm -uv-dynamic-versioning==0.13.0 \ - --hash=sha256:3220cbf10987d862d78e9931957782a274fa438d33efb1fa26b8155353749e06 \ - --hash=sha256:86d37b89fa2b6836a515301f74ea2d56a1bc59a46a74d66a24c869d1fc8f7585 +uv-dynamic-versioning==0.14.0 \ + --hash=sha256:574fbc07e87ace45c01d55967ad3b864871257b98ff5b8ac87c261227ac8db5b \ + --hash=sha256:e087c346a786e98d41292ac2315180fb700cedfb30565fc973d64ce11a112387 # via mcp +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm versioneer==0.29 \ --hash=sha256:0f1a137bb5d6811e96a79bb0486798aeae9b9c6efc24b389659cebb0ee396cb9 \ --hash=sha256:5ab283b9857211d61b53318b7c792cf68e798e765ee17c27ade9f6c924235731 # via # pandas # partd -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # async-timeout # google-crc32c + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # httpx-sse + # libcst # meson # mmh3 # pandas @@ -829,13 +1077,13 @@ wheel==0.46.3 \ # psycopg-c # psycopg-pool # pycparser - # pymilvus # python-dateutil # setuptools-git-versioning # shellingham # snowflake-connector-python # tzdata # uvloop + # wrapt # The following packages are considered to be unsafe in a requirements file: setuptools==80.10.2 \ @@ -847,6 +1095,7 @@ setuptools==80.10.2 \ # aiosignal # anyio # async-timeout + # cachetools # calver # certifi # cffi @@ -855,16 +1104,21 @@ setuptools==80.10.2 \ # dask # dill # frozenlist - # gitpython # google-api-core # google-cloud-bigquery # google-crc32c # googleapis-common-protos # greenlet # grpc-google-iam-v1 + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # gunicorn + # httptools # httpx-sse # importlib-metadata + # libcst # librt # markupsafe # maturin @@ -877,25 +1131,23 @@ setuptools==80.10.2 \ # pathspec # pluggy # prometheus-client - # propcache # proto-plus # psutil # psycopg - # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser # pyjwt - # pymilvus # pymysql # python-dotenv # pyyaml + # requests # setuptools-git-versioning # setuptools-rust # setuptools-scm # shellingham + # snowballstemmer # snowflake-connector-python # sqlalchemy # sqlglot @@ -906,23 +1158,23 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql - # types-setuptools # tzdata # uvloop + # vcs-versioning # versioneer # websockets # wrapt - # yarl # zipp -setuptools==80.9.0 \ - --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ - --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c - # via httptools +setuptools==80.3.1 \ + --hash=sha256:31e2c58dbb67c99c289f51c16d899afedae292b978f8051efaf6262d8212f927 \ + --hash=sha256:ea8e00d7992054c4c592aeb892f6ad51fe1b4d90cc6947cc45c45717c40ec537 + # via psycopg-c setuptools==82.0.1 \ --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via + # propcache # python-dateutil - # setuptools-scm - # ujson + # types-pymysql + # types-setuptools + # yarl diff --git a/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt index 2e6b889c058..56733d2fc1d 100644 --- a/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.11 --no-strip-extras pyproject.toml --extra minimal-sdist-build --no-emit-package milvus-lite --generate-hashes --output-file sdk/python/requirements/py3.11-minimal-sdist-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -152,9 +153,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -165,6 +166,41 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy async-timeout==5.0.1 \ --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 @@ -173,9 +209,9 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema @@ -184,31 +220,35 @@ babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ --hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # via sphinx -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -303,130 +343,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -436,56 +491,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt @@ -557,13 +612,13 @@ cython==3.0.12 \ --hash=sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3 \ --hash=sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -575,50 +630,50 @@ docutils==0.22.4 \ --hash=sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968 \ --hash=sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -626,9 +681,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -768,15 +823,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -786,9 +841,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -800,37 +855,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -874,139 +929,163 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -greenlet==3.3.2 \ - --hash=sha256:02b0a8682aecd4d3c6c18edf52bc8e51eacdd75c8eac52a790a210b06aa295fd \ - --hash=sha256:18cb1b7337bca281915b3c5d5ae19f4e76d35e1df80f4ad3c1a7be91fadf1082 \ - --hash=sha256:1a9172f5bf6bd88e6ba5a84e0a68afeac9dc7b6b412b245dd64f52d83c81e55b \ - --hash=sha256:1e692b2dae4cc7077cbb11b47d258533b48c8fde69a33d0d8a82e2fe8d8531d5 \ - --hash=sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f \ - --hash=sha256:1fb39a11ee2e4d94be9a76671482be9398560955c9e568550de0224e41104727 \ - --hash=sha256:20154044d9085151bc309e7689d6f7ba10027f8f5a8c0676ad398b951913d89e \ - --hash=sha256:2eaf067fc6d886931c7962e8c6bede15d2f01965560f3359b27c80bde2d151f2 \ - --hash=sha256:34308836d8370bddadb41f5a7ce96879b72e2fdfb4e87729330c6ab52376409f \ - --hash=sha256:394ead29063ee3515b4e775216cb756b2e3b4a7e55ae8fd884f17fa579e6b327 \ - --hash=sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd \ - --hash=sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2 \ - --hash=sha256:43e99d1749147ac21dde49b99c9abffcbc1e2d55c67501465ef0930d6e78e070 \ - --hash=sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99 \ - --hash=sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be \ - --hash=sha256:4c956a19350e2c37f2c48b336a3afb4bff120b36076d9d7fb68cb44e05d95b79 \ - --hash=sha256:508c7f01f1791fbc8e011bd508f6794cb95397fdb198a46cb6635eb5b78d85a7 \ - --hash=sha256:527fec58dc9f90efd594b9b700662ed3fb2493c2122067ac9c740d98080a620e \ - --hash=sha256:59b3e2c40f6706b05a9cd299c836c6aa2378cabe25d021acd80f13abf81181cf \ - --hash=sha256:5d0e35379f93a6d0222de929a25ab47b5eb35b5ef4721c2b9cbcc4036129ff1f \ - --hash=sha256:63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506 \ - --hash=sha256:64970c33a50551c7c50491671265d8954046cb6e8e2999aacdd60e439b70418a \ - --hash=sha256:6c6f8ba97d17a1e7d664151284cb3315fc5f8353e75221ed4324f84eb162b395 \ - --hash=sha256:8b466dff7a4ffda6ca975979bab80bdadde979e29fc947ac3be4451428d8b0e4 \ - --hash=sha256:8c1fdd7d1b309ff0da81d60a9688a8bd044ac4e18b250320a96fc68d31c209ca \ - --hash=sha256:8c4dd0f3997cf2512f7601563cc90dfb8957c0cff1e3a1b23991d4ea1776c492 \ - --hash=sha256:8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab \ - --hash=sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358 \ - --hash=sha256:8e4ab3cfb02993c8cc248ea73d7dae6cec0253e9afa311c9b37e603ca9fad2ce \ - --hash=sha256:94ad81f0fd3c0c0681a018a976e5c2bd2ca2d9d94895f23e7bb1af4e8af4e2d5 \ - --hash=sha256:97245cc10e5515dbc8c3104b2928f7f02b6813002770cfaffaf9a6e0fc2b94ef \ - --hash=sha256:9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d \ - --hash=sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac \ - --hash=sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55 \ - --hash=sha256:a7945dd0eab63ded0a48e4dcade82939783c172290a7903ebde9e184333ca124 \ - --hash=sha256:aa6ac98bdfd716a749b84d4034486863fd81c3abde9aa3cf8eff9127981a4ae4 \ - --hash=sha256:ab0c7e7901a00bc0a7284907273dc165b32e0d109a6713babd04471327ff7986 \ - --hash=sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd \ - --hash=sha256:ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f \ - --hash=sha256:ae9e21c84035c490506c17002f5c8ab25f980205c3e61ddb3a2a2a2e6c411fcb \ - --hash=sha256:b26b0f4428b871a751968285a1ac9648944cea09807177ac639b030bddebcea4 \ - --hash=sha256:b568183cf65b94919be4438dc28416b234b678c608cafac8874dfeeb2a9bbe13 \ - --hash=sha256:b6997d360a4e6a4e936c0f9625b1c20416b8a0ea18a8e19cabbefc712e7397ab \ - --hash=sha256:b8bddc5b73c9720bea487b3bffdb1840fe4e3656fba3bd40aa1489e9f37877ff \ - --hash=sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a \ - --hash=sha256:c2e47408e8ce1c6f1ceea0dffcdf6ebb85cc09e55c7af407c99f1112016e45e9 \ - --hash=sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86 \ - --hash=sha256:ccd21bb86944ca9be6d967cf7691e658e43417782bce90b5d2faeda0ff78a7dd \ - --hash=sha256:cd6f9e2bbd46321ba3bbb4c8a15794d32960e3b0ae2cc4d49a1a53d314805d71 \ - --hash=sha256:d248d8c23c67d2291ffd47af766e2a3aa9fa1c6703155c099feb11f526c63a92 \ - --hash=sha256:d3a62fa76a32b462a97198e4c9e99afb9ab375115e74e9a83ce180e7a496f643 \ - --hash=sha256:e26e72bec7ab387ac80caa7496e0f908ff954f31065b0ffc1f8ecb1338b11b54 \ - --hash=sha256:e3cb43ce200f59483eb82949bf1835a99cf43d7571e900d7c8d5c62cdf25d2f9 +greenlet==3.5.1 \ + --hash=sha256:001775efe7b8e758861294c7a27c28af87f3f3f1c20468a2bc618c45b346c061 \ + --hash=sha256:00929c98ec525fd9bf075875d8c5f6a983a90906cdf78a66e6de2d8e466c2a19 \ + --hash=sha256:017a544f0385d441e88714160d089d6900ef46c9eff9d99b6715a5ef2d127747 \ + --hash=sha256:089fff7a6ce8d9316d1f65ebc00273a56be258c1725b32b94de90a3a979557e1 \ + --hash=sha256:1072b4f9edcc1e192d9283a66a3e68d6b84c561de33a83d7858beb9ba1effe10 \ + --hash=sha256:10a9a1c0bfbc93d41156ffcb90c75fbc05544054faf15dcc1fdf9765f8b607f0 \ + --hash=sha256:110a1ca7b49b014b097f6078272c3f4ed31af45b254de5228b79adba879f6af9 \ + --hash=sha256:111e2390ffffc47d5840b01711dd7fac07d4c09283d0283e7f3264b14e284c64 \ + --hash=sha256:17d86354f0ae6b61bf9be5148d0dd34e06c3cb7c602c671f79f29ac3b150e659 \ + --hash=sha256:1ffdb3c0bb002c99cd8f298957e046c3dbf6006b5b7cdf11a4e19194624a0a0a \ + --hash=sha256:2baee5ca02031757ffe8cc3d69f0cc0aec7065ce362622da74f32d3bcab1c541 \ + --hash=sha256:2c18ef16bf6d4dd410e4dd52996888ea1497be26892fe5bbc73580aba4287b8e \ + --hash=sha256:2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c \ + --hash=sha256:3bfbd69cc349e43bf3a8ae1c85548ff0718efc887615c2db16c3833d7b0b072d \ + --hash=sha256:3c8bb982ad117d29478ef8f5533e97df21f1e2befd17a299257b0c96d1371c0b \ + --hash=sha256:3d955c89b75eeca4723d7cc14135f393cd47c32e2a6cb4a8e4c6e760a26b0986 \ + --hash=sha256:4378720dd888136c27215a0214d32a4d37c3852765d45bc37aad0623423cfd78 \ + --hash=sha256:45718441607f9325d948db98cbc691276059316d0358c188c246da4e1d4d23d2 \ + --hash=sha256:5028648bf2253ec4745add746129d3904121fa7fe871a76bed23c5720573ce0a \ + --hash=sha256:50ae25a67bea74ea41fb14b960bc532df73eb713417b2d61892dced82fe8d3bc \ + --hash=sha256:51518ff74664078fc51bffcc6fc529b0df5ae58da192691cee765d45ce944a2b \ + --hash=sha256:540dae7b956209af4d70a3be35927b4055f617763771e5e84a5255bea934d2f5 \ + --hash=sha256:5a56aeb7d5d9cc4b3a735efb5095bd4b4f6f0e4f93e5ca876d0e2315137b7829 \ + --hash=sha256:5e300185139abc337ade480c327183adf42a875ac7181bfe66d7d4efea31fbea \ + --hash=sha256:67821bb03e4e98664490edb787ff6af501194c29bbee0f5c1dfdcf1dc3d9d436 \ + --hash=sha256:6c09df69dc1712d131332054a858a3e5cca400967fa3a672e2324fbb0971448c \ + --hash=sha256:6ebeb75c81211f5c702576cf81f315e77e23cfdb2c7c6fcb9dd143e6de35c360 \ + --hash=sha256:73f78f9b9f0a5c06e5c946ba1e8e36f5114923b6be109ee618c54f079c3ea14f \ + --hash=sha256:7546556f0d649f99f6a361098a55f761181bb2ea12ff150bb16d26092ad88244 \ + --hash=sha256:7715a5a2c3378ba602c3a440558261e13a820bb53a82693aacd7b7f6d964e283 \ + --hash=sha256:7b5f5fae05b8ac6d176a61b60c394a8cbdc2b5b91b81793066e68745cf165e54 \ + --hash=sha256:7eacb17a9d41538a2bc4912eba5ef13823c83cb69e4d141d0813debe7163187f \ + --hash=sha256:7ffdb990dcaa0234cf9845aead5df2e3c3a8b6507d409274dd87e0d5ab05ffc2 \ + --hash=sha256:80eb4b04dadc4e67df3fae179a32c4706a3f495bc7f22fc8a81115d5f5512188 \ + --hash=sha256:88e300d136eac057b2397aa1cfd7328b4c87c7eb66a09c7bc6a1292234db474e \ + --hash=sha256:89101bfd5011e069be974903cb3a4e4523845e4ece2d62dcd8d358933c0ef249 \ + --hash=sha256:8a17c42330e261299766b75ac1ea32caa437a9453c8f65d16a13140db378ecd3 \ + --hash=sha256:8a271fcd66c74615cda6a964fda3f304267a12e50a084472218a39bb0376f563 \ + --hash=sha256:8d8a23250ea3ec7b36de8fa4b541e9e2db3ee82915cc060ab0631609ad8b28de \ + --hash=sha256:92fd6d44ac5e5a887c8a5dc4a8ba0ba908527c31c12f78c6bc7dcfe8aab279f6 \ + --hash=sha256:975eac34b44a7077ca4d421348455b94f0f518246a7f14bc6d2fdcfe5b584368 \ + --hash=sha256:9ab3c3a0b2ae6198e67c898dad5215a49f9ae0d0081b3c3ec59f333e39eeca26 \ + --hash=sha256:9b1ec3274918a81d3ea778b9e75b56b72b33f300edb6cf7f3a7fe1dae56683de \ + --hash=sha256:9d59e840387076a51016777a9328b3f2c427c6f9208a6e958bad251be50a648d \ + --hash=sha256:a0cbed8bb44e23c5b199f888f4e4ce096b45ad9f25ff74a7ad0213875e936bb2 \ + --hash=sha256:a19570c52a21420dcbc94e661994bc325c0b5b11304540fed514586da5dc8f2e \ + --hash=sha256:a203a8bd0acb0701653d3bbb26e404854a68674139ed5cbb778830f42b09bb33 \ + --hash=sha256:a4764e0bfc6a4d114c865b32520805c16a990ef5f286a514413b05d5ecd6a23d \ + --hash=sha256:a57b0d05a0448eed231d59c0ceb287dde984551e54cbc51ac2d4865712838e9c \ + --hash=sha256:a5c81f74d204d3edd136ebfd50dce53acbb776995d721a0fe801626cfc93b8cd \ + --hash=sha256:a5ea42a752d47a145eae922b605cd1634665ac3d5ec1e72402d5048e8d60d207 \ + --hash=sha256:a6fdf2433a5441ef9a95464f7c3e674775da1c8c1177fff311cee1acad4626ed \ + --hash=sha256:add5217d68b31130f0beca584d7fef4878327d2e31642b66618a14eef312b63b \ + --hash=sha256:b0703c2cef53e01baec47f7a3868009913ad71ec678bbecb42a6f40895e4ce62 \ + --hash=sha256:b9152fca4a6466e114aaec745ae61cba739903a109754a9d4e1262f01e9259b1 \ + --hash=sha256:c0141e37414c10164e702b8fb1473304221ad98f71600850c6ef7ff4880feba0 \ + --hash=sha256:c3d35f87c7253b715d13d679e0783d845910144f282cb939fe1ba4ac8616269c \ + --hash=sha256:c5551170cf4f5ff5623e9af81323751979fee2c731e2287b61f73cd27257b823 \ + --hash=sha256:cbfc69be86e10dcfef5b1e6269d1d6926552aa89ee39e1de3353360c1b6989ab \ + --hash=sha256:cc6ab7e555c8a112ad3a76e368e86e12a2754bcae1652a5602e133ec7b635523 \ + --hash=sha256:cd443683db272ebaaca03af98c0b063ab30db70ea8a31a1559f35e3f7b744ccd \ + --hash=sha256:d0932b81d72f552ded9d810d00021b64d89f2195a91ce115b893f943b7a4ab3c \ + --hash=sha256:d40a890035c0058cadbdc4af7569800fd28a0e527a0fdbb7b5f9418f176846ce \ + --hash=sha256:d5ee3ea898009fa898f85f9982255d35278c477bebe185beca249cab42d4526c \ + --hash=sha256:d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07 \ + --hash=sha256:dc71ff466927a201b08305acac451ebe1aedfcea002f62f1f2f2ac2ac1e6a135 \ + --hash=sha256:de2daaaebd1a5aa88c49045b6baf9310b3263796bd88db713edf37cf53e7bb4e \ + --hash=sha256:ded7b068c7c31c1a8657d4fd42d886b3e051ae29f88b80c5ff9d502257b0f071 \ + --hash=sha256:e5cc9606aa5f4e0bde0d3bd502b44f743864c3ffa5cfa1011b1e30f5aa02366f \ + --hash=sha256:e630136e905fe5ff43e86945ae41220b6d1470956a39220e708110ac48d01ea5 \ + --hash=sha256:e6cd99ea59dd5d89f0c956606571d79bfe6f68c9eb7f4a4083a41a7f1587edee \ + --hash=sha256:e7516cf6ae6b8a582c2770a0caed47b8a48373ed732c33d69a72913ae6ac923e \ + --hash=sha256:ea37d5a157eb9493820d3792ac4ece28619a394391d2b9f2f78057d396ff0f0f \ + --hash=sha256:ea8da1e900d758d078810d4255d8c6aa572181896a31ec79d779eb79c3adc9ad \ + --hash=sha256:ed8cdb691169715a9a492844a83246f090182247d1a5031dc78a403f68ba1e97 \ + --hash=sha256:ef08c1567c78074b22d1a200183d52d04a14df447bf70bcbb6a3507a48e776fc \ + --hash=sha256:f16ba1efc0715b680a18b8123d90dad887c6112ae3555b4b5c32c149540c6b4e \ + --hash=sha256:fa4f98af3a528f0c3fd592a26df7f376f93329c8f4d987f6bb979057af8bf5e2 \ + --hash=sha256:ffea73584b216150eab159b6d12348fb253e68757974de1e2c40d8a318ac89ed # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1014,21 +1093,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -1046,157 +1125,182 @@ hatch-vcs==0.4.0 \ --hash=sha256:093810748fe01db0d451fabcf2c1ac2688caefd232d4ede967090b1c1b07d9f7 \ --hash=sha256:b8a2b6bee54cf6f9fc93762db73890017ae59c9081d1038a41f16235ceaf8b2c # via feast (pyproject.toml) -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # feast (pyproject.toml) # hatch-fancy-pypi-readme # hatch-vcs -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1212,9 +1316,9 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1225,9 +1329,9 @@ imagesize==2.0.0 \ --hash=sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 \ --hash=sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3 # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1252,109 +1356,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1447,9 +1551,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1725,123 +1829,129 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask @@ -1853,85 +1963,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1945,6 +2055,7 @@ packaging==26.0 \ # setuptools-scm # snowflake-connector-python # sphinx + # vcs-versioning pandas==2.3.3 \ --hash=sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7 \ --hash=sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593 \ @@ -2010,9 +2121,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -2033,16 +2144,16 @@ patchelf==0.17.2.4 \ --hash=sha256:d842b51f0401460f3b1f3a3a67d2c266a8f515a5adfbfa6e7b656cb3ac2ed8bc \ --hash=sha256:d9b35ebfada70c02679ad036407d9724ffe1255122ba4ac5e4be5868618a5689 # via feast (pyproject.toml) -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ @@ -2052,151 +2163,150 @@ prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2235,68 +2345,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2309,12 +2419,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2327,141 +2435,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2469,31 +2576,31 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2516,13 +2623,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2605,9 +2712,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2615,9 +2722,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2625,6 +2732,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python # sphinx @@ -2634,9 +2742,9 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework @@ -2645,132 +2753,143 @@ roman-numerals==4.1.0 \ --hash=sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2 \ --hash=sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # via sphinx -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ @@ -2783,11 +2902,10 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus # setuptools-scm -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via hatch-vcs shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ @@ -2799,37 +2917,37 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ @@ -2863,83 +2981,79 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2955,58 +3069,58 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -3015,39 +3129,41 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via feast (pyproject.toml) -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal # anyio # fastapi + # grpcio # ibis-framework # mcp # mypy @@ -3070,101 +3186,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -3232,116 +3262,118 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3410,222 +3442,207 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata # The following packages were excluded from the output: diff --git a/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt b/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt deleted file mode 100644 index cc38cfb316c..00000000000 --- a/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt +++ /dev/null @@ -1,7078 +0,0 @@ -# This file was autogenerated by uv via the following command: -# uv pip compile -p 3.11 --no-strip-extras setup.py --extra mongodb --extra ci --generate-hashes --output-file sdk/python/requirements/py3.11-mongodb-dev-requirements.txt -accelerate==1.12.0 \ - --hash=sha256:3e2091cd341423207e2f084a6654b1efcd250dc326f2a37d6dde446e07cabb11 \ - --hash=sha256:70988c352feb481887077d2ab845125024b2a137a5090d6d7a32b57d03a45df6 - # via docling-ibm-models -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 - # via feast (setup.py) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 - # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via - # aiobotocore - # aiohttp-cors - # fsspec - # ray -aiohttp-cors==0.8.1 \ - --hash=sha256:3180cf304c5c712d626b9162b195b1db7ddf976a2a25172b35bb2448b890a80d \ - --hash=sha256:ccacf9cb84b64939ea15f859a146af1f662a6b1d68175754a07315e305fb1403 - # via ray -aioitertools==0.13.0 \ - --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ - --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c - # via aiobotocore -aiosignal==1.4.0 \ - --hash=sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e \ - --hash=sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7 - # via aiohttp -alabaster==0.7.16 \ - --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ - --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 - # via sphinx -altair==4.2.2 \ - --hash=sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5 \ - --hash=sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87 - # via great-expectations -annotated-doc==0.0.4 \ - --hash=sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320 \ - --hash=sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4 - # via fastapi -annotated-types==0.7.0 \ - --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ - --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 - # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c - # via - # elasticsearch - # httpx - # jupyter-server - # mcp - # sse-starlette - # starlette - # watchfiles -appnope==0.1.4 \ - --hash=sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee \ - --hash=sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c - # via ipykernel -argon2-cffi==25.1.0 \ - --hash=sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1 \ - --hash=sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 - # via - # jupyter-server - # minio -argon2-cffi-bindings==25.1.0 \ - --hash=sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99 \ - --hash=sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6 \ - --hash=sha256:21378b40e1b8d1655dd5310c84a40fc19a9aa5e6366e835ceb8576bf0fea716d \ - --hash=sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44 \ - --hash=sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a \ - --hash=sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f \ - --hash=sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2 \ - --hash=sha256:5acb4e41090d53f17ca1110c3427f0a130f944b896fc8c83973219c97f57b690 \ - --hash=sha256:5d588dec224e2a83edbdc785a5e6f3c6cd736f46bfd4b441bbb5aa1f5085e584 \ - --hash=sha256:6dca33a9859abf613e22733131fc9194091c1fa7cb3e131c143056b4856aa47e \ - --hash=sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0 \ - --hash=sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f \ - --hash=sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623 \ - --hash=sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b \ - --hash=sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44 \ - --hash=sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98 \ - --hash=sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500 \ - --hash=sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94 \ - --hash=sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6 \ - --hash=sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d \ - --hash=sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85 \ - --hash=sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92 \ - --hash=sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d \ - --hash=sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a \ - --hash=sha256:da0c79c23a63723aa5d782250fbf51b768abca630285262fb5144ba5ae01e520 \ - --hash=sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb - # via argon2-cffi -arrow==1.4.0 \ - --hash=sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 \ - --hash=sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7 - # via isoduration -asn1crypto==1.5.1 \ - --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ - --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 - # via snowflake-connector-python -assertpy==1.1 \ - --hash=sha256:acc64329934ad71a3221de185517a43af33e373bb44dc05b5a9b174394ef4833 - # via feast (setup.py) -asttokens==3.0.1 \ - --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ - --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 - # via stack-data -async-lru==2.1.0 \ - --hash=sha256:9eeb2fecd3fe42cc8a787fc32ead53a3a7158cc43d039c3c55ab3e4e5b2a80ed \ - --hash=sha256:fa12dcf99a42ac1280bc16c634bbaf06883809790f6304d85cdab3f666f33a7e - # via jupyterlab -async-property==0.2.2 \ - --hash=sha256:17d9bd6ca67e27915a75d92549df64b5c7174e9dc806b30a3934dc4ff0506380 \ - --hash=sha256:8924d792b5843994537f8ed411165700b27b2bd966cefc4daeefc1253442a9d7 - # via python-keycloak -async-timeout==5.0.1 \ - --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ - --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 - # via redis -atpublic==5.1 \ - --hash=sha256:135783dbd887fbddb6ef032d104da70c124f2b44b9e2d79df07b9da5334825e3 \ - --hash=sha256:abc1f4b3dbdd841cc3539e4b5e4f3ad41d658359de704e30cb36da4d4e9d3022 - # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 - # via - # aiohttp - # jsonlines - # jsonschema - # referencing -azure-core==1.38.0 \ - --hash=sha256:8194d2682245a3e4e3151a667c686464c3786fed7918b394d035bdcd61bb5993 \ - --hash=sha256:ab0c9b2cd71fecb1842d52c965c95285d3cfb38902f6766e4a471f1cd8905335 - # via - # azure-identity - # azure-storage-blob -azure-identity==1.25.1 \ - --hash=sha256:87ca8328883de6036443e1c37b40e8dc8fb74898240f61071e09d2e369361456 \ - --hash=sha256:e9edd720af03dff020223cd269fa3a61e8f345ea75443858273bcb44844ab651 - # via feast (setup.py) -azure-storage-blob==12.28.0 \ - --hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \ - --hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41 - # via feast (setup.py) -babel==2.17.0 \ - --hash=sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d \ - --hash=sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 - # via - # jupyterlab-server - # sphinx -bcrypt==5.0.0 \ - --hash=sha256:046ad6db88edb3c5ece4369af997938fb1c19d6a699b9c1b27b0db432faae4c4 \ - --hash=sha256:0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a \ - --hash=sha256:0c8e093ea2532601a6f686edbc2c6b2ec24131ff5c52f7610dd64fa4553b5464 \ - --hash=sha256:0cae4cb350934dfd74c020525eeae0a5f79257e8a201c0c176f4b84fdbf2a4b4 \ - --hash=sha256:137c5156524328a24b9fac1cb5db0ba618bc97d11970b39184c1d87dc4bf1746 \ - --hash=sha256:200af71bc25f22006f4069060c88ed36f8aa4ff7f53e67ff04d2ab3f1e79a5b2 \ - --hash=sha256:212139484ab3207b1f0c00633d3be92fef3c5f0af17cad155679d03ff2ee1e41 \ - --hash=sha256:2b732e7d388fa22d48920baa267ba5d97cca38070b69c0e2d37087b381c681fd \ - --hash=sha256:35a77ec55b541e5e583eb3436ffbbf53b0ffa1fa16ca6782279daf95d146dcd9 \ - --hash=sha256:38cac74101777a6a7d3b3e3cfefa57089b5ada650dce2baf0cbdd9d65db22a9e \ - --hash=sha256:3abeb543874b2c0524ff40c57a4e14e5d3a66ff33fb423529c88f180fd756538 \ - --hash=sha256:3ca8a166b1140436e058298a34d88032ab62f15aae1c598580333dc21d27ef10 \ - --hash=sha256:3cf67a804fc66fc217e6914a5635000259fbbbb12e78a99488e4d5ba445a71eb \ - --hash=sha256:4870a52610537037adb382444fefd3706d96d663ac44cbb2f37e3919dca3d7ef \ - --hash=sha256:48f753100931605686f74e27a7b49238122aa761a9aefe9373265b8b7aa43ea4 \ - --hash=sha256:4bfd2a34de661f34d0bda43c3e4e79df586e4716ef401fe31ea39d69d581ef23 \ - --hash=sha256:560ddb6ec730386e7b3b26b8b4c88197aaed924430e7b74666a586ac997249ef \ - --hash=sha256:5b1589f4839a0899c146e8892efe320c0fa096568abd9b95593efac50a87cb75 \ - --hash=sha256:5feebf85a9cefda32966d8171f5db7e3ba964b77fdfe31919622256f80f9cf42 \ - --hash=sha256:611f0a17aa4a25a69362dcc299fda5c8a3d4f160e2abb3831041feb77393a14a \ - --hash=sha256:61afc381250c3182d9078551e3ac3a41da14154fbff647ddf52a769f588c4172 \ - --hash=sha256:64d7ce196203e468c457c37ec22390f1a61c85c6f0b8160fd752940ccfb3a683 \ - --hash=sha256:64ee8434b0da054d830fa8e89e1c8bf30061d539044a39524ff7dec90481e5c2 \ - --hash=sha256:6b8f520b61e8781efee73cba14e3e8c9556ccfb375623f4f97429544734545b4 \ - --hash=sha256:741449132f64b3524e95cd30e5cd3343006ce146088f074f31ab26b94e6c75ba \ - --hash=sha256:744d3c6b164caa658adcb72cb8cc9ad9b4b75c7db507ab4bc2480474a51989da \ - --hash=sha256:79cfa161eda8d2ddf29acad370356b47f02387153b11d46042e93a0a95127493 \ - --hash=sha256:7aeef54b60ceddb6f30ee3db090351ecf0d40ec6e2abf41430997407a46d2254 \ - --hash=sha256:7edda91d5ab52b15636d9c30da87d2cc84f426c72b9dba7a9b4fe142ba11f534 \ - --hash=sha256:7f277a4b3390ab4bebe597800a90da0edae882c6196d3038a73adf446c4f969f \ - --hash=sha256:7f4c94dec1b5ab5d522750cb059bb9409ea8872d4494fd152b53cca99f1ddd8c \ - --hash=sha256:801cad5ccb6b87d1b430f183269b94c24f248dddbbc5c1f78b6ed231743e001c \ - --hash=sha256:83e787d7a84dbbfba6f250dd7a5efd689e935f03dd83b0f919d39349e1f23f83 \ - --hash=sha256:89042e61b5e808b67daf24a434d89bab164d4de1746b37a8d173b6b14f3db9ff \ - --hash=sha256:92864f54fb48b4c718fc92a32825d0e42265a627f956bc0361fe869f1adc3e7d \ - --hash=sha256:9d52ed507c2488eddd6a95bccee4e808d3234fa78dd370e24bac65a21212b861 \ - --hash=sha256:9fffdb387abe6aa775af36ef16f55e318dcda4194ddbf82007a6f21da29de8f5 \ - --hash=sha256:a28bc05039bdf3289d757f49d616ab3efe8cf40d8e8001ccdd621cd4f98f4fc9 \ - --hash=sha256:a5393eae5722bcef046a990b84dff02b954904c36a194f6cfc817d7dca6c6f0b \ - --hash=sha256:a71f70ee269671460b37a449f5ff26982a6f2ba493b3eabdd687b4bf35f875ac \ - --hash=sha256:b17366316c654e1ad0306a6858e189fc835eca39f7eb2cafd6aaca8ce0c40a2e \ - --hash=sha256:baade0a5657654c2984468efb7d6c110db87ea63ef5a4b54732e7e337253e44f \ - --hash=sha256:c2388ca94ffee269b6038d48747f4ce8df0ffbea43f31abfa18ac72f0218effb \ - --hash=sha256:c58b56cdfb03202b3bcc9fd8daee8e8e9b6d7e3163aa97c631dfcfcc24d36c86 \ - --hash=sha256:cde08734f12c6a4e28dc6755cd11d3bdfea608d93d958fffbe95a7026ebe4980 \ - --hash=sha256:d79e5c65dcc9af213594d6f7f1fa2c98ad3fc10431e7aa53c176b441943efbdd \ - --hash=sha256:d8d65b564ec849643d9f7ea05c6d9f0cd7ca23bdd4ac0c2dbef1104ab504543d \ - --hash=sha256:db99dca3b1fdc3db87d7c57eac0c82281242d1eabf19dcb8a6b10eb29a2e72d1 \ - --hash=sha256:dcd58e2b3a908b5ecc9b9df2f0085592506ac2d5110786018ee5e160f28e0911 \ - --hash=sha256:dd19cf5184a90c873009244586396a6a884d591a5323f0e8a5922560718d4993 \ - --hash=sha256:ddb4e1500f6efdd402218ffe34d040a1196c072e07929b9820f363a1fd1f4191 \ - --hash=sha256:e3cf5b2560c7b5a142286f69bde914494b6d8f901aaa71e453078388a50881c4 \ - --hash=sha256:ed2e1365e31fc73f1825fa830f1c8f8917ca1b3ca6185773b349c20fd606cec2 \ - --hash=sha256:edfcdcedd0d0f05850c52ba3127b1fce70b9f89e0fe5ff16517df7e81fa3cbb8 \ - --hash=sha256:f0ce778135f60799d89c9693b9b398819d15f1921ba15fe719acb3178215a7db \ - --hash=sha256:f2347d3534e76bf50bca5500989d6c1d05ed64b440408057a37673282c654927 \ - --hash=sha256:f3c08197f3039bec79cee59a606d62b96b16669cff3949f21e74796b6e3cd2be \ - --hash=sha256:f632fd56fc4e61564f78b46a2269153122db34988e78b6be8b32d28507b7eaeb \ - --hash=sha256:f6984a24db30548fd39a44360532898c33528b74aedf81c26cf29c51ee47057e \ - --hash=sha256:f70aadb7a809305226daedf75d90379c397b094755a710d7014b8b117df1ebbf \ - --hash=sha256:f748f7c2d6fd375cc93d3fba7ef4a9e3a092421b8dbf34d8d4dc06be9492dfdd \ - --hash=sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 \ - --hash=sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b - # via paramiko -beautifulsoup4==4.14.3 \ - --hash=sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb \ - --hash=sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86 - # via - # docling - # nbconvert -bigtree==1.2.0 \ - --hash=sha256:157bab9492a644243563e63a5c9a730d51267c6653046986ad42d5268bedeef7 \ - --hash=sha256:86c09a4d5cc5597db057813205f34972b4db6aac4f99fe3b97d3f322ebc13030 - # via feast (setup.py) -bleach[css]==6.3.0 \ - --hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \ - --hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6 - # via nbconvert -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 - # via - # feast (setup.py) - # ikvpy - # moto - # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b - # via - # aiobotocore - # boto3 - # moto - # s3transfer - # snowflake-connector-python -build==1.4.0 \ - --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ - --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 - # via - # feast (setup.py) - # pip-tools - # singlestoredb -cassandra-driver==3.29.3 \ - --hash=sha256:064bf45d3ca87239e11168c0110676fc64f7fdbddb4bcba9be787b8ad5f6d734 \ - --hash=sha256:0785f6e0986089e922378ae3b64b5f696440aeb595fb84c2cf3ccef220c6ae91 \ - --hash=sha256:158f7e5cb894a76a592aa0ca659a8e7c2a57ef603e04c07bbbc289a70e9ac893 \ - --hash=sha256:1c241ba08473baf31a333feb59793190d01625541c2368d3bbb0f43a586f1d6a \ - --hash=sha256:26013d768b2ea4728c09144b08c0eb86ad692e85cb15f4e52e3107abca83683c \ - --hash=sha256:27adf8869937461ad08c5fefb47857532e467b408db496db4dbf8b132a4bd623 \ - --hash=sha256:281f67af1b8df88741eef551afbb49f78e4f366a7ab23e7060a1f0d6ba655752 \ - --hash=sha256:29fc241475801872dc27c3dd1a3976373536223dd4fd1c01868ff86bdbbfd48b \ - --hash=sha256:2b72312a8b62a905da6133effbba9b0731c8e30af96e10ca77fc5c34532c6827 \ - --hash=sha256:2cb72808dfc46c40a6ee352ace181ce3170adde1cfd1447da91709a8cf482e20 \ - --hash=sha256:38216e13d6f2e0d4513a5b8806e70ce4a8f28a82962793a67371582fc2c7141b \ - --hash=sha256:3f654b01d8d49f68deedfaff1edcff314e3103d29130b2a034df6c490c522351 \ - --hash=sha256:51d6a5390e2454b599500049f0a5c72aa701db155c1e542f9a1157c1c45814b1 \ - --hash=sha256:54afde4aaa5b55fbc2c075e1c55fb14a5739459428f3bb81f849ad020f7d5bcf \ - --hash=sha256:572bd5a01089ab92da12f4f52b32b878547bbc544a798d8cfd042e7fc2601c75 \ - --hash=sha256:5a0113020d86e8f61c7a2ae3d508720cd036df7462a55926b85dd97ada27e143 \ - --hash=sha256:5f9858b5ccdf75dd89c20d74474b59dd3a2e2f86c7251b310011c46acdef3874 \ - --hash=sha256:638047c1f70fb14c9d8f743931d4f4f42aff6793b47afded3097c002ef8c1165 \ - --hash=sha256:63adca0f9219be3fe8789f4aa7b77c5f6a7bf65d6442959db52c653140ca4185 \ - --hash=sha256:7552fb7189acd06161f8feac7045a387dc9e03b3b9f7dcb5675178906cee792e \ - --hash=sha256:7a2f371af54cd1d153ef373a733889ebfbcc9c30e00429fc12a2569bad9239e1 \ - --hash=sha256:84b24f69a7bbe76302330d47422a7fcc1998a6a96ffd414a795d7d95992b49cb \ - --hash=sha256:891a1b6a111a591ad9f1c9e088846848dc9e6be030a6086c8c3aa5d2d837f266 \ - --hash=sha256:96ad742f5cbfb771df512959ab5de36e248ce9aa2c487fd81c37d5c0a627c094 \ - --hash=sha256:9abedc832e9a6636741299aae46c032d8c1248b507d8cebbaa2f48ec202904bc \ - --hash=sha256:9b7032b44769c454e96aa11483bfd167a87ea341268f1075b0ff84f780c910a9 \ - --hash=sha256:c935431682557ffcd3efc1c7bcb01b0f6769a1c90751a7154d5e3c905a6a2042 \ - --hash=sha256:e1d09691d757f5b1900a98cc3b6cc7d8506683a2188c01eca86545f91edbbaf5 \ - --hash=sha256:facd488c2b9be8bffcad5903566581e96d2863d2ec4bcad7f114d1b2b2f39ad0 \ - --hash=sha256:fcf45725ae1751cb934b9b827a7d9cd899bbd09eb1ad28e2160b4584de35ba77 \ - --hash=sha256:ff6b82ee4533f6fd4474d833e693b44b984f58337173ee98ed76bce08721a636 - # via feast (setup.py) -certifi==2026.1.4 \ - --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ - --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 - # via - # clickhouse-connect - # docling - # elastic-transport - # httpcore - # httpx - # kubernetes - # minio - # requests - # snowflake-connector-python -cffi==1.17.1 \ - --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ - --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ - --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ - --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ - --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ - --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ - --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ - --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ - --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ - --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ - --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ - --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ - --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ - --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ - --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ - --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ - --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ - --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ - --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ - --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ - --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ - --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ - --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ - --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ - --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ - --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ - --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ - --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ - --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ - --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ - --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ - --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ - --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ - --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ - --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ - --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ - --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ - --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ - --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ - --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ - --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ - --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ - --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ - --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ - --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ - --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ - --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ - --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ - --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ - --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ - --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ - --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ - --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ - --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ - --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ - --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ - --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ - --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ - --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ - --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ - --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ - --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ - --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ - --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ - --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ - --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ - --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b - # via - # feast (setup.py) - # argon2-cffi-bindings - # cryptography - # ikvpy - # pynacl - # snowflake-connector-python -cfgv==3.5.0 \ - --hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \ - --hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132 - # via pre-commit -charset-normalizer==3.4.4 \ - --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ - --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ - --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ - --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ - --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ - --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ - --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ - --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ - --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ - --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ - --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ - --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ - --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ - --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ - --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ - --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ - --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ - --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ - --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ - --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ - --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ - --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ - --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ - --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ - --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ - --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ - --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ - --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ - --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ - --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ - --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ - --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ - --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ - --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ - --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ - --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ - --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ - --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ - --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ - --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ - --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ - --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ - --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ - --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ - --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ - --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ - --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ - --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ - --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ - --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ - --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ - --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ - --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ - --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ - --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ - --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ - --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ - --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ - --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ - --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ - --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ - --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ - --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ - --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ - --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ - --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ - --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ - --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ - --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ - --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ - --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ - --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ - --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ - --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ - --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ - --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ - --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ - --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ - --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ - --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ - --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ - --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ - --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ - --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ - --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ - --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ - --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ - --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ - --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ - --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ - --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ - --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ - --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ - --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ - --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ - --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ - --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ - --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ - --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ - --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ - --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ - --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ - --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ - --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ - --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ - --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ - --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ - --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ - --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ - --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ - --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ - --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ - --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 - # via - # requests - # snowflake-connector-python -click==8.2.1 \ - --hash=sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202 \ - --hash=sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b - # via - # feast (setup.py) - # dask - # geomet - # great-expectations - # pip-tools - # ray - # typer - # uvicorn -clickhouse-connect==0.10.0 \ - --hash=sha256:01e5ba7696789b445392816180910a6bc9b0995cb86f3d503179e2be13991919 \ - --hash=sha256:0b3bbb1efdb3d71b6a2a2dcd607b0899f3b1ffe1e8125662709ee2ebbc1503cc \ - --hash=sha256:1159ee2c33e7eca40b53dda917a8b6a2ed889cb4c54f3d83b303b31ddb4f351d \ - --hash=sha256:1246137a53fb270d4bb8b51e56816d5b3f5cc595a5b2d281393308a34d8a5f43 \ - --hash=sha256:1405057ae1b6225e2de7879f582afcf7049d2cde858d0bda32b615d5f82ed330 \ - --hash=sha256:185975081de4dbec4096210f0c5adf1cf89e4c03e92f5eab1afbb70cf0636c14 \ - --hash=sha256:195f1824405501b747b572e1365c6265bb1629eeb712ce91eda91da3c5794879 \ - --hash=sha256:19cb3af95721013a0f8e88276277e23e960b08f7c14613a325a14c418207f54f \ - --hash=sha256:21e9fe9fbca37724898ff15e29c5332682786e0b95ba0c15b5f3a9c628c83873 \ - --hash=sha256:225d052bd5b885e43dd13b3a3bb251f76fcdd429b160558d2abb50ebe958f921 \ - --hash=sha256:28f2666e59bf478461693e10e84acaa9a7e32b427d2d3d72843fd7e0a7415a77 \ - --hash=sha256:2c755df1791c779b3a0a54e0789f6f55cbedfc6d6aa49046223e62986886b90d \ - --hash=sha256:3646fc9184a5469b95cf4a0846e6954e6e9e85666f030a5d2acae58fa8afb37e \ - --hash=sha256:40b7cf86d016ae6c6c3af6a7b5786f41c18632bfbc9e58d0c4a21a4c5d50c674 \ - --hash=sha256:42a5101decf2d9b49cf95619486e9f4d192e08d05886c513001f6238a21f4c70 \ - --hash=sha256:48554e836c6b56fe0854d9a9f565569010583d4960094d60b68a53f9f83042f0 \ - --hash=sha256:51193dc39f4169b0dd6da13003bbea60527dea92eb2408aecae7f1fb4ad2c5a4 \ - --hash=sha256:57239e8f49fc31d5993cb6b3bc14c00f2704d6a4a73c96ad97496c6c00144da5 \ - --hash=sha256:5b20b3f8f93743f4dcc61dc2bd9e5c374de1e57d4a601f48e46dd06d2d4f7b97 \ - --hash=sha256:5fa4f3763d46b90dc28b1f38eba8de83fbf6c9928f071dd66074e7d6de80e21b \ - --hash=sha256:60772faa54d56f0fa34650460910752a583f5948f44dddeabfafaecbca21fc54 \ - --hash=sha256:6286832cc79affc6fddfbf5563075effa65f80e7cd1481cf2b771ce317c67d08 \ - --hash=sha256:63bbb5721bfece698e155c01b8fa95ce4377c584f4d04b43f383824e8a8fa129 \ - --hash=sha256:6db414cd78333c5430e95d21c75968ad5416a37662fb7ef5536ddae1e46283ee \ - --hash=sha256:71cafb1918ec41dd46d6ec943a1d8caa3bf1f9a59c5b3d73d2dfda065d4834b7 \ - --hash=sha256:75a91c5c29d1afad1f925037747200c2a57106665dc40234bfd5e92436588874 \ - --hash=sha256:75e9de32b9a9f3c39caf5c8837eb07512fa4e8de7a182bcdbb82f2ae551d7651 \ - --hash=sha256:7907624635fe7f28e1b85c7c8b125a72679a63ecdb0b9f4250b704106ef438f8 \ - --hash=sha256:7c72d7a0564fe8e3c393ad89f19cfdc31cd7bd8b2abd9ff1a4ea66a034180a70 \ - --hash=sha256:7e0d9ad118a398c269b45591077d496ee5472cf78f4e334a709e9e2aa064eedf \ - --hash=sha256:7fbdba6b414d52e21cccb23545e3562873318a898247e9b7108aec019911f1b4 \ - --hash=sha256:7fe2a6cd98517330c66afe703fb242c0d3aa2c91f2f7dc9fb97c122c5c60c34b \ - --hash=sha256:88b4890f13163e163bf6fa61f3a013bb974c95676853b7a4e63061faf33911ac \ - --hash=sha256:8a4f20ea756e0c019e06a51d23f41edf1f0c260615e0572cb7ab0f696dfec91c \ - --hash=sha256:8d70432f1dfb88f49d7d95f62c51d762cf1fb5867e7e52aeab1f97f1bebf678e \ - --hash=sha256:92b8b6691a92d2613ee35f5759317bd4be7ba66d39bf81c4deed620feb388ca6 \ - --hash=sha256:93bf4869d27d9e86469f8fa4f0f27a618e4e63a970c3084f531c0d4706efba49 \ - --hash=sha256:9c30c902da7eb01d60b61b566603ab2069e0813b8db60b7c75a4be34b62f63e8 \ - --hash=sha256:9d9b815ec685e143ba22fb6b6803a397da2daacccaa700ced998633ff0ef5e24 \ - --hash=sha256:9eb8df083e5fda78ac7249938691c2c369e8578b5df34c709467147e8289f1d9 \ - --hash=sha256:a0256328802c6e5580513e197cef7f9ba49a99fc98e9ba410922873427569564 \ - --hash=sha256:a22457d56570eea77618e30e2a250484a7d70594dc10d636b4d5a454bb405e9a \ - --hash=sha256:a2427d312bc3526520a0be8c648479af3f6353da7a33a62db2368d6203b08efd \ - --hash=sha256:a545a9a1ebbd8489bf81dfad43ae877ce54d51ed88b635a35df9f4ea42eba6a4 \ - --hash=sha256:aacaff01523192fd319f60440908b67ca5e26c762a74a00a7c32f9913fe59e12 \ - --hash=sha256:b090c7d8e602dd084b2795265cd30610461752284763d9ad93a5d619a0e0ff21 \ - --hash=sha256:b3e393dd95bcce02307f558f6aee53bf2a1bfc83f13030c9b4e47b2045de293f \ - --hash=sha256:b8a708d38b81dcc8c13bb85549c904817e304d2b7f461246fed2945524b7a31b \ - --hash=sha256:bd6e1870df82dd57a47bc2a2a6f39c57da8aee43cc291a44d04babfdec5986dc \ - --hash=sha256:c4cf7a2e62874f173b34c593941da1d7472c9db6ffdd6de0123ecc3cfecf6b8d \ - --hash=sha256:d0afc1b2fef342f4b077c66fb8bf87bbe7ec74547940357239d35c249d45f983 \ - --hash=sha256:d69b3f55a3a2f5414db7bed45afcca940e78ce1867cf5cc0c202f7be21cf48e9 \ - --hash=sha256:db8452ef4efe1948c180a7becb572fb4926dfc69f9f5cdd29e70841b7e97e8dd \ - --hash=sha256:e32ef05046558928728d577ff6e053495cb5bf870e1f61fd2ea0c980587fefb7 \ - --hash=sha256:ef58f431e2ef3c2a91a6d5535484186f2f57f50eff791410548b17017563784b \ - --hash=sha256:f50fe43ddd9161986cc881ce2276d665d99c3d77f5d595c9e9497f9f10e0270b \ - --hash=sha256:f798b9941490e9d6aa1b86c6f06a602d0568cc12c0589c8cfc406fb871f42062 \ - --hash=sha256:f927722c5e054cf833a4112cf82d633e37d3b329f01e232754cc2678be268020 \ - --hash=sha256:fe7e6be0f40a8a77a90482944f5cc2aa39084c1570899e8d2d1191f62460365b - # via feast (setup.py) -cloudpickle==3.1.2 \ - --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ - --hash=sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a - # via dask -codeflare-sdk==0.33.1 \ - --hash=sha256:6622a73edde5042455ae7d76279a5279c55db4950533ea7f12aac2fc51d49bb8 \ - --hash=sha256:ad41ec5260217fd030904fb4b9fe62e26c3f51ac7999a5d607eb4b1359edd5e5 - # via feast (setup.py) -colorama==0.4.6 \ - --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ - --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 - # via - # feast (setup.py) - # great-expectations -colorful==0.5.8 \ - --hash=sha256:a9381fdda3337fbaba5771991020abc69676afa102646650b759927892875992 \ - --hash=sha256:bb16502b198be2f1c42ba3c52c703d5f651d826076817185f0294c1a549a7445 - # via ray -comm==0.2.3 \ - --hash=sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971 \ - --hash=sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417 - # via - # ipykernel - # ipywidgets -couchbase==4.3.2 \ - --hash=sha256:032a180afd6621358b2c73543b9c5db9939b442fc3ad6d54417c36c8a8f65838 \ - --hash=sha256:11ce688ed46edf8387bf51866618c7b4e06399e7fb34a6df002764996c109d1f \ - --hash=sha256:1f0bf68a2a67958db87a81da4d30d63915f39598482d62cd7fe9752b625dcb19 \ - --hash=sha256:220fe6b75ebbda4651a8e0370642c0f5db5da7f3b0acd9fc8e2b5b31427f9fb1 \ - --hash=sha256:2841b86eb80454279548d8102ce6e71f5bc791eb4a83cb3575b7cf4104c374b2 \ - --hash=sha256:30115cde63fc18abe587d167bbb0d37e8c253f7430e08e69f64eaca2eb7e4ca0 \ - --hash=sha256:3fb88b9f52c2099a4e25fbc30f27734c3da5c86af930de1f4102d03a3df8e77a \ - --hash=sha256:401a7d5a442196bf805746b8354636753ec12c788fba918245345c32211bdf0c \ - --hash=sha256:419a79b2a98bf3d168b264e0dfc1a0949727a2c3ef455e2ffe8e734a2fdc6e7a \ - --hash=sha256:46e492814163162a43d5cbf867eac0d685ea73c803f3238f65c0068ea4a2ce61 \ - --hash=sha256:52cdcd65fb6565f51ea4540fe823143f0fb9d650136b96b904b1650b05a06746 \ - --hash=sha256:540545fd867de02985eb16733c1b16228b0e09461e44a9c2bfad0200fdf7d09a \ - --hash=sha256:5b4eccd4a0ac30d58ea0570a1882a8c0e367a9d54d80c0f6a288e348d1b2b41e \ - --hash=sha256:5b8ee78c7a4b7451db6fcd534dc24462f2cd0e863f16495e687a23b7aecf8296 \ - --hash=sha256:687cb157c89822f463fd5373356e38ee7ebecf6306c9da9cae5b54cedad2b66d \ - --hash=sha256:6a43ce67ffe90bbb5460da5c95d778e804bcd81c037cc8a347f2966afc6c4b5a \ - --hash=sha256:6dcff2c9907ee506e63814c417212e9b51760b914609771dff92508888031dfa \ - --hash=sha256:6f3c2fc874a8b6ca7e6c8b3aaebcbfa4e14937afdb470aaa9b16724c4746b8d5 \ - --hash=sha256:6f820249b9d71593b29fb0ab3eff66ba36914076e00486ca0b99ce6ac6fd1ce9 \ - --hash=sha256:841c59deff25a3185469726d96cce0e120e6b062e724cb6981d1a2c1e2a629e5 \ - --hash=sha256:85df43305f2646203192d67a9433abb5e1098390cba6adec8c4f675ba9ba7fdc \ - --hash=sha256:86e2713759b26ee279574d740151ba4b0ad859a45fc7ac1d13fcdd39d8ee2951 \ - --hash=sha256:a4b964dd2b804036c57b670734b7aa02985dc5cf6d1a8f9f7d4af8feaf012fef \ - --hash=sha256:aac415f89c38482ac076b4b766537701e99f728cc1c5b2de8c16fa28ce7caa53 \ - --hash=sha256:b12288e15326b6fae027a419467403d6c9f3f9641cd9cfee0ab0930a9d2315cd \ - --hash=sha256:bbefa6111be033587b04b2586f5fc8d6db9a76ec138fea5288c8698c8f294bc2 \ - --hash=sha256:bd93d352ccb35c86eec9e5b4d1de015c26c15b52c80204f75189bde627b8b529 \ - --hash=sha256:bf5814a8e9efe405c9c81145c8afca7e55b964543984c9d8dc340163597b09b2 \ - --hash=sha256:c139c594118e1df6932491c26b825ac777fd201f49cda303892065e607f9c3ef \ - --hash=sha256:c18b7c937e63e6d869371d9c4b0a0f9cc1a87dba48950a4276e294c091d76ce5 \ - --hash=sha256:c50ae993c81d81ed0f02a37cbe034825408195b9fe29980b3379e2e05b2e1bec - # via feast (setup.py) -couchbase-columnar==1.0.0 \ - --hash=sha256:08b0947ee67f8fb15949e9323d60e5dbb44fb2d86d09f6e997a0bdcde6cd2b15 \ - --hash=sha256:0f5ea6a24a73008a2f5a6e3aae51a49f4bb360b198a1f3d2ca4bb22044fe9671 \ - --hash=sha256:16d97e8d87a5cedc12771167860ddf02e0d9c66486ef26f83622284a2aff5de2 \ - --hash=sha256:1e516734b59f6994c8485ebb7d0070c0927f8bffa8bc7e58b7b8e0f81657c1d2 \ - --hash=sha256:2ba2be7e7e13032696f690f11841a895afcde70f1a9b2aa959c95663eacfddc3 \ - --hash=sha256:2be53deb619b9770a23433ca83146076c12e9f6fd59b74009f3afb5664339c7b \ - --hash=sha256:2fa7cfc9fb06f9c8911453a7e7c80ce115dd9f24e753eedbab9f2b9415aae45d \ - --hash=sha256:3835259a260faf3818db0612b11acf0e5db525ecea44ee8cc9164ce3d564f1a8 \ - --hash=sha256:4879c98941fbba04c50c24c8635827bbcf44259b35488456623b6e3448351533 \ - --hash=sha256:49624c174b2bb7d1350be4c6a8554de7461d5748d9ee4d7aea6f880bed35ca2f \ - --hash=sha256:51d6c64aa89bebc3a157b812387bfca9592ef5efb8fbe84ed85a6da8618e911e \ - --hash=sha256:5743193fe5314b34e4c7dc6b4fbe60b7678af6b401ba3b30f81c03bf3c2ff8ab \ - --hash=sha256:732d25b08acd8e30fd620920e788213c8b0edf3936c74ad21d89db911510b64b \ - --hash=sha256:7469365678072900e4d5498b0c744011135037a840ca8d0d2c33dd627508f2e0 \ - --hash=sha256:776c7a52a2253250d5a75ec1f395d2d919df4b7b417005700f241dfd2b074260 \ - --hash=sha256:7c2906720ac80d5b846a077f71ffaf955af41fddd319b3c50b4496e8eec875d9 \ - --hash=sha256:82b2591691d9a188c0319ae1a5b2d67928f0c541fefbf92421a7fc604372cfcf \ - --hash=sha256:85864666cbe8fd726df310a635a522a7c27134ff66cdce455bb314ab990a0839 \ - --hash=sha256:9612170835fd2668d9968eb87a8d85ebfa38ea997d697b4265a0632ffd107b90 \ - --hash=sha256:a698825b6eb7a611fcd76a314ff470d92101505731b9252bd211a1d24ad24a32 \ - --hash=sha256:ab95caa0e5008bb2fc6b90022c6e780ceb2cf21ace2f6306e09e386f19089c18 \ - --hash=sha256:aca0a4d3453857454919dfcd2c360f91a5894c7e522c1e115335c2d3ad0673ed \ - --hash=sha256:b7a949818efdea84bf050e821e81c6293c20b7ee2c55fd68a8e772c08cdb93ba \ - --hash=sha256:cbe66361da2dda11945fcfae584bbeda153300b2dec45ebb708ba9ff53ac8373 \ - --hash=sha256:dc934b033524a4353177a792a7b525e4d2e2f67ba654dacfa80921f48e7edc1c \ - --hash=sha256:e6301c5cba0803c819ab94330c0382805f546c06dbb16108ba28af5f65cc31ab \ - --hash=sha256:ebe16a763af54ebf6aaa21bddddc28089739e37c383c206dc51353399209278d \ - --hash=sha256:efaff88520c34babf243ab0429df5c141e0dbe0c952a24e091a6e5b1374352ab \ - --hash=sha256:fa8fbddf971a2391543bc7dafaf3b581ad1a69c1fa0a474295b38a6fd8aed54f \ - --hash=sha256:fc0fad2d386c5b5df7aaaccd8751e01caa886cc640cc8c92523dd07c4e7be519 \ - --hash=sha256:fc4efa3e15190c3731478006de494b046bc57785e9c8ae99ac8b375a91683e38 - # via feast (setup.py) -coverage[toml]==7.13.1 \ - --hash=sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784 \ - --hash=sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e \ - --hash=sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3 \ - --hash=sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0 \ - --hash=sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79 \ - --hash=sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75 \ - --hash=sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6 \ - --hash=sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f \ - --hash=sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88 \ - --hash=sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b \ - --hash=sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573 \ - --hash=sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0 \ - --hash=sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2 \ - --hash=sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0 \ - --hash=sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba \ - --hash=sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd \ - --hash=sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c \ - --hash=sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673 \ - --hash=sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e \ - --hash=sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee \ - --hash=sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3 \ - --hash=sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e \ - --hash=sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461 \ - --hash=sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6 \ - --hash=sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6 \ - --hash=sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500 \ - --hash=sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a \ - --hash=sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9 \ - --hash=sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc \ - --hash=sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5 \ - --hash=sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3 \ - --hash=sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d \ - --hash=sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842 \ - --hash=sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1 \ - --hash=sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486 \ - --hash=sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29 \ - --hash=sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968 \ - --hash=sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9 \ - --hash=sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4 \ - --hash=sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c \ - --hash=sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a \ - --hash=sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465 \ - --hash=sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8 \ - --hash=sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09 \ - --hash=sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416 \ - --hash=sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894 \ - --hash=sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a \ - --hash=sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9 \ - --hash=sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4 \ - --hash=sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5 \ - --hash=sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f \ - --hash=sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb \ - --hash=sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd \ - --hash=sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae \ - --hash=sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a \ - --hash=sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e \ - --hash=sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564 \ - --hash=sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd \ - --hash=sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6 \ - --hash=sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f \ - --hash=sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7 \ - --hash=sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a \ - --hash=sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee \ - --hash=sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62 \ - --hash=sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d \ - --hash=sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef \ - --hash=sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b \ - --hash=sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1 \ - --hash=sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78 \ - --hash=sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398 \ - --hash=sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53 \ - --hash=sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d \ - --hash=sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c \ - --hash=sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909 \ - --hash=sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f \ - --hash=sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9 \ - --hash=sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90 \ - --hash=sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851 \ - --hash=sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147 \ - --hash=sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf \ - --hash=sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864 \ - --hash=sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4 \ - --hash=sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf \ - --hash=sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4 \ - --hash=sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a \ - --hash=sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4 \ - --hash=sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c \ - --hash=sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992 \ - --hash=sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c \ - --hash=sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19 \ - --hash=sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7 \ - --hash=sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766 - # via pytest-cov -cryptography==43.0.3 \ - --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ - --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ - --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ - --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ - --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ - --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ - --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ - --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ - --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ - --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ - --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ - --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ - --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ - --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ - --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ - --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ - --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ - --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ - --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ - --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ - --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ - --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ - --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ - --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ - --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ - --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ - --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 - # via - # feast (setup.py) - # azure-identity - # azure-storage-blob - # codeflare-sdk - # great-expectations - # jwcrypto - # moto - # msal - # paramiko - # pyjwt - # pyopenssl - # snowflake-connector-python - # types-pyopenssl - # types-redis -dask[dataframe]==2026.1.1 \ - --hash=sha256:12b1dbb0d6e92f287feb4076871600b2fba3a843d35ff214776ada5e9e7a1529 \ - --hash=sha256:146b0ef2918eb581e06139183a88801b4a8c52d7c37758a91f8c3b75c54b0e15 - # via feast (setup.py) -datasets==4.0.0 \ - --hash=sha256:7ef95e62025fd122882dbce6cb904c8cd3fbc829de6669a5eb939c77d50e203d \ - --hash=sha256:9657e7140a9050db13443ba21cb5de185af8af944479b00e7ff1e00a61c8dbf1 - # via feast (setup.py) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 - # via - # google-cloud-bigquery - # pandas-gbq -debugpy==1.8.19 \ - --hash=sha256:0601708223fe1cd0e27c6cce67a899d92c7d68e73690211e6788a4b0e1903f5b \ - --hash=sha256:14035cbdbb1fe4b642babcdcb5935c2da3b1067ac211c5c5a8fdc0bb31adbcaa \ - --hash=sha256:1e8c4d1bd230067bf1bbcdbd6032e5a57068638eb28b9153d008ecde288152af \ - --hash=sha256:327cb28c3ad9e17bc925efc7f7018195fd4787c2fe4b7af1eec11f1d19bdec62 \ - --hash=sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38 \ - --hash=sha256:4468de0c30012d367944f0eab4ecb8371736e8ef9522a465f61214f344c11183 \ - --hash=sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee \ - --hash=sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d \ - --hash=sha256:76f566baaf7f3e06adbe67ffedccd2ee911d1e486f55931939ce3f0fe1090774 \ - --hash=sha256:783a519e6dfb1f3cd773a9bda592f4887a65040cb0c7bd38dde410f4e53c40d4 \ - --hash=sha256:7b62c0f015120ede25e5124a5f9d8a424e1208e3d96a36c89958f046ee21fff6 \ - --hash=sha256:806d6800246244004625d5222d7765874ab2d22f3ba5f615416cf1342d61c488 \ - --hash=sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606 \ - --hash=sha256:8e19a725f5d486f20e53a1dde2ab8bb2c9607c40c00a42ab646def962b41125f \ - --hash=sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d \ - --hash=sha256:a21bfdea088f713df05fa246ba0520f6ba44dd7eaec224742f51987a6979a648 \ - --hash=sha256:b1cb98e5325da3059ca24445fca48314bfddfdf65ce1b59ff07055e723f06bd2 \ - --hash=sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976 \ - --hash=sha256:b7dd275cf2c99e53adb9654f5ae015f70415bbe2bacbe24cfee30d54b6aa03c5 \ - --hash=sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e \ - --hash=sha256:c047177ab2d286451f242b855b650d313198c4a987140d4b35218b2855a64a4a \ - --hash=sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73 \ - --hash=sha256:c5dcfa21de1f735a4f7ced4556339a109aa0f618d366ede9da0a3600f2516d8b \ - --hash=sha256:c9b9bf440141a36836bdbe4320a2b126bb38aafa85e1aed05d7bfbb0e2a278bf \ - --hash=sha256:d40c016c1f538dbf1762936e3aeb43a89b965069d9f60f9e39d35d9d25e6b809 \ - --hash=sha256:d9b6f633fd2865af2afba2beb0c1819b6ecd4aed1c8f90f5d1bbca3272306b10 \ - --hash=sha256:e24b1652a1df1ab04d81e7ead446a91c226de704ff5dde6bd0a0dbaab07aa3f2 \ - --hash=sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de \ - --hash=sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb \ - --hash=sha256:fce6da15d73be5935b4438435c53adb512326a3e11e4f90793ea87cd9f018254 - # via ipykernel -decorator==5.2.1 \ - --hash=sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360 \ - --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a - # via ipython -defusedxml==0.7.1 \ - --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ - --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 - # via nbconvert -deltalake==0.25.5 \ - --hash=sha256:0b36afba5936f74c42920c06d140535e6efc8361f659770014944d8e69fbca09 \ - --hash=sha256:0ca70e824fd7bcd16aeaaf9a43800eb9dc6c5d05b7854328c4cb4a240643ef78 \ - --hash=sha256:173e4b83fcff10f26474ae117161c3f2bdd5f44c30c20463c24b6b8b520e7656 \ - --hash=sha256:4ea62150f9d7d37dce0d973e833b91b07139031cc416ba72ebddbdd1a748f270 \ - --hash=sha256:76be7e1ed8d13f2dc933361057a44a47a89e6112d4f5ea0a73fb510bedd96efc \ - --hash=sha256:cb1c7e826fd7c3bdd3676c7471d3b551e1a3674e44cd8e3747a0017a2c0292b7 \ - --hash=sha256:e8f0d24bf64455f702da8402307b22e01f91e0f76694f7c5e33c9513011e8d29 - # via feast (setup.py) -deprecation==2.1.0 \ - --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ - --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a - # via python-keycloak -dill==0.3.8 \ - --hash=sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca \ - --hash=sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7 - # via - # feast (setup.py) - # datasets - # multiprocess -distlib==0.4.0 \ - --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ - --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d - # via virtualenv -dnspython==2.8.0 \ - --hash=sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af \ - --hash=sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f - # via - # feast (setup.py) - # pymongo -docker==7.1.0 \ - --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ - --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 - # via testcontainers -docling==2.27.0 \ - --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ - --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d - # via feast (setup.py) -docling-core[chunking]==2.60.0 \ - --hash=sha256:25499f43c9e894e6ff0be5c57a3c4fb78f87caa7808d0829fa11c056600cc2b6 \ - --hash=sha256:7703dfbad7e64fdf38bd3a9518ec80dd0162b5e7850a83fb572bfd88b62b8a39 - # via - # docling - # docling-ibm-models - # docling-parse -docling-ibm-models==3.10.3 \ - --hash=sha256:6be756e45df155a367087b93e0e5f2d65905e7e81a5f57c1d3ae57096631655a \ - --hash=sha256:e034d1398c99059998da18e38ef80af8a5d975f04de17f6e93efa075fb29cac4 - # via docling -docling-parse==4.7.3 \ - --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ - --hash=sha256:281347b3e937c1a5ffa6f8774ee603b64a0899fe8a6885573dec7eb48a3421d8 \ - --hash=sha256:29c91f78c877ae4637011efdb478f20a571e6794be924795b3469958a6401cd6 \ - --hash=sha256:32a2a8aedc56e82e2e3337b7afb83070db1fcfde86cbd93bba80ef2e331b6c13 \ - --hash=sha256:3b04459cc97a8a4929622e341b9981e23987a63af07db599afc5e1c4d389060b \ - --hash=sha256:45ec74bda63738c72e9f3989d19ef6ea7e3b1d61328ffc68d55b1b18eb6c4002 \ - --hash=sha256:53bd45241dca228715800afa0f96fdc826f7c234e9effcd5cefc86026ff19301 \ - --hash=sha256:5936e6bcb7969c2a13f38ecc75cada3b0919422dc845e96da4b0b7b3bbc394ce \ - --hash=sha256:5fc8f4770f9f6f90ba25f52451864a64394ddb158aea3a8fdda46a208c029cf6 \ - --hash=sha256:659234b800c094525476c6a97e771cd61491201e0c9f4af8ee6d39df9758bcae \ - --hash=sha256:65e0653d9617d38e73bab069dc3e7960668ff4a6b0ff45a7635c3790eeed8a08 \ - --hash=sha256:66896bbe925073e4d48f18ec29dcd611a390d6b2378fae72125e77b020cd5664 \ - --hash=sha256:6cb4fe8c62de06b70e6b38c4bd608f41ea3e9d7154a4e05f9a3c4d8944fe3a25 \ - --hash=sha256:75522790df921b6be5d86cf26d184a4af97c1c65e2d22698a9516bc049c398cf \ - --hash=sha256:91b9fbe8209922f46bbd8c6fd1a44193a4c364ff3fa398af7bcc8aaa404567d9 \ - --hash=sha256:978e7e7032760385264896871ae87cb3a04081766cc966c57e9750ce803162ac \ - --hash=sha256:9d18a5b1f7eecabed631c497a19f19d281a0d86f24bfe5d239e3df89bdc4df32 \ - --hash=sha256:a6e0f9e18d808c87ce0fe1900c74a3496a42743f4bba7ed4dd83a0e6e168644a \ - --hash=sha256:bd23eeb479355316fe807703220439fd1de1df4ca0145a49c35f71b184f87254 \ - --hash=sha256:c5a416ae2e1761914ee8d7dbfbe3858e106c876b5a7fccaa3917c038e2f126ec \ - --hash=sha256:ca64977a19ecd580a48f22137a30470d7ccf0995b2c25a74136c6facec7c617d \ - --hash=sha256:d3d86c51f9ce35a1b40b2f410f7271d9bd5fc58e7240f4cae7fdd2cef757e671 \ - --hash=sha256:d89231aa4fba3e38b80c11beb8edc07569e934c1f3935b51f57904fefe958ba5 \ - --hash=sha256:dc32b6f25a673e41b9a8112b6b841284f60dbac9427b7848a03b435460f74aee \ - --hash=sha256:dffd19ed373b0da5cea124606b183489a8686c3d18643e94485be1bdda5713ea \ - --hash=sha256:ef691045623863624f2cb7347572d0262a53cb84940ef7dd851d9f13a2eb8833 \ - --hash=sha256:f4a93f91f97055e19cade33bb957d83f8615f1d2a0103b89827aca16b31a3e22 - # via docling -docutils==0.19 \ - --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ - --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc - # via sphinx -duckdb==1.1.3 \ - --hash=sha256:00cca22df96aa3473fe4584f84888e2cf1c516e8c2dd837210daec44eadba586 \ - --hash=sha256:08935700e49c187fe0e9b2b86b5aad8a2ccd661069053e38bfaed3b9ff795efd \ - --hash=sha256:0897f83c09356206ce462f62157ce064961a5348e31ccb2a557a7531d814e70e \ - --hash=sha256:09c68522c30fc38fc972b8a75e9201616b96ae6da3444585f14cf0d116008c95 \ - --hash=sha256:0a55169d2d2e2e88077d91d4875104b58de45eff6a17a59c7dc41562c73df4be \ - --hash=sha256:0ba6baa0af33ded836b388b09433a69b8bec00263247f6bf0a05c65c897108d3 \ - --hash=sha256:183ac743f21c6a4d6adfd02b69013d5fd78e5e2cd2b4db023bc8a95457d4bc5d \ - --hash=sha256:1aa3abec8e8995a03ff1a904b0e66282d19919f562dd0a1de02f23169eeec461 \ - --hash=sha256:1c0226dc43e2ee4cc3a5a4672fddb2d76fd2cf2694443f395c02dd1bea0b7fce \ - --hash=sha256:1d9ab6143e73bcf17d62566e368c23f28aa544feddfd2d8eb50ef21034286f24 \ - --hash=sha256:2141c6b28162199999075d6031b5d63efeb97c1e68fb3d797279d31c65676269 \ - --hash=sha256:252d9b17d354beb9057098d4e5d5698e091a4f4a0d38157daeea5fc0ec161670 \ - --hash=sha256:25fb02629418c0d4d94a2bc1776edaa33f6f6ccaa00bd84eb96ecb97ae4b50e9 \ - --hash=sha256:2f073d15d11a328f2e6d5964a704517e818e930800b7f3fa83adea47f23720d3 \ - --hash=sha256:35c420f58abc79a68a286a20fd6265636175fadeca1ce964fc8ef159f3acc289 \ - --hash=sha256:4ebf5f60ddbd65c13e77cddb85fe4af671d31b851f125a4d002a313696af43f1 \ - --hash=sha256:4f0e2e5a6f5a53b79aee20856c027046fba1d73ada6178ed8467f53c3877d5e0 \ - --hash=sha256:51c6d79e05b4a0933672b1cacd6338f882158f45ef9903aef350c4427d9fc898 \ - --hash=sha256:51e7dbd968b393343b226ab3f3a7b5a68dee6d3fe59be9d802383bf916775cb8 \ - --hash=sha256:5ace6e4b1873afdd38bd6cc8fcf90310fb2d454f29c39a61d0c0cf1a24ad6c8d \ - --hash=sha256:5d57776539211e79b11e94f2f6d63de77885f23f14982e0fac066f2885fcf3ff \ - --hash=sha256:6411e21a2128d478efbd023f2bdff12464d146f92bc3e9c49247240448ace5a6 \ - --hash=sha256:647f17bd126170d96a38a9a6f25fca47ebb0261e5e44881e3782989033c94686 \ - --hash=sha256:68c3a46ab08836fe041d15dcbf838f74a990d551db47cb24ab1c4576fc19351c \ - --hash=sha256:77f26884c7b807c7edd07f95cf0b00e6d47f0de4a534ac1706a58f8bc70d0d31 \ - --hash=sha256:7c71169fa804c0b65e49afe423ddc2dc83e198640e3b041028da8110f7cd16f7 \ - --hash=sha256:80158f4c7c7ada46245837d5b6869a336bbaa28436fbb0537663fa324a2750cd \ - --hash=sha256:872d38b65b66e3219d2400c732585c5b4d11b13d7a36cd97908d7981526e9898 \ - --hash=sha256:8ee97ec337794c162c0638dda3b4a30a483d0587deda22d45e1909036ff0b739 \ - --hash=sha256:911d58c22645bfca4a5a049ff53a0afd1537bc18fedb13bc440b2e5af3c46148 \ - --hash=sha256:9c619e4849837c8c83666f2cd5c6c031300cd2601e9564b47aa5de458ff6e69d \ - --hash=sha256:9d0767ada9f06faa5afcf63eb7ba1befaccfbcfdac5ff86f0168c673dd1f47aa \ - --hash=sha256:9e3f5cd604e7c39527e6060f430769b72234345baaa0987f9500988b2814f5e4 \ - --hash=sha256:a1f83c7217c188b7ab42e6a0963f42070d9aed114f6200e3c923c8899c090f16 \ - --hash=sha256:a1fa0c502f257fa9caca60b8b1478ec0f3295f34bb2efdc10776fc731b8a6c5f \ - --hash=sha256:a30dd599b8090ea6eafdfb5a9f1b872d78bac318b6914ada2d35c7974d643640 \ - --hash=sha256:a433ae9e72c5f397c44abdaa3c781d94f94f4065bcbf99ecd39433058c64cb38 \ - --hash=sha256:a4748635875fc3c19a7320a6ae7410f9295557450c0ebab6d6712de12640929a \ - --hash=sha256:b74e121ab65dbec5290f33ca92301e3a4e81797966c8d9feef6efdf05fc6dafd \ - --hash=sha256:c443d3d502335e69fc1e35295fcfd1108f72cb984af54c536adfd7875e79cee5 \ - --hash=sha256:c5336939d83837af52731e02b6a78a446794078590aa71fd400eb17f083dda3e \ - --hash=sha256:cddc6c1a3b91dcc5f32493231b3ba98f51e6d3a44fe02839556db2b928087378 \ - --hash=sha256:d08308e0a46c748d9c30f1d67ee1143e9c5ea3fbcccc27a47e115b19e7e78aa9 \ - --hash=sha256:d5724fd8a49e24d730be34846b814b98ba7c304ca904fbdc98b47fa95c0b0cee \ - --hash=sha256:e4ef7ba97a65bd39d66f2a7080e6fb60e7c3e41d4c1e19245f90f53b98e3ac32 \ - --hash=sha256:e59087dbbb63705f2483544e01cccf07d5b35afa58be8931b224f3221361d537 \ - --hash=sha256:e86006958e84c5c02f08f9b96f4bc26990514eab329b1b4f71049b3727ce5989 \ - --hash=sha256:ecb1dc9062c1cc4d2d88a5e5cd8cc72af7818ab5a3c0f796ef0ffd60cfd3efb4 \ - --hash=sha256:eeacb598120040e9591f5a4edecad7080853aa8ac27e62d280f151f8c862afa3 \ - --hash=sha256:f549af9f7416573ee48db1cf8c9d27aeed245cb015f4b4f975289418c6cf7320 \ - --hash=sha256:f58db1b65593ff796c8ea6e63e2e144c944dd3d51c8d8e40dffa7f41693d35d3 \ - --hash=sha256:f9b47036945e1db32d70e414a10b1593aec641bd4c5e2056873d971cc21e978b - # via ibis-framework -dunamai==1.25.0 \ - --hash=sha256:7f9dc687dd3256e613b6cc978d9daabfd2bb5deb8adc541fc135ee423ffa98ab \ - --hash=sha256:a7f8360ea286d3dbaf0b6a1473f9253280ac93d619836ad4514facb70c0719d1 - # via poetry-dynamic-versioning -durationpy==0.10 \ - --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ - --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 - # via kubernetes -easyocr==1.7.2 \ - --hash=sha256:5be12f9b0e595d443c9c3d10b0542074b50f0ec2d98b141a109cd961fd1c177c - # via docling -elastic-transport==9.2.1 \ - --hash=sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4 \ - --hash=sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d - # via elasticsearch -elasticsearch==9.2.1 \ - --hash=sha256:8665f5a0b4d29a7c2772851c05ea8a09279abb7928b7d727524613bd61d75958 \ - --hash=sha256:97f473418e8976611349757287ac982acf12f4e305182863d985d5a031c36830 - # via feast (setup.py) -entrypoints==0.4 \ - --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ - --hash=sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f - # via altair -et-xmlfile==2.0.0 \ - --hash=sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa \ - --hash=sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54 - # via openpyxl -execnet==2.1.2 \ - --hash=sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd \ - --hash=sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec - # via pytest-xdist -executing==1.2.0 \ - --hash=sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc \ - --hash=sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107 - # via - # codeflare-sdk - # stack-data -faiss-cpu==1.10.0 \ - --hash=sha256:035e4d797e2db7fc0d0c90531d4a655d089ad5d1382b7a49358c1f2307b3a309 \ - --hash=sha256:2aca486fe2d680ea64a18d356206c91ff85db99fd34c19a757298c67c23262b1 \ - --hash=sha256:2f15b7957d474391fc63f02bfb8011b95317a580e4d9bd70c276f4bc179a17b3 \ - --hash=sha256:3118b5d7680b0e0a3cd64b3d29389d8384de4298739504fc661b658109540b4b \ - --hash=sha256:345a52dbfa980d24b93c94410eadf82d1eef359c6a42e5e0768cca96539f1c3c \ - --hash=sha256:449f3eb778d6d937e01a16a3170de4bb8aabfe87c7cb479b458fb790276310c5 \ - --hash=sha256:473d158fbd638d6ad5fb64469ba79a9f09d3494b5f4e8dfb4f40ce2fc335dca4 \ - --hash=sha256:49b6647aa9e159a2c4603cbff2e1b313becd98ad6e851737ab325c74fe8e0278 \ - --hash=sha256:6693474be296a7142ade1051ea18e7d85cedbfdee4b7eac9c52f83fed0467855 \ - --hash=sha256:6f8c0ef8b615c12c7bf612bd1fc51cffa49c1ddaa6207c6981f01ab6782e6b3b \ - --hash=sha256:70ebe60a560414dc8dd6cfe8fed105c8f002c0d11f765f5adfe8d63d42c0467f \ - --hash=sha256:74c5712d4890f15c661ab7b1b75867812e9596e1469759956fad900999bedbb5 \ - --hash=sha256:7a9fef4039ed877d40e41d5563417b154c7f8cd57621487dad13c4eb4f32515f \ - --hash=sha256:82ca5098de694e7b8495c1a8770e2c08df6e834922546dad0ae1284ff519ced6 \ - --hash=sha256:8ff6924b0f00df278afe70940ae86302066466580724c2f3238860039e9946f1 \ - --hash=sha256:9899c340f92bd94071d6faf4bef0ccb5362843daea42144d4ba857a2a1f67511 \ - --hash=sha256:c1108a4059c66c37c403183e566ca1ed0974a6af7557c92d49207639aab661bc \ - --hash=sha256:cb77a6a5f304890c23ffb4c566bc819c0e0cf34370b20ddff02477f2bbbaf7a3 \ - --hash=sha256:cb80b530a9ded44a7d4031a7355a237aaa0ff1f150c1176df050e0254ea5f6f6 \ - --hash=sha256:cb8473d69c3964c1bf3f8eb3e04287bb3275f536e6d9635ef32242b5f506b45d \ - --hash=sha256:dadbbb834ddc34ca7e21411811833cebaae4c5a86198dd7c2a349dbe4e7e0398 \ - --hash=sha256:dcd0cb2ec84698cbe3df9ed247d2392f09bda041ad34b92d38fa916cd019ad4b \ - --hash=sha256:e02af3696a6b9e1f9072e502f48095a305de2163c42ceb1f6f6b1db9e7ffe574 \ - --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ - --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a - # via feast (setup.py) -fastapi==0.128.0 \ - --hash=sha256:1cc179e1cef10a6be60ffe429f79b829dce99d8de32d7acb7e6c8dfdf7f2645a \ - --hash=sha256:aebd93f9716ee3b4f4fcfe13ffb7cf308d99c9f3ab5622d8877441072561582d - # via - # feast (setup.py) - # fastapi-mcp -fastapi-mcp==0.4.0 \ - --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ - --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d - # via feast (setup.py) -fastjsonschema==2.21.2 \ - --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ - --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de - # via nbformat -filelock==3.20.3 \ - --hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \ - --hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1 - # via - # datasets - # huggingface-hub - # ray - # snowflake-connector-python - # torch - # transformers - # virtualenv -filetype==1.2.0 \ - --hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \ - --hash=sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25 - # via docling -fqdn==1.5.1 \ - --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ - --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 - # via jsonschema -frozenlist==1.8.0 \ - --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ - --hash=sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0 \ - --hash=sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121 \ - --hash=sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd \ - --hash=sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7 \ - --hash=sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c \ - --hash=sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84 \ - --hash=sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d \ - --hash=sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b \ - --hash=sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79 \ - --hash=sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967 \ - --hash=sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f \ - --hash=sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4 \ - --hash=sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7 \ - --hash=sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef \ - --hash=sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9 \ - --hash=sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3 \ - --hash=sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd \ - --hash=sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087 \ - --hash=sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068 \ - --hash=sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7 \ - --hash=sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed \ - --hash=sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b \ - --hash=sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f \ - --hash=sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25 \ - --hash=sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe \ - --hash=sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143 \ - --hash=sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e \ - --hash=sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930 \ - --hash=sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37 \ - --hash=sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128 \ - --hash=sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2 \ - --hash=sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675 \ - --hash=sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f \ - --hash=sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746 \ - --hash=sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df \ - --hash=sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8 \ - --hash=sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c \ - --hash=sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0 \ - --hash=sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad \ - --hash=sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82 \ - --hash=sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29 \ - --hash=sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c \ - --hash=sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30 \ - --hash=sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf \ - --hash=sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62 \ - --hash=sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5 \ - --hash=sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383 \ - --hash=sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c \ - --hash=sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52 \ - --hash=sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d \ - --hash=sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1 \ - --hash=sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a \ - --hash=sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714 \ - --hash=sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65 \ - --hash=sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95 \ - --hash=sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1 \ - --hash=sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506 \ - --hash=sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888 \ - --hash=sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6 \ - --hash=sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41 \ - --hash=sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459 \ - --hash=sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a \ - --hash=sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608 \ - --hash=sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa \ - --hash=sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8 \ - --hash=sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1 \ - --hash=sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186 \ - --hash=sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6 \ - --hash=sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed \ - --hash=sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e \ - --hash=sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52 \ - --hash=sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 \ - --hash=sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450 \ - --hash=sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496 \ - --hash=sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a \ - --hash=sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3 \ - --hash=sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24 \ - --hash=sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178 \ - --hash=sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695 \ - --hash=sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7 \ - --hash=sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4 \ - --hash=sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e \ - --hash=sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e \ - --hash=sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61 \ - --hash=sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca \ - --hash=sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad \ - --hash=sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b \ - --hash=sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a \ - --hash=sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8 \ - --hash=sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51 \ - --hash=sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011 \ - --hash=sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8 \ - --hash=sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103 \ - --hash=sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b \ - --hash=sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda \ - --hash=sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806 \ - --hash=sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042 \ - --hash=sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e \ - --hash=sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b \ - --hash=sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef \ - --hash=sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d \ - --hash=sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567 \ - --hash=sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a \ - --hash=sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2 \ - --hash=sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0 \ - --hash=sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e \ - --hash=sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b \ - --hash=sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d \ - --hash=sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a \ - --hash=sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52 \ - --hash=sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47 \ - --hash=sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1 \ - --hash=sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94 \ - --hash=sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f \ - --hash=sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff \ - --hash=sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822 \ - --hash=sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a \ - --hash=sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11 \ - --hash=sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581 \ - --hash=sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51 \ - --hash=sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565 \ - --hash=sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 \ - --hash=sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92 \ - --hash=sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2 \ - --hash=sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5 \ - --hash=sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4 \ - --hash=sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 \ - --hash=sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027 \ - --hash=sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd - # via - # aiohttp - # aiosignal -fsspec[http]==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b - # via - # feast (setup.py) - # dask - # datasets - # huggingface-hub - # ray - # torch -geomet==1.1.0 \ - --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ - --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 - # via cassandra-driver -google-api-core[grpc]==2.29.0 \ - --hash=sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7 \ - --hash=sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9 - # via - # feast (setup.py) - # google-cloud-bigquery - # google-cloud-bigquery-storage - # google-cloud-bigtable - # google-cloud-core - # google-cloud-datastore - # google-cloud-storage - # opencensus - # pandas-gbq -google-auth==2.47.0 \ - --hash=sha256:833229070a9dfee1a353ae9877dcd2dec069a8281a4e72e72f77d4a70ff945da \ - --hash=sha256:c516d68336bfde7cf0da26aab674a36fedcf04b37ac4edd59c597178760c3498 - # via - # google-api-core - # google-auth-oauthlib - # google-cloud-bigquery - # google-cloud-bigquery-storage - # google-cloud-bigtable - # google-cloud-core - # google-cloud-datastore - # google-cloud-storage - # pandas-gbq - # pydata-google-auth -google-auth-oauthlib==1.2.4 \ - --hash=sha256:0e922eea5f2baacaf8867febb782e46e7b153236c21592ed76ab3ddb77ffd772 \ - --hash=sha256:3ca93859c6cc9003c8e12b2a0868915209d7953f05a70f4880ab57d57e56ee3e - # via - # pandas-gbq - # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.0 \ - --hash=sha256:0469bcf9e3dad3cab65b67cce98180c8c0aacf3253d47f0f8e976f299b49b5ab \ - --hash=sha256:b3ccb11caf0029f15b29569518f667553fe08f6f1459b959020c83fbbd8f2e68 - # via - # feast (setup.py) - # pandas-gbq -google-cloud-bigquery-storage==2.36.0 \ - --hash=sha256:1769e568070db672302771d2aec18341de10712aa9c4a8c549f417503e0149f0 \ - --hash=sha256:d3c1ce9d2d3a4d7116259889dcbe3c7c70506f71f6ce6bbe54aa0a68bbba8f8f - # via feast (setup.py) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b - # via feast (setup.py) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 - # via - # google-cloud-bigquery - # google-cloud-bigtable - # google-cloud-datastore - # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 - # via feast (setup.py) -google-cloud-storage==2.19.0 \ - --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ - --hash=sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2 - # via feast (setup.py) -google-crc32c==1.8.0 \ - --hash=sha256:014a7e68d623e9a4222d663931febc3033c5c7c9730785727de2a81f87d5bab8 \ - --hash=sha256:01f126a5cfddc378290de52095e2c7052be2ba7656a9f0caf4bcd1bfb1833f8a \ - --hash=sha256:0470b8c3d73b5f4e3300165498e4cf25221c7eb37f1159e221d1825b6df8a7ff \ - --hash=sha256:119fcd90c57c89f30040b47c211acee231b25a45d225e3225294386f5d258288 \ - --hash=sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411 \ - --hash=sha256:17446feb05abddc187e5441a45971b8394ea4c1b6efd88ab0af393fd9e0a156a \ - --hash=sha256:19b40d637a54cb71e0829179f6cb41835f0fbd9e8eb60552152a8b52c36cbe15 \ - --hash=sha256:2a3dc3318507de089c5384cc74d54318401410f82aa65b2d9cdde9d297aca7cb \ - --hash=sha256:3b9776774b24ba76831609ffbabce8cdf6fa2bd5e9df37b594221c7e333a81fa \ - --hash=sha256:3cc0c8912038065eafa603b238abf252e204accab2a704c63b9e14837a854962 \ - --hash=sha256:3d488e98b18809f5e322978d4506373599c0c13e6c5ad13e53bb44758e18d215 \ - --hash=sha256:3ebb04528e83b2634857f43f9bb8ef5b2bbe7f10f140daeb01b58f972d04736b \ - --hash=sha256:450dc98429d3e33ed2926fc99ee81001928d63460f8538f21a5d6060912a8e27 \ - --hash=sha256:4b8286b659c1335172e39563ab0a768b8015e88e08329fa5321f774275fc3113 \ - --hash=sha256:57a50a9035b75643996fbf224d6661e386c7162d1dfdab9bc4ca790947d1007f \ - --hash=sha256:61f58b28e0b21fcb249a8247ad0db2e64114e201e2e9b4200af020f3b6242c9f \ - --hash=sha256:6f35aaffc8ccd81ba3162443fabb920e65b1f20ab1952a31b13173a67811467d \ - --hash=sha256:71734788a88f551fbd6a97be9668a0020698e07b2bf5b3aa26a36c10cdfb27b2 \ - --hash=sha256:864abafe7d6e2c4c66395c1eb0fe12dc891879769b52a3d56499612ca93b6092 \ - --hash=sha256:86cfc00fe45a0ac7359e5214a1704e51a99e757d0272554874f419f79838c5f7 \ - --hash=sha256:87b0072c4ecc9505cfa16ee734b00cd7721d20a0f595be4d40d3d21b41f65ae2 \ - --hash=sha256:87fa445064e7db928226b2e6f0d5304ab4cd0339e664a4e9a25029f384d9bb93 \ - --hash=sha256:89c17d53d75562edfff86679244830599ee0a48efc216200691de8b02ab6b2b8 \ - --hash=sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21 \ - --hash=sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79 \ - --hash=sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2 \ - --hash=sha256:ba6aba18daf4d36ad4412feede6221414692f44d17e5428bdd81ad3fc1eee5dc \ - --hash=sha256:cb5c869c2923d56cb0c8e6bcdd73c009c36ae39b652dbe46a05eb4ef0ad01454 \ - --hash=sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2 \ - --hash=sha256:db3fe8eaf0612fc8b20fa21a5f25bd785bc3cd5be69f8f3412b0ac2ffd49e733 \ - --hash=sha256:e6584b12cb06796d285d09e33f63309a09368b9d806a551d8036a4207ea43697 \ - --hash=sha256:f4b51844ef67d6cf2e9425983274da75f18b1597bb2c998e1c0a0e8d46f8f651 \ - --hash=sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c - # via - # google-cloud-bigtable - # google-cloud-storage - # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae - # via - # google-cloud-bigquery - # google-cloud-storage -googleapis-common-protos[grpc]==1.72.0 \ - --hash=sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038 \ - --hash=sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5 - # via - # feast (setup.py) - # google-api-core - # grpc-google-iam-v1 - # grpcio-status -great-expectations==0.18.8 \ - --hash=sha256:ab41cfa3de829a4f77bdcd4a23244684cbb67fdacc734d38910164cd02ec95b6 \ - --hash=sha256:c1205bede593f679e22e0b3826d6ae1623c439cafd553f9f0bc2b0fd441f6ed9 - # via feast (setup.py) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 - # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a - # via - # feast (setup.py) - # google-api-core - # google-cloud-bigquery - # google-cloud-bigquery-storage - # google-cloud-datastore - # googleapis-common-protos - # grpc-google-iam-v1 - # grpcio-health-checking - # grpcio-reflection - # grpcio-status - # grpcio-testing - # grpcio-tools - # ikvpy - # pymilvus - # qdrant-client - # ray -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d - # via feast (setup.py) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f - # via feast (setup.py) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 - # via - # google-api-core - # ikvpy -grpcio-testing==1.62.3 \ - --hash=sha256:06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb \ - --hash=sha256:f63577f28aaa95ea525124a0fd63c3429d71f769f4179b13f5e6cbc54979bfab - # via feast (setup.py) -grpcio-tools==1.62.3 \ - --hash=sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133 \ - --hash=sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e \ - --hash=sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e \ - --hash=sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7 \ - --hash=sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf \ - --hash=sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa \ - --hash=sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5 \ - --hash=sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c \ - --hash=sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373 \ - --hash=sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184 \ - --hash=sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1 \ - --hash=sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950 \ - --hash=sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61 \ - --hash=sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0 \ - --hash=sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26 \ - --hash=sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5 \ - --hash=sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1 \ - --hash=sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23 \ - --hash=sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d \ - --hash=sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833 \ - --hash=sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492 \ - --hash=sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43 \ - --hash=sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7 \ - --hash=sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3 \ - --hash=sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc \ - --hash=sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed \ - --hash=sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a \ - --hash=sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557 \ - --hash=sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193 \ - --hash=sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325 \ - --hash=sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b \ - --hash=sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf \ - --hash=sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d \ - --hash=sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10 \ - --hash=sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9 \ - --hash=sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc \ - --hash=sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5 \ - --hash=sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5 \ - --hash=sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f \ - --hash=sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc \ - --hash=sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f \ - --hash=sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6 \ - --hash=sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29 \ - --hash=sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434 \ - --hash=sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14 \ - --hash=sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667 \ - --hash=sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57 \ - --hash=sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d - # via feast (setup.py) -gunicorn==23.0.0 \ - --hash=sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d \ - --hash=sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec - # via - # feast (setup.py) - # uvicorn-worker -h11==0.16.0 \ - --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ - --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 - # via - # httpcore - # uvicorn -h2==4.3.0 \ - --hash=sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1 \ - --hash=sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd - # via httpx -happybase==1.3.0 \ - --hash=sha256:43b6275d2865fc1364680a03f085491cd85d8b84db3c5aa94d25186685dfd87e \ - --hash=sha256:f2644cf1ef9d662fbe6f709fcfd66bf13e949f3efd4745a3230cf5f904fb7839 - # via feast (setup.py) -hazelcast-python-client==5.6.0 \ - --hash=sha256:834b87076a47c781ef80bdcb522b86abc75ff28992dfe384e47f669f06cabb18 \ - --hash=sha256:e2cec409068990ca9b4381fe97160cc2375412334782bef45ab4c8fe4d10536c - # via feast (setup.py) -hf-xet==1.2.0 \ - --hash=sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e \ - --hash=sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc \ - --hash=sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4 \ - --hash=sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382 \ - --hash=sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090 \ - --hash=sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8 \ - --hash=sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0 \ - --hash=sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd \ - --hash=sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848 \ - --hash=sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737 \ - --hash=sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a \ - --hash=sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f \ - --hash=sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc \ - --hash=sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f \ - --hash=sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865 \ - --hash=sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f \ - --hash=sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813 \ - --hash=sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5 \ - --hash=sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649 \ - --hash=sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c \ - --hash=sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69 \ - --hash=sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832 - # via huggingface-hub -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def - # via feast (setup.py) -hpack==4.1.0 \ - --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ - --hash=sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca - # via h2 -httpcore==1.0.9 \ - --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ - --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 - # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 - # via uvicorn -httpx[http2]==0.27.2 \ - --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ - --hash=sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2 - # via - # feast (setup.py) - # fastapi-mcp - # jupyterlab - # mcp - # python-keycloak - # qdrant-client -httpx-sse==0.4.3 \ - --hash=sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc \ - --hash=sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d - # via mcp -huggingface-hub==0.36.0 \ - --hash=sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25 \ - --hash=sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d - # via - # accelerate - # datasets - # docling - # docling-ibm-models - # timm - # tokenizers - # transformers -hyperframe==6.1.0 \ - --hash=sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5 \ - --hash=sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08 - # via h2 -ibis-framework[duckdb, mssql]==9.5.0 \ - --hash=sha256:145fe30d94f111cff332580c275ce77725c5ff7086eede93af0b371649d009c0 \ - --hash=sha256:1c8a29277e63ee0dfc289bc8f550164b5e3bdaec1b76b62436c37d331bb4ef84 - # via - # feast (setup.py) - # ibis-substrait -ibis-substrait==4.0.1 \ - --hash=sha256:107ca49383a3cca2fdc88f67ea2f0172620c16fa8f39c9c52305af85dd6180b4 \ - --hash=sha256:614810a173d096fbc49d87a9b419e2162a3c25d8efda1a4d57a389ce56b9041f - # via feast (setup.py) -identify==2.6.16 \ - --hash=sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0 \ - --hash=sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980 - # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 - # via - # anyio - # httpx - # jsonschema - # requests - # snowflake-connector-python - # yarl -ikvpy==0.0.36 \ - --hash=sha256:b0edf6fb6482877940f6c2b5d59a7fabe30cb554b13b88ca52805f043cfda5b3 \ - --hash=sha256:c0ce7dfb61456c283c9ba2cdeb68b3647f245c3905bca652ca2a1068804939d1 - # via feast (setup.py) -imageio==2.37.2 \ - --hash=sha256:0212ef2727ac9caa5ca4b2c75ae89454312f440a756fcfc8ef1993e718f50f8a \ - --hash=sha256:ad9adfb20335d718c03de457358ed69f141021a333c40a53e57273d8a5bd0b9b - # via scikit-image -imagesize==1.4.1 \ - --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ - --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a - # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 - # via - # dask - # opentelemetry-api -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec - # via happybase -iniconfig==2.3.0 \ - --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ - --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 - # via pytest -invoke==2.2.1 \ - --hash=sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 \ - --hash=sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707 - # via paramiko -ipykernel==7.1.0 \ - --hash=sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db \ - --hash=sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c - # via jupyterlab -ipython==9.9.0 \ - --hash=sha256:48fbed1b2de5e2c7177eefa144aba7fcb82dac514f09b57e2ac9da34ddb54220 \ - --hash=sha256:b457fe9165df2b84e8ec909a97abcf2ed88f565970efba16b1f7229c283d252b - # via - # great-expectations - # ipykernel - # ipywidgets -ipython-pygments-lexers==1.1.1 \ - --hash=sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81 \ - --hash=sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c - # via ipython -ipywidgets==8.1.2 \ - --hash=sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60 \ - --hash=sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9 - # via - # codeflare-sdk - # great-expectations -isodate==0.7.2 \ - --hash=sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15 \ - --hash=sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6 - # via azure-storage-blob -isoduration==20.11.0 \ - --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ - --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 - # via jsonschema -jedi==0.19.2 \ - --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ - --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 - # via ipython -jinja2==3.1.6 \ - --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ - --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 - # via - # feast (setup.py) - # altair - # great-expectations - # jupyter-server - # jupyterlab - # jupyterlab-server - # moto - # nbconvert - # poetry-dynamic-versioning - # sphinx - # torch -jmespath==1.0.1 \ - --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ - --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe - # via - # aiobotocore - # boto3 - # botocore -joblib==1.5.3 \ - --hash=sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 \ - --hash=sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3 - # via scikit-learn -json5==0.13.0 \ - --hash=sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc \ - --hash=sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf - # via jupyterlab-server -jsonlines==4.0.0 \ - --hash=sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74 \ - --hash=sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55 - # via docling-ibm-models -jsonpatch==1.33 \ - --hash=sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade \ - --hash=sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c - # via great-expectations -jsonpointer==3.0.0 \ - --hash=sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 \ - --hash=sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef - # via - # jsonpatch - # jsonschema -jsonref==1.1.0 \ - --hash=sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552 \ - --hash=sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9 - # via docling-core -jsonschema[format-nongpl]==4.26.0 \ - --hash=sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326 \ - --hash=sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce - # via - # feast (setup.py) - # altair - # docling-core - # great-expectations - # jupyter-events - # jupyterlab-server - # mcp - # nbformat - # ray -jsonschema-specifications==2025.9.1 \ - --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ - --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d - # via jsonschema -jupyter-client==8.8.0 \ - --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ - --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a - # via - # ipykernel - # jupyter-server - # nbclient -jupyter-core==5.9.1 \ - --hash=sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508 \ - --hash=sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407 - # via - # ipykernel - # jupyter-client - # jupyter-server - # jupyterlab - # nbclient - # nbconvert - # nbformat -jupyter-events==0.12.0 \ - --hash=sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb \ - --hash=sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b - # via jupyter-server -jupyter-lsp==2.3.0 \ - --hash=sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245 \ - --hash=sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f - # via jupyterlab -jupyter-server==2.17.0 \ - --hash=sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5 \ - --hash=sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f - # via - # jupyter-lsp - # jupyterlab - # jupyterlab-server - # notebook - # notebook-shim -jupyter-server-terminals==0.5.4 \ - --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ - --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 - # via jupyter-server -jupyterlab==4.5.2 \ - --hash=sha256:76466ebcfdb7a9bb7e2fbd6459c0e2c032ccf75be673634a84bee4b3e6b13ab6 \ - --hash=sha256:c80a6b9f6dace96a566d590c65ee2785f61e7cd4aac5b4d453dcc7d0d5e069b7 - # via notebook -jupyterlab-pygments==0.3.0 \ - --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ - --hash=sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780 - # via nbconvert -jupyterlab-server==2.28.0 \ - --hash=sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c \ - --hash=sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968 - # via - # jupyterlab - # notebook -jupyterlab-widgets==3.0.16 \ - --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ - --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 - # via ipywidgets -jwcrypto==1.5.6 \ - --hash=sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 \ - --hash=sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039 - # via python-keycloak -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee - # via - # feast (setup.py) - # codeflare-sdk -lark==1.3.1 \ - --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ - --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 - # via rfc3987-syntax -latex2mathml==3.78.1 \ - --hash=sha256:f089b6d75e85b937f99693c93e8c16c0804008672c3dd2a3d25affd36f238100 \ - --hash=sha256:f941db80bf41db33f31df87b304e8b588f8166b813b0257c11c98f7a9d0aac71 - # via docling-core -lazy-loader==0.4 \ - --hash=sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc \ - --hash=sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1 - # via scikit-image -locket==1.0.0 \ - --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ - --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 - # via partd -lxml==5.4.0 \ - --hash=sha256:00b8686694423ddae324cf614e1b9659c2edb754de617703c3d29ff568448df5 \ - --hash=sha256:073eb6dcdf1f587d9b88c8c93528b57eccda40209cf9be549d469b942b41d70b \ - --hash=sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49 \ - --hash=sha256:0a01ce7d8479dce84fc03324e3b0c9c90b1ece9a9bb6a1b6c9025e7e4520e78c \ - --hash=sha256:0be91891bdb06ebe65122aa6bf3fc94489960cf7e03033c6f83a90863b23c58b \ - --hash=sha256:0cef4feae82709eed352cd7e97ae062ef6ae9c7b5dbe3663f104cd2c0e8d94ba \ - --hash=sha256:0e108352e203c7afd0eb91d782582f00a0b16a948d204d4dec8565024fafeea5 \ - --hash=sha256:0ea0252b51d296a75f6118ed0d8696888e7403408ad42345d7dfd0d1e93309a7 \ - --hash=sha256:0fce1294a0497edb034cb416ad3e77ecc89b313cff7adbee5334e4dc0d11f422 \ - --hash=sha256:1320091caa89805df7dcb9e908add28166113dcd062590668514dbd510798c88 \ - --hash=sha256:142accb3e4d1edae4b392bd165a9abdee8a3c432a2cca193df995bc3886249c8 \ - --hash=sha256:14479c2ad1cb08b62bb941ba8e0e05938524ee3c3114644df905d2331c76cd57 \ - --hash=sha256:151d6c40bc9db11e960619d2bf2ec5829f0aaffb10b41dcf6ad2ce0f3c0b2325 \ - --hash=sha256:15a665ad90054a3d4f397bc40f73948d48e36e4c09f9bcffc7d90c87410e478a \ - --hash=sha256:1a42b3a19346e5601d1b8296ff6ef3d76038058f311902edd574461e9c036982 \ - --hash=sha256:1af80c6316ae68aded77e91cd9d80648f7dd40406cef73df841aa3c36f6907c8 \ - --hash=sha256:1b717b00a71b901b4667226bba282dd462c42ccf618ade12f9ba3674e1fabc55 \ - --hash=sha256:1dc4ca99e89c335a7ed47d38964abcb36c5910790f9bd106f2a8fa2ee0b909d2 \ - --hash=sha256:20e16c08254b9b6466526bc1828d9370ee6c0d60a4b64836bc3ac2917d1e16df \ - --hash=sha256:226046e386556a45ebc787871d6d2467b32c37ce76c2680f5c608e25823ffc84 \ - --hash=sha256:24974f774f3a78ac12b95e3a20ef0931795ff04dbb16db81a90c37f589819551 \ - --hash=sha256:24f6df5f24fc3385f622c0c9d63fe34604893bc1a5bdbb2dbf5870f85f9a404a \ - --hash=sha256:27a9ded0f0b52098ff89dd4c418325b987feed2ea5cc86e8860b0f844285d740 \ - --hash=sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e \ - --hash=sha256:2b31a3a77501d86d8ade128abb01082724c0dfd9524f542f2f07d693c9f1175f \ - --hash=sha256:2c62891b1ea3094bb12097822b3d44b93fc6c325f2043c4d2736a8ff09e65f60 \ - --hash=sha256:2dc191e60425ad70e75a68c9fd90ab284df64d9cd410ba8d2b641c0c45bc006e \ - --hash=sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6 \ - --hash=sha256:32697d2ea994e0db19c1df9e40275ffe84973e4232b5c274f47e7c1ec9763cdd \ - --hash=sha256:3a3178b4873df8ef9457a4875703488eb1622632a9cee6d76464b60e90adbfcd \ - --hash=sha256:3b9c2754cef6963f3408ab381ea55f47dabc6f78f4b8ebb0f0b25cf1ac1f7609 \ - --hash=sha256:3d3c30ba1c9b48c68489dc1829a6eede9873f52edca1dda900066542528d6b20 \ - --hash=sha256:3e6d5557989cdc3ebb5302bbdc42b439733a841891762ded9514e74f60319ad6 \ - --hash=sha256:4025bf2884ac4370a3243c5aa8d66d3cb9e15d3ddd0af2d796eccc5f0244390e \ - --hash=sha256:4291d3c409a17febf817259cb37bc62cb7eb398bcc95c1356947e2871911ae61 \ - --hash=sha256:4329422de653cdb2b72afa39b0aa04252fca9071550044904b2e7036d9d97fe4 \ - --hash=sha256:43d549b876ce64aa18b2328faff70f5877f8c6dede415f80a2f799d31644d776 \ - --hash=sha256:460508a4b07364d6abf53acaa0a90b6d370fafde5693ef37602566613a9b0779 \ - --hash=sha256:47fb24cc0f052f0576ea382872b3fc7e1f7e3028e53299ea751839418ade92a6 \ - --hash=sha256:48b4afaf38bf79109bb060d9016fad014a9a48fb244e11b94f74ae366a64d252 \ - --hash=sha256:497cab4d8254c2a90bf988f162ace2ddbfdd806fce3bda3f581b9d24c852e03c \ - --hash=sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92 \ - --hash=sha256:4b7ce10634113651d6f383aa712a194179dcd496bd8c41e191cec2099fa09de5 \ - --hash=sha256:4cd915c0fb1bed47b5e6d6edd424ac25856252f09120e3e8ba5154b6b921860e \ - --hash=sha256:4d885698f5019abe0de3d352caf9466d5de2baded00a06ef3f1216c1a58ae78f \ - --hash=sha256:4f5322cf38fe0e21c2d73901abf68e6329dc02a4994e483adbcf92b568a09a54 \ - --hash=sha256:50441c9de951a153c698b9b99992e806b71c1f36d14b154592580ff4a9d0d877 \ - --hash=sha256:529024ab3a505fed78fe3cc5ddc079464e709f6c892733e3f5842007cec8ac6e \ - --hash=sha256:53370c26500d22b45182f98847243efb518d268374a9570409d2e2276232fd37 \ - --hash=sha256:53d9469ab5460402c19553b56c3648746774ecd0681b1b27ea74d5d8a3ef5590 \ - --hash=sha256:56dbdbab0551532bb26c19c914848d7251d73edb507c3079d6805fa8bba5b706 \ - --hash=sha256:5a99d86351f9c15e4a901fc56404b485b1462039db59288b203f8c629260a142 \ - --hash=sha256:5cca36a194a4eb4e2ed6be36923d3cffd03dcdf477515dea687185506583d4c9 \ - --hash=sha256:5f11a1526ebd0dee85e7b1e39e39a0cc0d9d03fb527f56d8457f6df48a10dc0c \ - --hash=sha256:61c7bbf432f09ee44b1ccaa24896d21075e533cd01477966a5ff5a71d88b2f56 \ - --hash=sha256:639978bccb04c42677db43c79bdaa23785dc7f9b83bfd87570da8207872f1ce5 \ - --hash=sha256:63e7968ff83da2eb6fdda967483a7a023aa497d85ad8f05c3ad9b1f2e8c84987 \ - --hash=sha256:664cdc733bc87449fe781dbb1f309090966c11cc0c0cd7b84af956a02a8a4729 \ - --hash=sha256:67ed8a40665b84d161bae3181aa2763beea3747f748bca5874b4af4d75998f87 \ - --hash=sha256:67f779374c6b9753ae0a0195a892a1c234ce8416e4448fe1e9f34746482070a7 \ - --hash=sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7 \ - --hash=sha256:696ea9e87442467819ac22394ca36cb3d01848dad1be6fac3fb612d3bd5a12cf \ - --hash=sha256:6ef80aeac414f33c24b3815ecd560cee272786c3adfa5f31316d8b349bfade28 \ - --hash=sha256:72ac9762a9f8ce74c9eed4a4e74306f2f18613a6b71fa065495a67ac227b3056 \ - --hash=sha256:75133890e40d229d6c5837b0312abbe5bac1c342452cf0e12523477cd3aa21e7 \ - --hash=sha256:7605c1c32c3d6e8c990dd28a0970a3cbbf1429d5b92279e37fda05fb0c92190e \ - --hash=sha256:773e27b62920199c6197130632c18fb7ead3257fce1ffb7d286912e56ddb79e0 \ - --hash=sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872 \ - --hash=sha256:79d5bfa9c1b455336f52343130b2067164040604e41f6dc4d8313867ed540079 \ - --hash=sha256:7a62cc23d754bb449d63ff35334acc9f5c02e6dae830d78dab4dd12b78a524f4 \ - --hash=sha256:7be701c24e7f843e6788353c055d806e8bd8466b52907bafe5d13ec6a6dbaecd \ - --hash=sha256:7ca56ebc2c474e8f3d5761debfd9283b8b18c76c4fc0967b74aeafba1f5647f9 \ - --hash=sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121 \ - --hash=sha256:891f7f991a68d20c75cb13c5c9142b2a3f9eb161f1f12a9489c82172d1f133c0 \ - --hash=sha256:8f82125bc7203c5ae8633a7d5d20bcfdff0ba33e436e4ab0abc026a53a8960b7 \ - --hash=sha256:91505d3ddebf268bb1588eb0f63821f738d20e1e7f05d3c647a5ca900288760b \ - --hash=sha256:942a5d73f739ad7c452bf739a62a0f83e2578afd6b8e5406308731f4ce78b16d \ - --hash=sha256:9454b8d8200ec99a224df8854786262b1bd6461f4280064c807303c642c05e76 \ - --hash=sha256:9459e6892f59ecea2e2584ee1058f5d8f629446eab52ba2305ae13a32a059530 \ - --hash=sha256:9776af1aad5a4b4a1317242ee2bea51da54b2a7b7b48674be736d463c999f37d \ - --hash=sha256:97dac543661e84a284502e0cf8a67b5c711b0ad5fb661d1bd505c02f8cf716d7 \ - --hash=sha256:98a3912194c079ef37e716ed228ae0dcb960992100461b704aea4e93af6b0bb9 \ - --hash=sha256:9b4a3bd174cc9cdaa1afbc4620c049038b441d6ba07629d89a83b408e54c35cd \ - --hash=sha256:9c886b481aefdf818ad44846145f6eaf373a20d200b5ce1a5c8e1bc2d8745410 \ - --hash=sha256:9ceaf423b50ecfc23ca00b7f50b64baba85fb3fb91c53e2c9d00bc86150c7e40 \ - --hash=sha256:a11a96c3b3f7551c8a8109aa65e8594e551d5a84c76bf950da33d0fb6dfafab7 \ - --hash=sha256:a3bcdde35d82ff385f4ede021df801b5c4a5bcdfb61ea87caabcebfc4945dc1b \ - --hash=sha256:a7fb111eef4d05909b82152721a59c1b14d0f365e2be4c742a473c5d7372f4f5 \ - --hash=sha256:a81e1196f0a5b4167a8dafe3a66aa67c4addac1b22dc47947abd5d5c7a3f24b5 \ - --hash=sha256:a8c9b7f16b63e65bbba889acb436a1034a82d34fa09752d754f88d708eca80e1 \ - --hash=sha256:a8ef956fce64c8551221f395ba21d0724fed6b9b6242ca4f2f7beb4ce2f41997 \ - --hash=sha256:ab339536aa798b1e17750733663d272038bf28069761d5be57cb4a9b0137b4f8 \ - --hash=sha256:ac7ba71f9561cd7d7b55e1ea5511543c0282e2b6450f122672a2694621d63b7e \ - --hash=sha256:aea53d51859b6c64e7c51d522c03cc2c48b9b5d6172126854cc7f01aa11f52bc \ - --hash=sha256:aea7c06667b987787c7d1f5e1dfcd70419b711cdb47d6b4bb4ad4b76777a0563 \ - --hash=sha256:aefe1a7cb852fa61150fcb21a8c8fcea7b58c4cb11fbe59c97a0a4b31cae3c8c \ - --hash=sha256:b0989737a3ba6cf2a16efb857fb0dfa20bc5c542737fddb6d893fde48be45433 \ - --hash=sha256:b108134b9667bcd71236c5a02aad5ddd073e372fb5d48ea74853e009fe38acb6 \ - --hash=sha256:b12cb6527599808ada9eb2cd6e0e7d3d8f13fe7bbb01c6311255a15ded4c7ab4 \ - --hash=sha256:b5aff6f3e818e6bdbbb38e5967520f174b18f539c2b9de867b1e7fde6f8d95a4 \ - --hash=sha256:b67319b4aef1a6c56576ff544b67a2a6fbd7eaee485b241cabf53115e8908b8f \ - --hash=sha256:b7c86884ad23d61b025989d99bfdd92a7351de956e01c61307cb87035960bcb1 \ - --hash=sha256:b92b69441d1bd39f4940f9eadfa417a25862242ca2c396b406f9272ef09cdcaa \ - --hash=sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f \ - --hash=sha256:bda3ea44c39eb74e2488297bb39d47186ed01342f0022c8ff407c250ac3f498e \ - --hash=sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063 \ - --hash=sha256:c5681160758d3f6ac5b4fea370495c48aac0989d6a0f01bb9a72ad8ef5ab75c4 \ - --hash=sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5 \ - --hash=sha256:c6364038c519dffdbe07e3cf42e6a7f8b90c275d4d1617a69bb59734c1a2d571 \ - --hash=sha256:c70e93fba207106cb16bf852e421c37bbded92acd5964390aad07cb50d60f5cf \ - --hash=sha256:ca755eebf0d9e62d6cb013f1261e510317a41bf4650f22963474a663fdfe02aa \ - --hash=sha256:cccd007d5c95279e529c146d095f1d39ac05139de26c098166c4beb9374b0f4d \ - --hash=sha256:ce31158630a6ac85bddd6b830cffd46085ff90498b397bd0a259f59d27a12188 \ - --hash=sha256:ce9c671845de9699904b1e9df95acfe8dfc183f2310f163cdaa91a3535af95de \ - --hash=sha256:d12832e1dbea4be280b22fd0ea7c9b87f0d8fc51ba06e92dc62d52f804f78ebd \ - --hash=sha256:d2ed1b3cb9ff1c10e6e8b00941bb2e5bb568b307bfc6b17dffbbe8be5eecba86 \ - --hash=sha256:d5663bc1b471c79f5c833cffbc9b87d7bf13f87e055a5c86c363ccd2348d7e82 \ - --hash=sha256:d90b729fd2732df28130c064aac9bb8aff14ba20baa4aee7bd0795ff1187545f \ - --hash=sha256:dc0af80267edc68adf85f2a5d9be1cdf062f973db6790c1d065e45025fa26140 \ - --hash=sha256:de5b4e1088523e2b6f730d0509a9a813355b7f5659d70eb4f319c76beea2e250 \ - --hash=sha256:de6f6bb8a7840c7bf216fb83eec4e2f79f7325eca8858167b68708b929ab2172 \ - --hash=sha256:df53330a3bff250f10472ce96a9af28628ff1f4efc51ccba351a8820bca2a8ba \ - --hash=sha256:e094ec83694b59d263802ed03a8384594fcce477ce484b0cbcd0008a211ca751 \ - --hash=sha256:e794f698ae4c5084414efea0f5cc9f4ac562ec02d66e1484ff822ef97c2cadff \ - --hash=sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c \ - --hash=sha256:eaf24066ad0b30917186420d51e2e3edf4b0e2ea68d8cd885b14dc8afdcf6556 \ - --hash=sha256:ecf4c4b83f1ab3d5a7ace10bafcb6f11df6156857a3c418244cef41ca9fa3e44 \ - --hash=sha256:ef5a7178fcc73b7d8c07229e89f8eb45b2908a9238eb90dcfc46571ccf0383b8 \ - --hash=sha256:f5cb182f6396706dc6cc1896dd02b1c889d644c081b0cdec38747573db88a7d7 \ - --hash=sha256:fa0e294046de09acd6146be0ed6727d1f42ded4ce3ea1e9a19c11b6774eea27c \ - --hash=sha256:fb54f7c6bafaa808f27166569b1511fc42701a7713858dddc08afdde9746849e \ - --hash=sha256:fd3be6481ef54b8cfd0e1e953323b7aa9d9789b94842d0e5b142ef4bb7999539 - # via - # docling - # python-docx - # python-pptx -lz4==4.4.5 \ - --hash=sha256:0846e6e78f374156ccf21c631de80967e03cc3c01c373c665789dc0c5431e7fc \ - --hash=sha256:0bba042ec5a61fa77c7e380351a61cb768277801240249841defd2ff0a10742f \ - --hash=sha256:12233624f1bc2cebc414f9efb3113a03e89acce3ab6f72035577bc61b270d24d \ - --hash=sha256:13254bd78fef50105872989a2dc3418ff09aefc7d0765528adc21646a7288294 \ - --hash=sha256:15551280f5656d2206b9b43262799c89b25a25460416ec554075a8dc568e4397 \ - --hash=sha256:1dd4d91d25937c2441b9fc0f4af01704a2d09f30a38c5798bc1d1b5a15ec9581 \ - --hash=sha256:214e37cfe270948ea7eb777229e211c601a3e0875541c1035ab408fbceaddf50 \ - --hash=sha256:216ca0c6c90719731c64f41cfbd6f27a736d7e50a10b70fad2a9c9b262ec923d \ - --hash=sha256:24092635f47538b392c4eaeff14c7270d2c8e806bf4be2a6446a378591c5e69e \ - --hash=sha256:28ccaeb7c5222454cd5f60fcd152564205bcb801bd80e125949d2dfbadc76bbd \ - --hash=sha256:2a2b7504d2dffed3fd19d4085fe1cc30cf221263fd01030819bdd8d2bb101cf1 \ - --hash=sha256:2c3ea562c3af274264444819ae9b14dbbf1ab070aff214a05e97db6896c7597e \ - --hash=sha256:33dd86cea8375d8e5dd001e41f321d0a4b1eb7985f39be1b6a4f466cd480b8a7 \ - --hash=sha256:3b84a42da86e8ad8537aabef062e7f661f4a877d1c74d65606c49d835d36d668 \ - --hash=sha256:451039b609b9a88a934800b5fc6ee401c89ad9c175abf2f4d9f8b2e4ef1afc64 \ - --hash=sha256:533298d208b58b651662dd972f52d807d48915176e5b032fb4f8c3b6f5fe535c \ - --hash=sha256:5f0b9e53c1e82e88c10d7c180069363980136b9d7a8306c4dca4f760d60c39f0 \ - --hash=sha256:609a69c68e7cfcfa9d894dc06be13f2e00761485b62df4e2472f1b66f7b405fb \ - --hash=sha256:61d0ee03e6c616f4a8b69987d03d514e8896c8b1b7cc7598ad029e5c6aedfd43 \ - --hash=sha256:66c5de72bf4988e1b284ebdd6524c4bead2c507a2d7f172201572bac6f593901 \ - --hash=sha256:67531da3b62f49c939e09d56492baf397175ff39926d0bd5bd2d191ac2bff95f \ - --hash=sha256:6bb05416444fafea170b07181bc70640975ecc2a8c92b3b658c554119519716c \ - --hash=sha256:6d0bf51e7745484d2092b3a51ae6eb58c3bd3ce0300cf2b2c14f76c536d5697a \ - --hash=sha256:713a777de88a73425cf08eb11f742cd2c98628e79a8673d6a52e3c5f0c116f33 \ - --hash=sha256:75419bb1a559af00250b8f1360d508444e80ed4b26d9d40ec5b09fe7875cb989 \ - --hash=sha256:7b62f94b523c251cf32aa4ab555f14d39bd1a9df385b72443fd76d7c7fb051f5 \ - --hash=sha256:7c4e7c44b6a31de77d4dc9772b7d2561937c9588a734681f70ec547cfbc51ecd \ - --hash=sha256:7dc1e1e2dbd872f8fae529acd5e4839efd0b141eaa8ae7ce835a9fe80fbad89f \ - --hash=sha256:83bc23ef65b6ae44f3287c38cbf82c269e2e96a26e560aa551735883388dcc4b \ - --hash=sha256:8a842ead8ca7c0ee2f396ca5d878c4c40439a527ebad2b996b0444f0074ed004 \ - --hash=sha256:92159782a4502858a21e0079d77cdcaade23e8a5d252ddf46b0652604300d7be \ - --hash=sha256:9b5e6abca8df9f9bdc5c3085f33ff32cdc86ed04c65e0355506d46a5ac19b6e9 \ - --hash=sha256:a1acbbba9edbcbb982bc2cac5e7108f0f553aebac1040fbec67a011a45afa1ba \ - --hash=sha256:a2af2897333b421360fdcce895c6f6281dc3fab018d19d341cf64d043fc8d90d \ - --hash=sha256:a482eecc0b7829c89b498fda883dbd50e98153a116de612ee7c111c8bcf82d1d \ - --hash=sha256:a5f197ffa6fc0e93207b0af71b302e0a2f6f29982e5de0fbda61606dd3a55832 \ - --hash=sha256:a88cbb729cc333334ccfb52f070463c21560fca63afcf636a9f160a55fac3301 \ - --hash=sha256:b424df1076e40d4e884cfcc4c77d815368b7fb9ebcd7e634f937725cd9a8a72a \ - --hash=sha256:bd85d118316b53ed73956435bee1997bd06cc66dd2fa74073e3b1322bd520a67 \ - --hash=sha256:c1cfa663468a189dab510ab231aad030970593f997746d7a324d40104db0d0a9 \ - --hash=sha256:c216b6d5275fc060c6280936bb3bb0e0be6126afb08abccde27eed23dead135f \ - --hash=sha256:c8e71b14938082ebaf78144f3b3917ac715f72d14c076f384a4c062df96f9df6 \ - --hash=sha256:cdd4bdcbaf35056086d910d219106f6a04e1ab0daa40ec0eeef1626c27d0fddb \ - --hash=sha256:d221fa421b389ab2345640a508db57da36947a437dfe31aeddb8d5c7b646c22d \ - --hash=sha256:d64141085864918392c3159cdad15b102a620a67975c786777874e1e90ef15ce \ - --hash=sha256:d6da84a26b3aa5da13a62e4b89ab36a396e9327de8cd48b436a3467077f8ccd4 \ - --hash=sha256:d994b87abaa7a88ceb7a37c90f547b8284ff9da694e6afcfaa8568d739faf3f7 \ - --hash=sha256:da68497f78953017deb20edff0dba95641cc86e7423dfadf7c0264e1ac60dc22 \ - --hash=sha256:daffa4807ef54b927451208f5f85750c545a4abbff03d740835fc444cd97f758 \ - --hash=sha256:df5aa4cead2044bab83e0ebae56e0944cc7fcc1505c7787e9e1057d6d549897e \ - --hash=sha256:e099ddfaa88f59dd8d36c8a3c66bd982b4984edf127eb18e30bb49bdba68ce67 \ - --hash=sha256:e64e61f29cf95afb43549063d8433b46352baf0c8a70aa45e2585618fcf59d86 \ - --hash=sha256:e928ec2d84dc8d13285b4a9288fd6246c5cde4f5f935b479f50d986911f085e3 \ - --hash=sha256:f32b9e65d70f3684532358255dc053f143835c5f5991e28a5ac4c93ce94b9ea7 \ - --hash=sha256:f6538aaaedd091d6e5abdaa19b99e6e82697d67518f114721b5248709b639fad \ - --hash=sha256:f9b8bde9909a010c75b3aea58ec3910393b758f3c219beed67063693df854db0 \ - --hash=sha256:ff1b50aeeec64df5603f17984e4b5be6166058dcf8f1e26a3da40d7a0f6ab547 - # via - # clickhouse-connect - # trino -makefun==1.16.0 \ - --hash=sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4 \ - --hash=sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947 - # via great-expectations -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 - # via rich -marko==2.2.2 \ - --hash=sha256:6940308e655f63733ca518c47a68ec9510279dbb916c83616e4c4b5829f052e8 \ - --hash=sha256:f064ae8c10416285ad1d96048dc11e98ef04e662d3342ae416f662b70aa7959e - # via docling -markupsafe==3.0.3 \ - --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ - --hash=sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a \ - --hash=sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf \ - --hash=sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19 \ - --hash=sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf \ - --hash=sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c \ - --hash=sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175 \ - --hash=sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219 \ - --hash=sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb \ - --hash=sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6 \ - --hash=sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab \ - --hash=sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26 \ - --hash=sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1 \ - --hash=sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce \ - --hash=sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218 \ - --hash=sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634 \ - --hash=sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695 \ - --hash=sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad \ - --hash=sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73 \ - --hash=sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c \ - --hash=sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe \ - --hash=sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa \ - --hash=sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559 \ - --hash=sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa \ - --hash=sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37 \ - --hash=sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758 \ - --hash=sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f \ - --hash=sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8 \ - --hash=sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d \ - --hash=sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c \ - --hash=sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 \ - --hash=sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a \ - --hash=sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19 \ - --hash=sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9 \ - --hash=sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9 \ - --hash=sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc \ - --hash=sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2 \ - --hash=sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4 \ - --hash=sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354 \ - --hash=sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50 \ - --hash=sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698 \ - --hash=sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9 \ - --hash=sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b \ - --hash=sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc \ - --hash=sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115 \ - --hash=sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e \ - --hash=sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485 \ - --hash=sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f \ - --hash=sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12 \ - --hash=sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025 \ - --hash=sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009 \ - --hash=sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d \ - --hash=sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b \ - --hash=sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a \ - --hash=sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 \ - --hash=sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f \ - --hash=sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d \ - --hash=sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1 \ - --hash=sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287 \ - --hash=sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6 \ - --hash=sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f \ - --hash=sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 \ - --hash=sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed \ - --hash=sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b \ - --hash=sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c \ - --hash=sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026 \ - --hash=sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8 \ - --hash=sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 \ - --hash=sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6 \ - --hash=sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e \ - --hash=sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d \ - --hash=sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d \ - --hash=sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01 \ - --hash=sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7 \ - --hash=sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419 \ - --hash=sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795 \ - --hash=sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1 \ - --hash=sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5 \ - --hash=sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d \ - --hash=sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42 \ - --hash=sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe \ - --hash=sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda \ - --hash=sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e \ - --hash=sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737 \ - --hash=sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523 \ - --hash=sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591 \ - --hash=sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc \ - --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ - --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 - # via - # jinja2 - # nbconvert - # werkzeug -marshmallow==3.26.2 \ - --hash=sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73 \ - --hash=sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57 - # via great-expectations -matplotlib-inline==0.2.1 \ - --hash=sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76 \ - --hash=sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe - # via - # ipykernel - # ipython -mcp==1.25.0 \ - --hash=sha256:56310361ebf0364e2d438e5b45f7668cbb124e158bb358333cd06e49e83a6802 \ - --hash=sha256:b37c38144a666add0862614cc79ec276e97d72aa8ca26d622818d4e278b9721a - # via fastapi-mcp -mdurl==0.1.2 \ - --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ - --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba - # via markdown-it-py -milvus-lite==2.4.12 \ - --hash=sha256:20087663e7b4385050b7ad08f1f03404426d4c87b1ff91d5a8723eee7fd49e88 \ - --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ - --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ - --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (setup.py) - # pymilvus -minio==7.2.11 \ - --hash=sha256:153582ed52ff3b5005ba558e1f25bfe1e9e834f7f0745e594777f28e3e81e1a0 \ - --hash=sha256:4db95a21fe1e2022ec975292d8a1f83bd5b18f830d23d42a4518ac7a5281d7c5 - # via feast (setup.py) -mistune==3.2.0 \ - --hash=sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a \ - --hash=sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 - # via - # great-expectations - # nbconvert -mmh3==5.2.0 \ - --hash=sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051 \ - --hash=sha256:097e13c8b8a66c5753c6968b7640faefe85d8e38992703c1f666eda6ef4c3762 \ - --hash=sha256:0b898cecff57442724a0f52bf42c2de42de63083a91008fb452887e372f9c328 \ - --hash=sha256:10983c10f5c77683bd845751905ba535ec47409874acc759d5ce3ff7ef34398a \ - --hash=sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb \ - --hash=sha256:127c95336f2a98c51e7682341ab7cb0be3adb9df0819ab8505a726ed1801876d \ - --hash=sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c \ - --hash=sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667 \ - --hash=sha256:1556e31e4bd0ac0c17eaf220be17a09c171d7396919c3794274cb3415a9d3646 \ - --hash=sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4 \ - --hash=sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12 \ - --hash=sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8 \ - --hash=sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765 \ - --hash=sha256:1fae471339ae1b9c641f19cf46dfe6ffd7f64b1fba7c4333b99fa3dd7f21ae0a \ - --hash=sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9 \ - --hash=sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49 \ - --hash=sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3 \ - --hash=sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd \ - --hash=sha256:2ebfc46b39168ab1cd44670a32ea5489bcbc74a25795c61b6d888c5c2cf654ed \ - --hash=sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115 \ - --hash=sha256:33576136c06b46a7046b6d83a3d75fbca7d25f84cec743f1ae156362608dc6d2 \ - --hash=sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647 \ - --hash=sha256:382a6bb3f8c6532ea084e7acc5be6ae0c6effa529240836d59352398f002e3fc \ - --hash=sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be \ - --hash=sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5 \ - --hash=sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770 \ - --hash=sha256:3c6041fd9d5fb5fcac57d5c80f521a36b74aea06b8566431c63e4ffc49aced51 \ - --hash=sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991 \ - --hash=sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0 \ - --hash=sha256:419005f84ba1cab47a77465a2a843562dadadd6671b8758bf179d82a15ca63eb \ - --hash=sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908 \ - --hash=sha256:49037d417419863b222ae47ee562b2de9c3416add0a45c8d7f4e864be8dc4f89 \ - --hash=sha256:4a5f5536b1cbfa72318ab3bfc8a8188b949260baed186b75f0abc75b95d8c051 \ - --hash=sha256:582f9dbeefe15c32a5fa528b79b088b599a1dfe290a4436351c6090f90ddebb8 \ - --hash=sha256:58477cf9ef16664d1ce2b038f87d2dc96d70fe50733a34a7f07da6c9a5e3538c \ - --hash=sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093 \ - --hash=sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513 \ - --hash=sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645 \ - --hash=sha256:61ac226af521a572700f863d6ecddc6ece97220ce7174e311948ff8c8919a363 \ - --hash=sha256:63830f846797187c5d3e2dae50f0848fdc86032f5bfdc58ae352f02f857e9025 \ - --hash=sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932 \ - --hash=sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7 \ - --hash=sha256:6ecb4e750d712abde046858ee6992b65c93f1f71b397fce7975c3860c07365d2 \ - --hash=sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3 \ - --hash=sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290 \ - --hash=sha256:7434a27754049144539d2099a6d2da5d88b8bdeedf935180bf42ad59b3607aa3 \ - --hash=sha256:746a5ee71c6d1103d9b560fa147881b5e68fd35da56e54e03d5acefad0e7c055 \ - --hash=sha256:7733ec52296fc1ba22e9b90a245c821adbb943e98c91d8a330a2254612726106 \ - --hash=sha256:7901c893e704ee3c65f92d39b951f8f34ccf8e8566768c58103fb10e55afb8c1 \ - --hash=sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037 \ - --hash=sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7 \ - --hash=sha256:7bbb0df897944b5ec830f3ad883e32c5a7375370a521565f5fe24443bfb2c4f7 \ - --hash=sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b \ - --hash=sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54 \ - --hash=sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081 \ - --hash=sha256:81c504ad11c588c8629536b032940f2a359dda3b6cbfd4ad8f74cb24dcd1b0bc \ - --hash=sha256:81df0dae22cd0da87f1c978602750f33d17fb3d21fb0f326c89dc89834fea79b \ - --hash=sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96 \ - --hash=sha256:8b0c53fe0994beade1ad7c0f13bd6fec980a0664bfbe5a6a7d64500b9ab76772 \ - --hash=sha256:8ebf241072cf2777a492d0e09252f8cc2b3edd07dfdb9404b9757bffeb4f2cee \ - --hash=sha256:931d47e08c9c8a67bf75d82f0ada8399eac18b03388818b62bfa42882d571d72 \ - --hash=sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65 \ - --hash=sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db \ - --hash=sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de \ - --hash=sha256:96f1e1ac44cbb42bcc406e509f70c9af42c594e72ccc7b1257f97554204445f0 \ - --hash=sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50 \ - --hash=sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504 \ - --hash=sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5 \ - --hash=sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279 \ - --hash=sha256:a7c0c7845566b9686480e6a7e9044db4afb60038d5fabd19227443f0104eeee4 \ - --hash=sha256:aa6e5d31fdc5ed9e3e95f9873508615a778fe9b523d52c17fc770a3eb39ab6e4 \ - --hash=sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773 \ - --hash=sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a \ - --hash=sha256:b0d753ad566c721faa33db7e2e0eddd74b224cdd3eaf8481d76c926603c7a00e \ - --hash=sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814 \ - --hash=sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43 \ - --hash=sha256:b5f317a727bba0e633a12e71228bc6a4acb4f471a98b1c003163b917311ea9a9 \ - --hash=sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63 \ - --hash=sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05 \ - --hash=sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0 \ - --hash=sha256:bc44fc2b886243d7c0d8daeb37864e16f232e5b56aaec27cc781d848264cfd28 \ - --hash=sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5 \ - --hash=sha256:be1374df449465c9f2500e62eee73a39db62152a8bdfbe12ec5b5c1cd451344d \ - --hash=sha256:be7d3dca9358e01dab1bad881fb2b4e8730cec58d36dd44482bc068bfcd3bc65 \ - --hash=sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094 \ - --hash=sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044 \ - --hash=sha256:c3f563e8901960e2eaa64c8e8821895818acabeb41c96f2efbb936f65dbe486c \ - --hash=sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e \ - --hash=sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c \ - --hash=sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07 \ - --hash=sha256:c677d78887244bf3095020b73c42b505b700f801c690f8eaa90ad12d3179612f \ - --hash=sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266 \ - --hash=sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22 \ - --hash=sha256:cadc16e8ea64b5d9a47363013e2bea469e121e6e7cb416a7593aeb24f2ad122e \ - --hash=sha256:cedac4f4054b8f7859e5aed41aaa31ad03fce6851901a7fdc2af0275ac533c10 \ - --hash=sha256:d22c9dcafed659fadc605538946c041722b6d1104fe619dbf5cc73b3c8a0ded8 \ - --hash=sha256:d765058da196f68dc721116cab335e696e87e76720e6ef8ee5a24801af65e63d \ - --hash=sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384 \ - --hash=sha256:dd966df3489ec13848d6c6303429bbace94a153f43d1ae2a55115fd36fd5ca5d \ - --hash=sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b \ - --hash=sha256:dfbead5575f6470c17e955b94f92d62a03dfc3d07f2e6f817d9b93dc211a1515 \ - --hash=sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501 \ - --hash=sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5 \ - --hash=sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078 \ - --hash=sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73 \ - --hash=sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9 \ - --hash=sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065 \ - --hash=sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d \ - --hash=sha256:e9a011469b47b752e7d20de296bb34591cdfcbe76c99c2e863ceaa2aa61113d2 \ - --hash=sha256:eb756caf8975882630ce4e9fbbeb9d3401242a72528230422c9ab3a0d278e60c \ - --hash=sha256:eba01ec3bd4a49b9ac5ca2bc6a73ff5f3af53374b8556fcc2966dd2af9eb7779 \ - --hash=sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935 \ - --hash=sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5 \ - --hash=sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b \ - --hash=sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5 \ - --hash=sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be \ - --hash=sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b \ - --hash=sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a \ - --hash=sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3 \ - --hash=sha256:fdfd3fb739f4e22746e13ad7ba0c6eedf5f454b18d11249724a388868e308ee4 \ - --hash=sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110 - # via feast (setup.py) -mock==2.0.0 \ - --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \ - --hash=sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba - # via feast (setup.py) -moto==4.2.14 \ - --hash=sha256:6d242dbbabe925bb385ddb6958449e5c827670b13b8e153ed63f91dbdb50372c \ - --hash=sha256:8f9263ca70b646f091edcc93e97cda864a542e6d16ed04066b1370ed217bd190 - # via feast (setup.py) -mpire[dill]==2.10.2 \ - --hash=sha256:d627707f7a8d02aa4c7f7d59de399dec5290945ddf7fbd36cbb1d6ebb37a51fb \ - --hash=sha256:f66a321e93fadff34585a4bfa05e95bd946cf714b442f51c529038eb45773d97 - # via semchunk -mpmath==1.3.0 \ - --hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \ - --hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c - # via sympy -msal==1.34.0 \ - --hash=sha256:76ba83b716ea5a6d75b0279c0ac353a0e05b820ca1f6682c0eb7f45190c43c2f \ - --hash=sha256:f669b1644e4950115da7a176441b0e13ec2975c29528d8b9e81316023676d6e1 - # via - # azure-identity - # msal-extensions -msal-extensions==1.3.1 \ - --hash=sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca \ - --hash=sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4 - # via azure-identity -msgpack==1.1.2 \ - --hash=sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2 \ - --hash=sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014 \ - --hash=sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931 \ - --hash=sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b \ - --hash=sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b \ - --hash=sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999 \ - --hash=sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029 \ - --hash=sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 \ - --hash=sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9 \ - --hash=sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c \ - --hash=sha256:350ad5353a467d9e3b126d8d1b90fe05ad081e2e1cef5753f8c345217c37e7b8 \ - --hash=sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f \ - --hash=sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a \ - --hash=sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42 \ - --hash=sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e \ - --hash=sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f \ - --hash=sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 \ - --hash=sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb \ - --hash=sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef \ - --hash=sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf \ - --hash=sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245 \ - --hash=sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794 \ - --hash=sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af \ - --hash=sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff \ - --hash=sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e \ - --hash=sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296 \ - --hash=sha256:67016ae8c8965124fdede9d3769528ad8284f14d635337ffa6a713a580f6c030 \ - --hash=sha256:6bde749afe671dc44893f8d08e83bf475a1a14570d67c4bb5cec5573463c8833 \ - --hash=sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939 \ - --hash=sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa \ - --hash=sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90 \ - --hash=sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c \ - --hash=sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717 \ - --hash=sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406 \ - --hash=sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a \ - --hash=sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251 \ - --hash=sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2 \ - --hash=sha256:94fd7dc7d8cb0a54432f296f2246bc39474e017204ca6f4ff345941d4ed285a7 \ - --hash=sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e \ - --hash=sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b \ - --hash=sha256:9fba231af7a933400238cb357ecccf8ab5d51535ea95d94fc35b7806218ff844 \ - --hash=sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 \ - --hash=sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87 \ - --hash=sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b \ - --hash=sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c \ - --hash=sha256:a8f6e7d30253714751aa0b0c84ae28948e852ee7fb0524082e6716769124bc23 \ - --hash=sha256:ad09b984828d6b7bb52d1d1d0c9be68ad781fa004ca39216c8a1e63c0f34ba3c \ - --hash=sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e \ - --hash=sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620 \ - --hash=sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69 \ - --hash=sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f \ - --hash=sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 \ - --hash=sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27 \ - --hash=sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46 \ - --hash=sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa \ - --hash=sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00 \ - --hash=sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9 \ - --hash=sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84 \ - --hash=sha256:ea5405c46e690122a76531ab97a079e184c0daf491e588592d6a23d3e32af99e \ - --hash=sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20 \ - --hash=sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e \ - --hash=sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162 - # via ray -multidict==6.7.0 \ - --hash=sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3 \ - --hash=sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec \ - --hash=sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd \ - --hash=sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b \ - --hash=sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb \ - --hash=sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32 \ - --hash=sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f \ - --hash=sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7 \ - --hash=sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36 \ - --hash=sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd \ - --hash=sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff \ - --hash=sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8 \ - --hash=sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d \ - --hash=sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721 \ - --hash=sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0 \ - --hash=sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3 \ - --hash=sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d \ - --hash=sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa \ - --hash=sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10 \ - --hash=sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202 \ - --hash=sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0 \ - --hash=sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718 \ - --hash=sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e \ - --hash=sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6 \ - --hash=sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1 \ - --hash=sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2 \ - --hash=sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754 \ - --hash=sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c \ - --hash=sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390 \ - --hash=sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128 \ - --hash=sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912 \ - --hash=sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c \ - --hash=sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3 \ - --hash=sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6 \ - --hash=sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2 \ - --hash=sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f \ - --hash=sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84 \ - --hash=sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842 \ - --hash=sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9 \ - --hash=sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6 \ - --hash=sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd \ - --hash=sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8 \ - --hash=sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599 \ - --hash=sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62 \ - --hash=sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec \ - --hash=sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34 \ - --hash=sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0 \ - --hash=sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e \ - --hash=sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6 \ - --hash=sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc \ - --hash=sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc \ - --hash=sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c \ - --hash=sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7 \ - --hash=sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4 \ - --hash=sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4 \ - --hash=sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38 \ - --hash=sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5 \ - --hash=sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111 \ - --hash=sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e \ - --hash=sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84 \ - --hash=sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c \ - --hash=sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1 \ - --hash=sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546 \ - --hash=sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a \ - --hash=sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c \ - --hash=sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036 \ - --hash=sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38 \ - --hash=sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99 \ - --hash=sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64 \ - --hash=sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e \ - --hash=sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f \ - --hash=sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159 \ - --hash=sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e \ - --hash=sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12 \ - --hash=sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1 \ - --hash=sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0 \ - --hash=sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184 \ - --hash=sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851 \ - --hash=sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb \ - --hash=sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32 \ - --hash=sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b \ - --hash=sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288 \ - --hash=sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81 \ - --hash=sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd \ - --hash=sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45 \ - --hash=sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a \ - --hash=sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca \ - --hash=sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5 \ - --hash=sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb \ - --hash=sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349 \ - --hash=sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b \ - --hash=sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f \ - --hash=sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32 \ - --hash=sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5 \ - --hash=sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34 \ - --hash=sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c \ - --hash=sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4 \ - --hash=sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17 \ - --hash=sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60 \ - --hash=sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394 \ - --hash=sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff \ - --hash=sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00 \ - --hash=sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85 \ - --hash=sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7 \ - --hash=sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304 \ - --hash=sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13 \ - --hash=sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e \ - --hash=sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e \ - --hash=sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792 \ - --hash=sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329 \ - --hash=sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb \ - --hash=sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b \ - --hash=sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000 \ - --hash=sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6 \ - --hash=sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62 \ - --hash=sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63 \ - --hash=sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5 \ - --hash=sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e \ - --hash=sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c \ - --hash=sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827 \ - --hash=sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8 \ - --hash=sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91 \ - --hash=sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96 \ - --hash=sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad \ - --hash=sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6 \ - --hash=sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40 \ - --hash=sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7 \ - --hash=sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4 \ - --hash=sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648 \ - --hash=sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064 \ - --hash=sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73 \ - --hash=sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b \ - --hash=sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762 \ - --hash=sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e \ - --hash=sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4 \ - --hash=sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e \ - --hash=sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546 \ - --hash=sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046 \ - --hash=sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6 \ - --hash=sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9 \ - --hash=sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d \ - --hash=sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf \ - --hash=sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687 \ - --hash=sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e \ - --hash=sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885 \ - --hash=sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7 - # via - # aiobotocore - # aiohttp - # yarl -multiprocess==0.70.16 \ - --hash=sha256:0dfd078c306e08d46d7a8d06fb120313d87aa43af60d66da43ffff40b44d2f41 \ - --hash=sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1 \ - --hash=sha256:37b55f71c07e2d741374998c043b9520b626a8dddc8b3129222ca4f1a06ef67a \ - --hash=sha256:476887be10e2f59ff183c006af746cb6f1fd0eadcfd4ef49e605cbe2659920ee \ - --hash=sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3 \ - --hash=sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435 \ - --hash=sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a \ - --hash=sha256:ba8c31889abf4511c7308a8c52bb4a30b9d590e7f58523302ba00237702ca054 \ - --hash=sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02 \ - --hash=sha256:d951bed82c8f73929ac82c61f01a7b5ce8f3e5ef40f5b52553b4f547ce2b08ec \ - --hash=sha256:e7b9d0f307cd9bd50851afaac0dba2cb6c44449efff697df7c7645f7d3f2be3a \ - --hash=sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e - # via - # datasets - # mpire -mypy==1.11.2 \ - --hash=sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36 \ - --hash=sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce \ - --hash=sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6 \ - --hash=sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b \ - --hash=sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca \ - --hash=sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24 \ - --hash=sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383 \ - --hash=sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7 \ - --hash=sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86 \ - --hash=sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d \ - --hash=sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4 \ - --hash=sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8 \ - --hash=sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987 \ - --hash=sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385 \ - --hash=sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79 \ - --hash=sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef \ - --hash=sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6 \ - --hash=sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70 \ - --hash=sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca \ - --hash=sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70 \ - --hash=sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12 \ - --hash=sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104 \ - --hash=sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a \ - --hash=sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318 \ - --hash=sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1 \ - --hash=sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b \ - --hash=sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d - # via - # feast (setup.py) - # sqlalchemy -mypy-extensions==1.1.0 \ - --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ - --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 - # via mypy -mypy-protobuf==3.3.0 \ - --hash=sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d \ - --hash=sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248 - # via feast (setup.py) -nbclient==0.10.4 \ - --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ - --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 - # via nbconvert -nbconvert==7.16.6 \ - --hash=sha256:1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b \ - --hash=sha256:576a7e37c6480da7b8465eefa66c17844243816ce1ccc372633c6b71c3c0f582 - # via jupyter-server -nbformat==5.10.4 \ - --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ - --hash=sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b - # via - # great-expectations - # jupyter-server - # nbclient - # nbconvert -nest-asyncio==1.6.0 \ - --hash=sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe \ - --hash=sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c - # via ipykernel -networkx==3.6.1 \ - --hash=sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509 \ - --hash=sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 - # via - # scikit-image - # torch -ninja==1.13.0 \ - --hash=sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f \ - --hash=sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988 \ - --hash=sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9 \ - --hash=sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630 \ - --hash=sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db \ - --hash=sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978 \ - --hash=sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1 \ - --hash=sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72 \ - --hash=sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e \ - --hash=sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2 \ - --hash=sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9 \ - --hash=sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714 \ - --hash=sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200 \ - --hash=sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c \ - --hash=sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5 \ - --hash=sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96 \ - --hash=sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1 \ - --hash=sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa \ - --hash=sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e - # via easyocr -nodeenv==1.10.0 \ - --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ - --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb - # via pre-commit -notebook==7.5.2 \ - --hash=sha256:17d078a98603d70d62b6b4b3fcb67e87d7a68c398a7ae9b447eb2d7d9aec9979 \ - --hash=sha256:83e82f93c199ca730313bea1bb24bc279ea96f74816d038a92d26b6b9d5f3e4a - # via great-expectations -notebook-shim==0.2.4 \ - --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ - --hash=sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb - # via - # jupyterlab - # notebook -numpy==2.4.1 \ - --hash=sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c \ - --hash=sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba \ - --hash=sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5 \ - --hash=sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8 \ - --hash=sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0 \ - --hash=sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d \ - --hash=sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574 \ - --hash=sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696 \ - --hash=sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5 \ - --hash=sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505 \ - --hash=sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0 \ - --hash=sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162 \ - --hash=sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844 \ - --hash=sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205 \ - --hash=sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4 \ - --hash=sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc \ - --hash=sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d \ - --hash=sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93 \ - --hash=sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01 \ - --hash=sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c \ - --hash=sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f \ - --hash=sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33 \ - --hash=sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82 \ - --hash=sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2 \ - --hash=sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42 \ - --hash=sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509 \ - --hash=sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a \ - --hash=sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e \ - --hash=sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556 \ - --hash=sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a \ - --hash=sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510 \ - --hash=sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295 \ - --hash=sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73 \ - --hash=sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3 \ - --hash=sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9 \ - --hash=sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8 \ - --hash=sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745 \ - --hash=sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2 \ - --hash=sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02 \ - --hash=sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d \ - --hash=sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344 \ - --hash=sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f \ - --hash=sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be \ - --hash=sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425 \ - --hash=sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1 \ - --hash=sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2 \ - --hash=sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2 \ - --hash=sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb \ - --hash=sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9 \ - --hash=sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15 \ - --hash=sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690 \ - --hash=sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0 \ - --hash=sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261 \ - --hash=sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a \ - --hash=sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc \ - --hash=sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f \ - --hash=sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5 \ - --hash=sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df \ - --hash=sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9 \ - --hash=sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2 \ - --hash=sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 \ - --hash=sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426 \ - --hash=sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b \ - --hash=sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87 \ - --hash=sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220 \ - --hash=sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b \ - --hash=sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3 \ - --hash=sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e \ - --hash=sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501 \ - --hash=sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee \ - --hash=sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7 \ - --hash=sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c - # via - # feast (setup.py) - # accelerate - # altair - # dask - # datasets - # db-dtypes - # docling-ibm-models - # easyocr - # faiss-cpu - # great-expectations - # ibis-framework - # imageio - # opencv-python-headless - # pandas - # pandas-gbq - # pyarrow - # qdrant-client - # ray - # safetensors - # scikit-image - # scikit-learn - # scipy - # shapely - # tifffile - # torchvision - # transformers -oauthlib==3.3.1 \ - --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ - --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 - # via requests-oauthlib -opencensus==0.11.4 \ - --hash=sha256:a18487ce68bc19900336e0ff4655c5a116daf10c1b3685ece8d971bddad6a864 \ - --hash=sha256:cbef87d8b8773064ab60e5c2a1ced58bbaa38a6d052c41aec224958ce544eff2 - # via ray -opencensus-context==0.1.3 \ - --hash=sha256:073bb0590007af276853009fac7e4bab1d523c3f03baf4cb4511ca38967c6039 \ - --hash=sha256:a03108c3c10d8c80bb5ddf5c8a1f033161fa61972a9917f9b9b3a18517f0088c - # via opencensus -opencv-python-headless==4.13.0.90 \ - --hash=sha256:0e0c8c9f620802fddc4fa7f471a1d263c7b0dca16cd9e7e2f996bb8bd2128c0c \ - --hash=sha256:12a28674f215542c9bf93338de1b5bffd76996d32da9acb9e739fdb9c8bbd738 \ - --hash=sha256:32255203040dc98803be96362e13f9e4bce20146898222d2e5c242f80de50da5 \ - --hash=sha256:96060fc57a1abb1144b0b8129e2ff3bfcdd0ccd8e8bd05bd85256ff4ed587d3b \ - --hash=sha256:dbc1f4625e5af3a80ebdbd84380227c0f445228588f2521b11af47710caca1ba \ - --hash=sha256:e13790342591557050157713af17a7435ac1b50c65282715093c9297fa045d8f \ - --hash=sha256:eba38bc255d0b7d1969c5bcc90a060ca2b61a3403b613872c750bfa5dfe9e03b \ - --hash=sha256:f46b17ea0aa7e4124ca6ad71143f89233ae9557f61d2326bcdb34329a1ddf9bd - # via easyocr -openpyxl==3.1.5 \ - --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ - --hash=sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050 - # via docling -openshift-client==1.0.18 \ - --hash=sha256:be3979440cfd96788146a3a1650dabe939d4d516eea0b39f87e66d2ab39495b1 \ - --hash=sha256:d8a84080307ccd9556f6c62a3707a3e6507baedee36fa425754f67db9ded528b - # via codeflare-sdk -opentelemetry-api==1.39.1 \ - --hash=sha256:2edd8463432a7f8443edce90972169b195e7d6a05500cd29e6d13898187c9950 \ - --hash=sha256:fbde8c80e1b937a2c61f20347e91c0c18a1940cecf012d62e65a7caf08967c9c - # via - # opentelemetry-exporter-prometheus - # opentelemetry-sdk - # opentelemetry-semantic-conventions -opentelemetry-exporter-prometheus==0.60b1 \ - --hash=sha256:49f59178de4f4590e3cef0b8b95cf6e071aae70e1f060566df5546fad773b8fd \ - --hash=sha256:a4011b46906323f71724649d301b4dc188aaa068852e814f4df38cc76eac616b - # via ray -opentelemetry-proto==1.27.0 \ - --hash=sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6 \ - --hash=sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace - # via ray -opentelemetry-sdk==1.39.1 \ - --hash=sha256:4d5482c478513ecb0a5d938dcc61394e647066e0cc2676bee9f3af3f3f45f01c \ - --hash=sha256:cf4d4563caf7bff906c9f7967e2be22d0d6b349b908be0d90fb21c8e9c995cc6 - # via - # opentelemetry-exporter-prometheus - # ray -opentelemetry-semantic-conventions==0.60b1 \ - --hash=sha256:87c228b5a0669b748c76d76df6c364c369c28f1c465e50f661e39737e84bc953 \ - --hash=sha256:9fa8c8b0c110da289809292b0591220d3a7b53c1526a23021e977d68597893fb - # via opentelemetry-sdk -orjson==3.11.5 \ - --hash=sha256:0522003e9f7fba91982e83a97fec0708f5a714c96c4209db7104e6b9d132f111 \ - --hash=sha256:073aab025294c2f6fc0807201c76fdaed86f8fc4be52c440fb78fbb759a1ac09 \ - --hash=sha256:09b94b947ac08586af635ef922d69dc9bc63321527a3a04647f4986a73f4bd30 \ - --hash=sha256:1b280e2d2d284a6713b0cfec7b08918ebe57df23e3f76b27586197afca3cb1e9 \ - --hash=sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d \ - --hash=sha256:1cbf2735722623fcdee8e712cbaaab9e372bbcb0c7924ad711b261c2eccf4a5c \ - --hash=sha256:1db2088b490761976c1b2e956d5d4e6409f3732e9d79cfa69f876c5248d1baf9 \ - --hash=sha256:23d04c4543e78f724c4dfe656b3791b5f98e4c9253e13b2636f1af5d90e4a880 \ - --hash=sha256:298d2451f375e5f17b897794bcc3e7b821c0f32b4788b9bcae47ada24d7f3cf7 \ - --hash=sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875 \ - --hash=sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef \ - --hash=sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d \ - --hash=sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5 \ - --hash=sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629 \ - --hash=sha256:3c8d8a112b274fae8c5f0f01954cb0480137072c271f3f4958127b010dfefaec \ - --hash=sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e \ - --hash=sha256:42e8961196af655bb5e63ce6c60d25e8798cd4dfbc04f4203457fa3869322c2e \ - --hash=sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228 \ - --hash=sha256:4dad582bc93cef8f26513e12771e76385a7e6187fd713157e971c784112aad56 \ - --hash=sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81 \ - --hash=sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863 \ - --hash=sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287 \ - --hash=sha256:5f0a2ae6f09ac7bd47d2d5a5305c1d9ed08ac057cda55bb0a49fa506f0d2da00 \ - --hash=sha256:5f691263425d3177977c8d1dd896cde7b98d93cbf390b2544a090675e83a6a0a \ - --hash=sha256:61026196a1c4b968e1b1e540563e277843082e9e97d78afa03eb89315af531f1 \ - --hash=sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3 \ - --hash=sha256:667c132f1f3651c14522a119e4dd631fad98761fa960c55e8e7430bb2a1ba4ac \ - --hash=sha256:67394d3becd50b954c4ecd24ac90b5051ee7c903d167459f93e77fc6f5b4c968 \ - --hash=sha256:69a0f6ac618c98c74b7fbc8c0172ba86f9e01dbf9f62aa0b1776c2231a7bffe5 \ - --hash=sha256:6af8680328c69e15324b5af3ae38abbfcf9cbec37b5346ebfd52339c3d7e8a18 \ - --hash=sha256:7339f41c244d0eea251637727f016b3d20050636695bc78345cce9029b189401 \ - --hash=sha256:7403851e430a478440ecc1258bcbacbfbd8175f9ac1e39031a7121dd0de05ff8 \ - --hash=sha256:75412ca06e20904c19170f8a24486c4e6c7887dea591ba18a1ab572f1300ee9f \ - --hash=sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f \ - --hash=sha256:7bb2ce0b82bc9fd1168a513ddae7a857994b780b2945a8c51db4ab1c4b751ebc \ - --hash=sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51 \ - --hash=sha256:801a821e8e6099b8c459ac7540b3c32dba6013437c57fdcaec205b169754f38c \ - --hash=sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5 \ - --hash=sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f \ - --hash=sha256:835f26fa24ba0bb8c53ae2a9328d1706135b74ec653ed933869b74b6909e63fd \ - --hash=sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9 \ - --hash=sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39 \ - --hash=sha256:8be318da8413cdbbce77b8c5fac8d13f6eb0f0db41b30bb598631412619572e8 \ - --hash=sha256:8d5f16195bb671a5dd3d1dbea758918bada8f6cc27de72bd64adfbd748770814 \ - --hash=sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98 \ - --hash=sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb \ - --hash=sha256:9645ef655735a74da4990c24ffbd6894828fbfa117bc97c1edd98c282ecb52e1 \ - --hash=sha256:9c8494625ad60a923af6b2b0bd74107146efe9b55099e20d7740d995f338fcd8 \ - --hash=sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499 \ - --hash=sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7 \ - --hash=sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626 \ - --hash=sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2 \ - --hash=sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310 \ - --hash=sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85 \ - --hash=sha256:a86fe4ff4ea523eac8f4b57fdac319faf037d3c1be12405e6a7e86b3fbc4756a \ - --hash=sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4 \ - --hash=sha256:aa5e4244063db8e1d87e0f54c3f7522f14b2dc937e65d5241ef0076a096409fd \ - --hash=sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe \ - --hash=sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa \ - --hash=sha256:b42ffbed9128e547a1647a3e50bc88ab28ae9daa61713962e0d3dd35e820c125 \ - --hash=sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac \ - --hash=sha256:b9f86d69ae822cabc2a0f6c099b43e8733dda788405cba2665595b7e8dd8d167 \ - --hash=sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439 \ - --hash=sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05 \ - --hash=sha256:c0d87bd1896faac0d10b4f849016db81a63e4ec5df38757ffae84d45ab38aa71 \ - --hash=sha256:c0e5d9f7a0227df2927d343a6e3859bebf9208b427c79bd31949abcc2fa32fa5 \ - --hash=sha256:c2021afda46c1ed64d74b555065dbd4c2558d510d8cec5ea6a53001b3e5e82a9 \ - --hash=sha256:c2ed66358f32c24e10ceea518e16eb3549e34f33a9d51f99ce23b0251776a1ef \ - --hash=sha256:c404603df4865f8e0afe981aa3c4b62b406e6d06049564d58934860b62b7f91d \ - --hash=sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477 \ - --hash=sha256:ccc70da619744467d8f1f49a8cadae5ec7bbe054e5232d95f92ed8737f8c5870 \ - --hash=sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829 \ - --hash=sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706 \ - --hash=sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca \ - --hash=sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f \ - --hash=sha256:df9eadb2a6386d5ea2bfd81309c505e125cfc9ba2b1b99a97e60985b0b3665d1 \ - --hash=sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69 \ - --hash=sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0 \ - --hash=sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8 \ - --hash=sha256:e607b49b1a106ee2086633167033afbd63f76f2999e9236f638b06b112b24ea7 \ - --hash=sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e \ - --hash=sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3 \ - --hash=sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f \ - --hash=sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad \ - --hash=sha256:fea7339bdd22e6f1060c55ac31b6a755d86a5b2ad3657f2669ec243f8e3b2bdb \ - --hash=sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626 \ - --hash=sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583 - # via trino -overrides==7.7.0 \ - --hash=sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a \ - --hash=sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 - # via jupyter-server -packaging==24.2 \ - --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ - --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f - # via - # accelerate - # build - # dask - # datasets - # db-dtypes - # deprecation - # dunamai - # faiss-cpu - # google-cloud-bigquery - # great-expectations - # gunicorn - # huggingface-hub - # ibis-framework - # ibis-substrait - # ipykernel - # jupyter-events - # jupyter-server - # jupyterlab - # jupyterlab-server - # lazy-loader - # marshmallow - # nbconvert - # pandas-gbq - # pytest - # ray - # safetensors - # scikit-image - # snowflake-connector-python - # sphinx - # transformers -pandas==2.3.3 \ - --hash=sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7 \ - --hash=sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593 \ - --hash=sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5 \ - --hash=sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791 \ - --hash=sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73 \ - --hash=sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec \ - --hash=sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4 \ - --hash=sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5 \ - --hash=sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac \ - --hash=sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084 \ - --hash=sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c \ - --hash=sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87 \ - --hash=sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35 \ - --hash=sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250 \ - --hash=sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c \ - --hash=sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826 \ - --hash=sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9 \ - --hash=sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713 \ - --hash=sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1 \ - --hash=sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523 \ - --hash=sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3 \ - --hash=sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78 \ - --hash=sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53 \ - --hash=sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c \ - --hash=sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21 \ - --hash=sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5 \ - --hash=sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff \ - --hash=sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45 \ - --hash=sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110 \ - --hash=sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493 \ - --hash=sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b \ - --hash=sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450 \ - --hash=sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86 \ - --hash=sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8 \ - --hash=sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98 \ - --hash=sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89 \ - --hash=sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66 \ - --hash=sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b \ - --hash=sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8 \ - --hash=sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29 \ - --hash=sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6 \ - --hash=sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc \ - --hash=sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2 \ - --hash=sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788 \ - --hash=sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa \ - --hash=sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151 \ - --hash=sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838 \ - --hash=sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b \ - --hash=sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a \ - --hash=sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d \ - --hash=sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908 \ - --hash=sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0 \ - --hash=sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b \ - --hash=sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c \ - --hash=sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee - # via - # feast (setup.py) - # altair - # dask - # datasets - # db-dtypes - # docling - # docling-core - # google-cloud-bigquery - # great-expectations - # ibis-framework - # pandas-gbq - # pymilvus - # ray - # snowflake-connector-python -pandas-gbq==0.30.0 \ - --hash=sha256:8fe811786e4ad2e0d4608e897534207d9fbe768ab3168f766a99f0cb4cd5ed20 \ - --hash=sha256:d9b4454b17aee3c23ef1dfcfd91df6e2b77f1e69e1e4b28467701cd75850664a - # via google-cloud-bigquery -pandocfilters==1.5.1 \ - --hash=sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e \ - --hash=sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc - # via nbconvert -paramiko==4.0.0 \ - --hash=sha256:0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 \ - --hash=sha256:6a25f07b380cc9c9a88d2b920ad37167ac4667f8d9886ccebd8f90f654b5d69f - # via openshift-client -parsimonious==0.11.0 \ - --hash=sha256:32e3818abf9f05b3b9f3b6d87d128645e30177e91f614d2277d88a0aea98fae2 \ - --hash=sha256:e080377d98957beec053580d38ae54fcdf7c470fb78670ba4bf8b5f9d5cad2a9 - # via singlestoredb -parso==0.8.5 \ - --hash=sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a \ - --hash=sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 - # via jedi -parsy==2.2 \ - --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ - --hash=sha256:e943147644a8cf0d82d1bcb5c5867dd517495254cea3e3eb058b1e421cb7561f - # via ibis-framework -partd==1.4.2 \ - --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ - --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c - # via dask -pbr==7.0.3 \ - --hash=sha256:b46004ec30a5324672683ec848aed9e8fc500b0d261d40a3229c2d2bbfcedc29 \ - --hash=sha256:ff223894eb1cd271a98076b13d3badff3bb36c424074d26334cd25aebeecea6b - # via mock -pexpect==4.9.0 \ - --hash=sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 \ - --hash=sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f - # via ipython -pillow==11.3.0 \ - --hash=sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2 \ - --hash=sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214 \ - --hash=sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e \ - --hash=sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59 \ - --hash=sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50 \ - --hash=sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632 \ - --hash=sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06 \ - --hash=sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a \ - --hash=sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51 \ - --hash=sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced \ - --hash=sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f \ - --hash=sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12 \ - --hash=sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8 \ - --hash=sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6 \ - --hash=sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580 \ - --hash=sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f \ - --hash=sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac \ - --hash=sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860 \ - --hash=sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd \ - --hash=sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722 \ - --hash=sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8 \ - --hash=sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4 \ - --hash=sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673 \ - --hash=sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788 \ - --hash=sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542 \ - --hash=sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e \ - --hash=sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd \ - --hash=sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8 \ - --hash=sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523 \ - --hash=sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967 \ - --hash=sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809 \ - --hash=sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477 \ - --hash=sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027 \ - --hash=sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae \ - --hash=sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b \ - --hash=sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c \ - --hash=sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f \ - --hash=sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e \ - --hash=sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b \ - --hash=sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7 \ - --hash=sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27 \ - --hash=sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361 \ - --hash=sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae \ - --hash=sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d \ - --hash=sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc \ - --hash=sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58 \ - --hash=sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad \ - --hash=sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6 \ - --hash=sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024 \ - --hash=sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978 \ - --hash=sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb \ - --hash=sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d \ - --hash=sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0 \ - --hash=sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9 \ - --hash=sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f \ - --hash=sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874 \ - --hash=sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa \ - --hash=sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081 \ - --hash=sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149 \ - --hash=sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6 \ - --hash=sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d \ - --hash=sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd \ - --hash=sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f \ - --hash=sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c \ - --hash=sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31 \ - --hash=sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e \ - --hash=sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db \ - --hash=sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6 \ - --hash=sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f \ - --hash=sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494 \ - --hash=sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69 \ - --hash=sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94 \ - --hash=sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77 \ - --hash=sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d \ - --hash=sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7 \ - --hash=sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a \ - --hash=sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438 \ - --hash=sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288 \ - --hash=sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b \ - --hash=sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635 \ - --hash=sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3 \ - --hash=sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d \ - --hash=sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe \ - --hash=sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0 \ - --hash=sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe \ - --hash=sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a \ - --hash=sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805 \ - --hash=sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8 \ - --hash=sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36 \ - --hash=sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a \ - --hash=sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b \ - --hash=sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e \ - --hash=sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25 \ - --hash=sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12 \ - --hash=sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada \ - --hash=sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c \ - --hash=sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71 \ - --hash=sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d \ - --hash=sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c \ - --hash=sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6 \ - --hash=sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1 \ - --hash=sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50 \ - --hash=sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653 \ - --hash=sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c \ - --hash=sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4 \ - --hash=sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3 - # via - # feast (setup.py) - # docling - # docling-core - # docling-ibm-models - # docling-parse - # easyocr - # imageio - # python-pptx - # scikit-image - # torchvision -pip==25.3 \ - --hash=sha256:8d0538dbbd7babbd207f261ed969c65de439f6bc9e5dbd3b3b9a77f25d95f343 \ - --hash=sha256:9655943313a94722b7774661c21049070f6bbb0a1516bf02f7c8d5d9201514cd - # via pip-tools -pip-tools==7.5.2 \ - --hash=sha256:2d64d72da6a044da1110257d333960563d7a4743637e8617dd2610ae7b82d60f \ - --hash=sha256:2fe16db727bbe5bf28765aeb581e792e61be51fc275545ef6725374ad720a1ce - # via feast (setup.py) -platformdirs==3.11.0 \ - --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \ - --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e - # via - # jupyter-core - # snowflake-connector-python - # virtualenv -pluggy==1.6.0 \ - --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ - --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 - # via - # docling - # pytest - # pytest-cov -ply==3.11 \ - --hash=sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3 \ - --hash=sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce - # via thriftpy2 -poetry-core==1.9.1 \ - --hash=sha256:6f45dd3598e0de8d9b0367360253d4c5d4d0110c8f5c71120a14f0e0f116c1a0 \ - --hash=sha256:7a2d49214bf58b4f17f99d6891d947a9836c9899a67a5069f52d7b67217f61b8 - # via feast (setup.py) -poetry-dynamic-versioning==1.9.1 \ - --hash=sha256:65a0c814e6d30d4807734a3c34edf261fd7cc3b340dbd23b6a33ee41f7d0b547 \ - --hash=sha256:d6e7b9df817aa2ca4946cd695c6c89e1379d2e6c640f008a9b6170d081a9da48 - # via feast (setup.py) -portalocker==3.2.0 \ - --hash=sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac \ - --hash=sha256:3cdc5f565312224bc570c49337bd21428bba0ef363bbcf58b9ef4a9f11779968 - # via qdrant-client -pre-commit==3.3.1 \ - --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ - --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 - # via feast (setup.py) -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 - # via - # feast (setup.py) - # jupyter-server - # opentelemetry-exporter-prometheus - # ray -prompt-toolkit==3.0.52 \ - --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ - --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 - # via ipython -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 - # via - # aiohttp - # yarl -proto-plus==1.27.0 \ - --hash=sha256:1baa7f81cf0f8acb8bc1f6d085008ba4171eaf669629d1b6d1673b21ed1c0a82 \ - --hash=sha256:873af56dd0d7e91836aee871e5799e1c6f1bda86ac9a983e0bb9f0c266a568c4 - # via - # google-api-core - # google-cloud-bigquery-storage - # google-cloud-bigtable - # google-cloud-datastore -protobuf==4.25.8 \ - --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ - --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ - --hash=sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af \ - --hash=sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0 \ - --hash=sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd \ - --hash=sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0 \ - --hash=sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7 \ - --hash=sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9 \ - --hash=sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f \ - --hash=sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3 \ - --hash=sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24 - # via - # feast (setup.py) - # google-api-core - # google-cloud-bigquery-storage - # google-cloud-bigtable - # google-cloud-datastore - # googleapis-common-protos - # grpc-google-iam-v1 - # grpcio-health-checking - # grpcio-reflection - # grpcio-status - # grpcio-testing - # grpcio-tools - # ikvpy - # mypy-protobuf - # opentelemetry-proto - # proto-plus - # pymilvus - # qdrant-client - # ray - # substrait -psutil==5.9.0 \ - --hash=sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5 \ - --hash=sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a \ - --hash=sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4 \ - --hash=sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841 \ - --hash=sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d \ - --hash=sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d \ - --hash=sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0 \ - --hash=sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845 \ - --hash=sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf \ - --hash=sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b \ - --hash=sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07 \ - --hash=sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618 \ - --hash=sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2 \ - --hash=sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd \ - --hash=sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666 \ - --hash=sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce \ - --hash=sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3 \ - --hash=sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d \ - --hash=sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25 \ - --hash=sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492 \ - --hash=sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b \ - --hash=sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d \ - --hash=sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2 \ - --hash=sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203 \ - --hash=sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2 \ - --hash=sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94 \ - --hash=sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9 \ - --hash=sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64 \ - --hash=sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56 \ - --hash=sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3 \ - --hash=sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c \ - --hash=sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3 - # via - # feast (setup.py) - # accelerate - # ipykernel -psycopg[binary, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 - # via feast (setup.py) -psycopg-binary==3.2.5 \ - --hash=sha256:02fb96091e2fb3ea1470b113fef08953baaedbca1d39a3f72d82cb615177846c \ - --hash=sha256:11e3ed8b94c750d54fc3e4502dd930fb0fd041629845b6a7ce089873ac9756b0 \ - --hash=sha256:1494827c43265820d5dcdc6f8086521bc7dd04b9da8831310978a788cdcd2e62 \ - --hash=sha256:21b839f9bfd77ed074f7f71464a43f453400c57d038a0ba0716329a28e335897 \ - --hash=sha256:23a1dc61abb8f7cc702472ab29554167a9421842f976c201ceb3b722c0299769 \ - --hash=sha256:274e852f9e61252bc8e80a0a43d300ba352d40219e856733054023a3bb960eb4 \ - --hash=sha256:28bd5cb2324567e5e70f07fe1d646398d6b0e210e28b49be0e69593590a59980 \ - --hash=sha256:2b053eae21dd3a6828b516a1171e1274d1af5f7c07d2d9a8f597f2e19c732168 \ - --hash=sha256:2cbb8649cfdacbd14e17f5ab78edc52d33350013888518c73e90c5d17d7bea55 \ - --hash=sha256:2cc86657c05e09c701e97f87132cd58e0d55381dd568520081ac1fe7580a9bbb \ - --hash=sha256:2d10ce4c39eb9631381a0c3792727946a4391e843625a7ee9579ac6bb11495a5 \ - --hash=sha256:2d22a15e45f43d36ed35aed4d5261f8ef6ab7d9b84ee075576ca56ae03b9e0aa \ - --hash=sha256:2dbaf32c18c0d11c4480016b89c9c5cadb7b64c55de7f181d222b189bd13a558 \ - --hash=sha256:32b5673736f04c36ccbf8012800fe5bc01b46dac22c5d59e41b043bebaad9d3d \ - --hash=sha256:375149006e21d58ed8aba640e0295d8e636043064c433af94eb58057f9b96877 \ - --hash=sha256:393ab353196d364858b47317d27804ecc58ab56dbde32217bd67f0f2f2980662 \ - --hash=sha256:39e2cd10bf15442d95c3f48376b25dc33360418ea6c3c05884d8bf42407768c0 \ - --hash=sha256:3d2e57a1d06f3968e49e948ba374f21a7d8dcf44f37d582a4aeddeb7c85ce239 \ - --hash=sha256:3eb71cfc35116e4a8e336b7e785f1fe06ca23b4516a48ea91facd577d1a1fdf6 \ - --hash=sha256:3f893c0ed3d5c7b83b76b1f8f7d3ca5a03e38bcd3cab5d65b5c25a0d1064aca4 \ - --hash=sha256:473f6827cf1faf3924eb77146d1e85126a1b5e48a88053b8d8b78dd29e971d78 \ - --hash=sha256:48f97936145cb7de18b95d85670b2d3e2c257277263272be05815b74fb0ef195 \ - --hash=sha256:48fcb12a0a72fdfe4102bdb1252a7366e8d73a2c89fe6ce5923be890de367c2f \ - --hash=sha256:4914dc60f2fddf0884464985e31d775aa865b665471fa156ec2f56fa72a1a097 \ - --hash=sha256:51a96d9fe51f718912b4a0089784f1f32d800217499fd0f0095b888506aba4c5 \ - --hash=sha256:5244bebaa9734a236b7157fb57c065b6c0f2344281916187bd73f951df1899e0 \ - --hash=sha256:5b81342e139ddccfa417832089cd213bd4beacd7a1462ca4019cafe71682d177 \ - --hash=sha256:5d2253189aa4cca0a425e2ca896d1a29760cd3a2b10ab12194e4e827a566505c \ - --hash=sha256:5fd017d7ed71c58f19b0f614e7bfb8f01ec862bacb67ae584f494d090956102e \ - --hash=sha256:605f70e267222d567fc40de7813ee3fb29f8145a1a20aa6fd3dc62baba9312f1 \ - --hash=sha256:60d0f36a42a822e43c4c7472df8a0c980c0f32e5d74ed871333c423a4e942f11 \ - --hash=sha256:62965045cc0fe3dc5dd55d39779620b225ef75962825c7b1b533033cb91810bd \ - --hash=sha256:65162a9cc3f86d70b1d895dbda506e3c079f80d082eb41c54d3f6d33a00b3965 \ - --hash=sha256:659f2c675d478b1bc01b95a8d3ded74fa939b370e71ffbecd496f617b215eb05 \ - --hash=sha256:6b581da13126b8715c0c0585cd37ce934c9864d44b2a4019f5487c0b943275e6 \ - --hash=sha256:71d82dbc7c6c7f5746468e7992e5483aa45b12250d78d220a2431ab88795825c \ - --hash=sha256:7376b13504396da9678b646f5338462347da01286b2a688a0d8493ec764683a2 \ - --hash=sha256:7623659d44a6aa032be4a066c658ba45009d768c2481526fbef7c609702af116 \ - --hash=sha256:7a94020821723a6a210206ddb458001f3ed27e1e6a0555b9422bebf7ead8ff37 \ - --hash=sha256:7d5f1bfc848a94e0d63fe693adee4f88bd9e5c415ecb4c9c17d2d44eba6795a6 \ - --hash=sha256:7efe6c732fd2d7e22d72dc4f7cf9b644020adacfff61b0a8a151343da8e661c0 \ - --hash=sha256:8a602d9fdb567cca090ca19ac3ebf10219065be2a4f8cf9eb8356cffb5a7ab1d \ - --hash=sha256:8cd9ebf335262e864d740f9dad3f672f61162cc0d4825a5eb5cf50df334a688f \ - --hash=sha256:8e6f2bef5aed021fbdf46323d3cd8847bf960efb56394698644a8ee2306f8892 \ - --hash=sha256:93221d5a759bd39b1face1d7d887d2b9ede3e55aefaff8eacf1b663ccdcd204b \ - --hash=sha256:9639289b72f9339721982e156527c296693236d6192ccc31412ab36fccd1683c \ - --hash=sha256:98efaedf2bf79f4d563ca039a57a025b72847bd80568f54709cc39fc1404772c \ - --hash=sha256:9abe093a303e25ac58774a11241150e2fe2947358d1ca12521ad03c90b131060 \ - --hash=sha256:a4321ee8180982d70458d3e8378e31448901bf0ee40fe0d410a87413578f4098 \ - --hash=sha256:a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed \ - --hash=sha256:a91b0e096fdfeb52d86bb8f5ee25dc22483d6960af9b968e6b381a8ec5bfbf82 \ - --hash=sha256:b5e0acbc991472188c9df40eb56d8a97ad3ad00d4de560b8b74bdc2d94041a8f \ - --hash=sha256:b6b5a4542aca4095ab35e184517cb0d18895ba4b6661c92865b431fa7b7974d8 \ - --hash=sha256:ba4a610882171bdaae0779f14e0ff45f3ee271fd2dbf16cdadfc81bd67323232 \ - --hash=sha256:bc5bd9bf5f5894923b78a41c5becd52d6bced1e1e43744855bd85cb341376ca6 \ - --hash=sha256:c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 \ - --hash=sha256:c3c5fa3d4fa0a651cefab391b783f89bc5e331afa0a4e93c9b16141993fa05c8 \ - --hash=sha256:ca5e36a3e7480a5c09aed99ecdb8e6554b21485c3b064297fe77f7b1b5806106 \ - --hash=sha256:d4e0c1b1aa5283f6d9a384ffc7a8400d25386bb98fdb9bddae446e4ef4da7366 \ - --hash=sha256:dc8bc40d82d1ee8dec136e10707c7f3147a6322fd8014e174a0f3446fb793649 \ - --hash=sha256:de576c49d7deab2b78088feb24e1f6ae3e16a0020e8496cdd3b8543f5e350e87 \ - --hash=sha256:e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 \ - --hash=sha256:eb8293d66c6a4ddc72fceb7ad0e111cb196cc394954ae0f9b63c251d97f1b00e \ - --hash=sha256:ee6d8f489a9b116ea8dc797664a50671585a4ca20573359f067858e1231cc217 \ - --hash=sha256:efb878d08dd49d7d9d18512e791b418a1171d08f935475eec98305f0886b7c14 - # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 - # via psycopg -ptyprocess==0.7.0 \ - --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ - --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 - # via - # pexpect - # terminado -pure-eval==0.2.3 \ - --hash=sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 \ - --hash=sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42 - # via stack-data -py==1.11.0 \ - --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \ - --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 - # via feast (setup.py) -py-cpuinfo==9.0.0 \ - --hash=sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690 \ - --hash=sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5 - # via pytest-benchmark -py-spy==0.4.1 \ - --hash=sha256:1fb8bf71ab8df95a95cc387deed6552934c50feef2cf6456bc06692a5508fd0c \ - --hash=sha256:4972c21890b6814017e39ac233c22572c4a61fd874524ebc5ccab0f2237aee0a \ - --hash=sha256:532d3525538254d1859b49de1fbe9744df6b8865657c9f0e444bf36ce3f19226 \ - --hash=sha256:6a80ec05eb8a6883863a367c6a4d4f2d57de68466f7956b6367d4edd5c61bb29 \ - --hash=sha256:809094208c6256c8f4ccadd31e9a513fe2429253f48e20066879239ba12cd8cc \ - --hash=sha256:d92e522bd40e9bf7d87c204033ce5bb5c828fca45fa28d970f58d71128069fdc \ - --hash=sha256:e53aa53daa2e47c2eef97dd2455b47bb3a7e7f962796a86cc3e7dbde8e6f4db4 \ - --hash=sha256:ee776b9d512a011d1ad3907ed53ae32ce2f3d9ff3e1782236554e22103b5c084 - # via ray -py4j==0.10.9.9 \ - --hash=sha256:c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 \ - --hash=sha256:f694cad19efa5bd1dee4f3e5270eb406613c974394035e5bfc4ec1aba870b879 - # via pyspark -pyarrow==17.0.0 \ - --hash=sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a \ - --hash=sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca \ - --hash=sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597 \ - --hash=sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c \ - --hash=sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb \ - --hash=sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977 \ - --hash=sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3 \ - --hash=sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687 \ - --hash=sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7 \ - --hash=sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204 \ - --hash=sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28 \ - --hash=sha256:5984f416552eea15fd9cee03da53542bf4cddaef5afecefb9aa8d1010c335087 \ - --hash=sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15 \ - --hash=sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc \ - --hash=sha256:75c06d4624c0ad6674364bb46ef38c3132768139ddec1c56582dbac54f2663e2 \ - --hash=sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155 \ - --hash=sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df \ - --hash=sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22 \ - --hash=sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a \ - --hash=sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b \ - --hash=sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03 \ - --hash=sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda \ - --hash=sha256:a5c8b238d47e48812ee577ee20c9a2779e6a5904f1708ae240f53ecbee7c9f07 \ - --hash=sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204 \ - --hash=sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b \ - --hash=sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c \ - --hash=sha256:da1e060b3876faa11cee287839f9cc7cdc00649f475714b8680a05fd9071d545 \ - --hash=sha256:db023dc4c6cae1015de9e198d41250688383c3f9af8f565370ab2b4cb5f62655 \ - --hash=sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420 \ - --hash=sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5 \ - --hash=sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4 \ - --hash=sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8 \ - --hash=sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053 \ - --hash=sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145 \ - --hash=sha256:f7ae2de664e0b158d1607699a16a488de3d008ba99b3a7aa5de1cbc13574d047 \ - --hash=sha256:fa3c246cc58cb5a4a5cb407a18f193354ea47dd0648194e6265bd24177982fe8 - # via - # feast (setup.py) - # dask - # datasets - # db-dtypes - # deltalake - # google-cloud-bigquery - # ibis-framework - # pandas-gbq - # ray - # snowflake-connector-python -pyarrow-hotfix==0.7 \ - --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ - --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d - # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa -pyasn1-modules==0.4.2 \ - --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ - --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 - # via google-auth -pybindgen==0.22.0 \ - --hash=sha256:21612f4806a2af25a175716d7e694563af7e10c704538a350cb595d187952f6f \ - --hash=sha256:5b4837d3138ac56863d93fe462f1dac39fb87bd50898e0da4c57fefd645437ac - # via feast (setup.py) -pyclipper==1.4.0 \ - --hash=sha256:0a4d2736fb3c42e8eb1d38bf27a720d1015526c11e476bded55138a977c17d9d \ - --hash=sha256:0b74a9dd44b22a7fd35d65fb1ceeba57f3817f34a97a28c3255556362e491447 \ - --hash=sha256:0b8c2105b3b3c44dbe1a266f64309407fe30bf372cf39a94dc8aaa97df00da5b \ - --hash=sha256:14c8bdb5a72004b721c4e6f448d2c2262d74a7f0c9e3076aeff41e564a92389f \ - --hash=sha256:1b6c8d75ba20c6433c9ea8f1a0feb7e4d3ac06a09ad1fd6d571afc1ddf89b869 \ - --hash=sha256:222ac96c8b8281b53d695b9c4fedc674f56d6d4320ad23f1bdbd168f4e316140 \ - --hash=sha256:29dae3e0296dff8502eeb7639fcfee794b0eec8590ba3563aee28db269da6b04 \ - --hash=sha256:37bfec361e174110cdddffd5ecd070a8064015c99383d95eb692c253951eee8a \ - --hash=sha256:3ef44b64666ebf1cb521a08a60c3e639d21b8c50bfbe846ba7c52a0415e936f4 \ - --hash=sha256:58e29d7443d7cc0e83ee9daf43927730386629786d00c63b04fe3b53ac01462c \ - --hash=sha256:6a97b961f182b92d899ca88c1bb3632faea2e00ce18d07c5f789666ebb021ca4 \ - --hash=sha256:6c317e182590c88ec0194149995e3d71a979cfef3b246383f4e035f9d4a11826 \ - --hash=sha256:773c0e06b683214dcfc6711be230c83b03cddebe8a57eae053d4603dd63582f9 \ - --hash=sha256:7c87480fc91a5af4c1ba310bdb7de2f089a3eeef5fe351a3cedc37da1fcced1c \ - --hash=sha256:81d8bb2d1fb9d66dc7ea4373b176bb4b02443a7e328b3b603a73faec088b952e \ - --hash=sha256:8d42b07a2f6cfe2d9b87daf345443583f00a14e856927782fde52f3a255e305a \ - --hash=sha256:9882bd889f27da78add4dd6f881d25697efc740bf840274e749988d25496c8e1 \ - --hash=sha256:98b2a40f98e1fc1b29e8a6094072e7e0c7dfe901e573bf6cfc6eb7ce84a7ae87 \ - --hash=sha256:9bc45f2463d997848450dbed91c950ca37c6cf27f84a49a5cad4affc0b469e39 \ - --hash=sha256:a8d2b5fb75ebe57e21ce61e79a9131edec2622ff23cc665e4d1d1f201bc1a801 \ - --hash=sha256:a9f11ad133257c52c40d50de7a0ca3370a0cdd8e3d11eec0604ad3c34ba549e9 \ - --hash=sha256:adcb7ca33c5bdc33cd775e8b3eadad54873c802a6d909067a57348bcb96e7a2d \ - --hash=sha256:b3b3630051b53ad2564cb079e088b112dd576e3d91038338ad1cc7915e0f14dc \ - --hash=sha256:bafad70d2679c187120e8c44e1f9a8b06150bad8c0aecf612ad7dfbfa9510f73 \ - --hash=sha256:bbc827b77442c99deaeee26e0e7f172355ddb097a5e126aea206d447d3b26286 \ - --hash=sha256:c9a3faa416ff536cee93417a72bfb690d9dea136dc39a39dbbe1e5dadf108c9c \ - --hash=sha256:ce1f83c9a4e10ea3de1959f0ae79e9a5bd41346dff648fee6228ba9eaf8b3872 \ - --hash=sha256:d1e5498d883b706a4ce636247f0d830c6eb34a25b843a1b78e2c969754ca9037 \ - --hash=sha256:d1f807e2b4760a8e5c6d6b4e8c1d71ef52b7fe1946ff088f4fa41e16a881a5ca \ - --hash=sha256:d49df13cbb2627ccb13a1046f3ea6ebf7177b5504ec61bdef87d6a704046fd6e \ - --hash=sha256:d4b2d7c41086f1927d14947c563dfc7beed2f6c0d9af13c42fe3dcdc20d35832 \ - --hash=sha256:e9b973467d9c5fa9bc30bb6ac95f9f4d7c3d9fc25f6cf2d1cc972088e5955c01 \ - --hash=sha256:f160a2c6ba036f7eaf09f1f10f4fbfa734234af9112fb5187877efed78df9303 \ - --hash=sha256:f2a50c22c3a78cb4e48347ecf06930f61ce98cf9252f2e292aa025471e9d75b1 \ - --hash=sha256:f3672dbafbb458f1b96e1ee3e610d174acb5ace5bd2ed5d1252603bb797f2fc6 \ - --hash=sha256:fd24849d2b94ec749ceac7c34c9f01010d23b6e9d9216cf2238b8481160e703d - # via easyocr -pycparser==2.23 \ - --hash=sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2 \ - --hash=sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934 - # via cffi -pycryptodome==3.23.0 \ - --hash=sha256:0011f7f00cdb74879142011f95133274741778abba114ceca229adbf8e62c3e4 \ - --hash=sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c \ - --hash=sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630 \ - --hash=sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f \ - --hash=sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27 \ - --hash=sha256:257bb3572c63ad8ba40b89f6fc9d63a2a628e9f9708d31ee26560925ebe0210a \ - --hash=sha256:350ebc1eba1da729b35ab7627a833a1a355ee4e852d8ba0447fafe7b14504d56 \ - --hash=sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef \ - --hash=sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5 \ - --hash=sha256:4764e64b269fc83b00f682c47443c2e6e85b18273712b98aa43bcb77f8570477 \ - --hash=sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886 \ - --hash=sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a \ - --hash=sha256:573a0b3017e06f2cffd27d92ef22e46aa3be87a2d317a5abf7cc0e84e321bd75 \ - --hash=sha256:63dad881b99ca653302b2c7191998dd677226222a3f2ea79999aa51ce695f720 \ - --hash=sha256:64093fc334c1eccfd3933c134c4457c34eaca235eeae49d69449dc4728079339 \ - --hash=sha256:6501790c5b62a29fcb227bd6b62012181d886a767ce9ed03b303d1f22eb5c625 \ - --hash=sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490 \ - --hash=sha256:6fe8258e2039eceb74dfec66b3672552b6b7d2c235b2dfecc05d16b8921649a8 \ - --hash=sha256:763d1d74f56f031788e5d307029caef067febf890cd1f8bf61183ae142f1a77b \ - --hash=sha256:7ac1080a8da569bde76c0a104589c4f414b8ba296c0b3738cf39a466a9fb1818 \ - --hash=sha256:865d83c906b0fc6a59b510deceee656b6bc1c4fa0d82176e2b77e97a420a996a \ - --hash=sha256:89d4d56153efc4d81defe8b65fd0821ef8b2d5ddf8ed19df31ba2f00872b8002 \ - --hash=sha256:90460fc9e088ce095f9ee8356722d4f10f86e5be06e2354230a9880b9c549aae \ - --hash=sha256:93837e379a3e5fd2bb00302a47aee9fdf7940d83595be3915752c74033d17ca7 \ - --hash=sha256:954af0e2bd7cea83ce72243b14e4fb518b18f0c1649b576d114973e2073b273d \ - --hash=sha256:9a53a4fe5cb075075d515797d6ce2f56772ea7e6a1e5e4b96cf78a14bac3d265 \ - --hash=sha256:9a77627a330ab23ca43b48b130e202582e91cc69619947840ea4d2d1be21eb39 \ - --hash=sha256:a176b79c49af27d7f6c12e4b178b0824626f40a7b9fed08f712291b6d54bf566 \ - --hash=sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353 \ - --hash=sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b \ - --hash=sha256:b34e8e11d97889df57166eda1e1ddd7676da5fcd4d71a0062a760e75060514b4 \ - --hash=sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2 \ - --hash=sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575 \ - --hash=sha256:ce64e84a962b63a47a592690bdc16a7eaf709d2c2697ababf24a0def566899a6 \ - --hash=sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843 \ - --hash=sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4 \ - --hash=sha256:d97618c9c6684a97ef7637ba43bdf6663a2e2e77efe0f863cce97a76af396446 \ - --hash=sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379 \ - --hash=sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa \ - --hash=sha256:e3f2d0aaf8080bda0587d58fc9fe4766e012441e2eed4269a77de6aea981c8be \ - --hash=sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7 - # via minio -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d - # via - # feast (setup.py) - # codeflare-sdk - # docling - # docling-core - # docling-ibm-models - # docling-parse - # fastapi - # fastapi-mcp - # great-expectations - # mcp - # pydantic-settings - # qdrant-client - # ray -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 - # via pydantic -pydantic-settings==2.12.0 \ - --hash=sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0 \ - --hash=sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809 - # via - # docling - # fastapi-mcp - # mcp -pydata-google-auth==1.9.1 \ - --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ - --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 - # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b - # via - # feast (setup.py) - # ipython - # ipython-pygments-lexers - # mpire - # nbconvert - # rich - # sphinx -pyjwt[crypto]==2.10.1 \ - --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \ - --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb - # via - # feast (setup.py) - # mcp - # msal - # singlestoredb - # snowflake-connector-python -pylatexenc==2.10 \ - --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 - # via docling -pymilvus==2.4.15 \ - --hash=sha256:0601591ce0498315e19e9ac3f4fdd3051102ca87b6ddff5b33849f522288cff7 \ - --hash=sha256:b21878e5df74dca91b3f3cf0b0597fa6b6aed7bf5cde9a1b10641994faa353bf - # via feast (setup.py) -pymongo==4.16.0 \ - --hash=sha256:03f42396c1b2c6f46f5401c5b185adc25f6113716e16d9503977ee5386fca0fb \ - --hash=sha256:12762e7cc0f8374a8cae3b9f9ed8dabb5d438c7b33329232dd9b7de783454033 \ - --hash=sha256:15bb062c0d6d4b0be650410032152de656a2a9a2aa4e1a7443a22695afacb103 \ - --hash=sha256:19a1c96e7f39c7a59a9cfd4d17920cf9382f6f684faeff4649bf587dc59f8edc \ - --hash=sha256:1c01e8a7cd0ea66baf64a118005535ab5bf9f9eb63a1b50ac3935dccf9a54abe \ - --hash=sha256:1d638b0b1b294d95d0fdc73688a3b61e05cc4188872818cd240d51460ccabcb5 \ - --hash=sha256:21d02cc10a158daa20cb040985e280e7e439832fc6b7857bff3d53ef6914ad50 \ - --hash=sha256:2290909275c9b8f637b0a92eb9b89281e18a72922749ebb903403ab6cc7da914 \ - --hash=sha256:25a6b03a68f9907ea6ec8bc7cf4c58a1b51a18e23394f962a6402f8e46d41211 \ - --hash=sha256:2a3ba6be3d8acf64b77cdcd4e36f0e4a8e87965f14a8b09b90ca86f10a1dd2f2 \ - --hash=sha256:2b0714d7764efb29bf9d3c51c964aed7c4c7237b341f9346f15ceaf8321fdb35 \ - --hash=sha256:2cd60cd1e05de7f01927f8e25ca26b3ea2c09de8723241e5d3bcfdc70eaff76b \ - --hash=sha256:2d0082631a7510318befc2b4fdab140481eb4b9dd62d9245e042157085da2a70 \ - --hash=sha256:311d4549d6bf1f8c61d025965aebb5ba29d1481dc6471693ab91610aaffbc0eb \ - --hash=sha256:36ef2fee50eee669587d742fb456e349634b4fcf8926208766078b089054b24b \ - --hash=sha256:3ead8a0050c53eaa55935895d6919d393d0328ec24b2b9115bdbe881aa222673 \ - --hash=sha256:46ffb728d92dd5b09fc034ed91acf5595657c7ca17d4cf3751322cd554153c17 \ - --hash=sha256:4a19ea46a0fe71248965305a020bc076a163311aefbaa1d83e47d06fa30ac747 \ - --hash=sha256:4a9390dce61d705a88218f0d7b54d7e1fa1b421da8129fc7c009e029a9a6b81e \ - --hash=sha256:4c4872299ebe315a79f7f922051061634a64fda95b6b17677ba57ef00b2ba2a4 \ - --hash=sha256:4cd047ba6cc83cc24193b9208c93e134a985ead556183077678c59af7aacc725 \ - --hash=sha256:4d4f7ba040f72a9f43a44059872af5a8c8c660aa5d7f90d5344f2ed1c3c02721 \ - --hash=sha256:4d79aa147ce86aef03079096d83239580006ffb684eead593917186aee407767 \ - --hash=sha256:4fbb8d3552c2ad99d9e236003c0b5f96d5f05e29386ba7abae73949bfebc13dd \ - --hash=sha256:55f8d5a6fe2fa0b823674db2293f92d74cd5f970bc0360f409a1fc21003862d3 \ - --hash=sha256:5b9c6d689bbe5beb156374508133218610e14f8c81e35bc17d7a14e30ab593e6 \ - --hash=sha256:5d9fdb386cf958e6ef6ff537d6149be7edb76c3268cd6833e6c36aa447e4443f \ - --hash=sha256:60307bb91e0ab44e560fe3a211087748b2b5f3e31f403baf41f5b7b0a70bd104 \ - --hash=sha256:61567f712bda04c7545a037e3284b4367cad8d29b3dec84b4bf3b2147020a75b \ - --hash=sha256:66af44ed23686dd5422307619a6db4b56733c5e36fe8c4adf91326dcf993a043 \ - --hash=sha256:6af1aaa26f0835175d2200e62205b78e7ec3ffa430682e322cc91aaa1a0dbf28 \ - --hash=sha256:6b2a20edb5452ac8daa395890eeb076c570790dfce6b7a44d788af74c2f8cf96 \ - --hash=sha256:6f2077ec24e2f1248f9cac7b9a2dfb894e50cc7939fcebfb1759f99304caabef \ - --hash=sha256:77cfd37a43a53b02b7bd930457c7994c924ad8bbe8dff91817904bcbf291b371 \ - --hash=sha256:78037d02389745e247fe5ab0bcad5d1ab30726eaac3ad79219c7d6bbb07eec53 \ - --hash=sha256:7902882ed0efb7f0e991458ab3b8cf0eb052957264949ece2f09b63c58b04f78 \ - --hash=sha256:85dc2f3444c346ea019a371e321ac868a4fab513b7a55fe368f0cc78de8177cc \ - --hash=sha256:8a0f73af1ea56c422b2dcfc0437459148a799ef4231c6aee189d2d4c59d6728f \ - --hash=sha256:8a254d49a9ffe9d7f888e3c677eed3729b14ce85abb08cd74732cead6ccc3c66 \ - --hash=sha256:8ba8405065f6e258a6f872fe62d797a28f383a12178c7153c01ed04e845c600c \ - --hash=sha256:91899dd7fb9a8c50f09c3c1cf0cb73bfbe2737f511f641f19b9650deb61c00ca \ - --hash=sha256:91ac0cb0fe2bf17616c2039dac88d7c9a5088f5cb5829b27c9d250e053664d31 \ - --hash=sha256:92a232af9927710de08a6c16a9710cc1b175fb9179c0d946cd4e213b92b2a69a \ - --hash=sha256:948152b30eddeae8355495f9943a3bf66b708295c0b9b6f467de1c620f215487 \ - --hash=sha256:96aa7ab896889bf330209d26459e493d00f8855772a9453bfb4520bb1f495baf \ - --hash=sha256:9caacac0dd105e2555521002e2d17afc08665187017b466b5753e84c016628e6 \ - --hash=sha256:9d9885aad05f82fd7ea0c9ca505d60939746b39263fa273d0125170da8f59098 \ - --hash=sha256:9dc2c00bed568732b89e211b6adca389053d5e6d2d5a8979e80b813c3ec4d1f9 \ - --hash=sha256:a1bf44e13cf2d44d2ea2e928a8140d5d667304abe1a61c4d55b4906f389fbe64 \ - --hash=sha256:aa30cd16ddd2f216d07ba01d9635c873e97ddb041c61cf0847254edc37d1c60e \ - --hash=sha256:acda193f440dd88c2023cb00aa8bd7b93a9df59978306d14d87a8b12fe426b05 \ - --hash=sha256:bd4911c40a43a821dfd93038ac824b756b6e703e26e951718522d29f6eb166a8 \ - --hash=sha256:be1099a8295b1a722d03fb7b48be895d30f4301419a583dcf50e9045968a041c \ - --hash=sha256:c126fb72be2518395cc0465d4bae03125119136462e1945aea19840e45d89cfc \ - --hash=sha256:c53338613043038005bf2e41a2fafa08d29cdbc0ce80891b5366c819456c1ae9 \ - --hash=sha256:c789236366525c3ee3cd6e4e450a9ff629a7d1f4d88b8e18a0aea0615fd7ecf8 \ - --hash=sha256:cf0ec79e8ca7077f455d14d915d629385153b6a11abc0b93283ed73a8013e376 \ - --hash=sha256:d15f060bc6d0964a8bb70aba8f0cb6d11ae99715438f640cff11bbcf172eb0e8 \ - --hash=sha256:d284bf68daffc57516535f752e290609b3b643f4bd54b28fc13cb16a89a8bda6 \ - --hash=sha256:dabbf3c14de75a20cc3c30bf0c6527157224a93dfb605838eabb1a2ee3be008d \ - --hash=sha256:dbbc5b254c36c37d10abb50e899bc3939bbb7ab1e7c659614409af99bd3e7675 \ - --hash=sha256:dfc320f08ea9a7ec5b2403dc4e8150636f0d6150f4b9792faaae539c88e7db3b \ - --hash=sha256:e2d509786344aa844ae243f68f833ca1ac92ac3e35a92ae038e2ceb44aa355ef \ - --hash=sha256:e37469602473f41221cea93fd3736708f561f0fa08ab6b2873dd962014390d52 \ - --hash=sha256:ed162b2227f98d5b270ecbe1d53be56c8c81db08a1a8f5f02d89c7bb4d19591d \ - --hash=sha256:efe020c46ce3c3a89af6baec6569635812129df6fb6cf76d4943af3ba6ee2069 \ - --hash=sha256:f1c5f1f818b669875d191323a48912d3fcd2e4906410e8297bb09ac50c4d5ccc \ - --hash=sha256:f25001a955073b80510c0c3db0e043dbbc36904fd69e511c74e3d8640b8a5111 \ - --hash=sha256:f3867dc225d9423c245a51eaac2cfcd53dde8e0a8d8090bb6aed6e31bd6c2d4f \ - --hash=sha256:f513b2c6c0d5c491f478422f6b5b5c27ac1af06a54c93ef8631806f7231bd92e \ - --hash=sha256:f6e42c1bc985d9beee884780ae6048790eb4cd565c46251932906bdb1630034a - # via feast (setup.py) -pymssql==2.3.2 \ - --hash=sha256:06883bc9bdb297ae9132d9371b5b1a3a223c8f93dd6a87d1c112c6a688f26d53 \ - --hash=sha256:0768d90f96ae3267d7561d3bcfe94dd671d107489e870388b12570c3debbc552 \ - --hash=sha256:0831c5c95aab0b9aba5142dc97e28f59c4130e1c34ffc13ecbfdd4d2fe45b8a0 \ - --hash=sha256:08facd25a50a7279385d1ffcee9d6d83c4e361db1af38e14519a87d7b1cadb10 \ - --hash=sha256:0a20a17db870fb0e446a6d6bf7664aaf84af7be58ab1fad025cafa4e092507a1 \ - --hash=sha256:1037053e6c74d6fe14c428cc942968b4e4bf06854706a83fe8e822e475e3f107 \ - --hash=sha256:148b7714fff5a5b7ce038e92b02dd9bf68fe442c181a3aae32148e7b13f6db95 \ - --hash=sha256:18089641b687be1ebd0f64f0d1ff977478a397ffa1af372bdf10dbec29cf6d2e \ - --hash=sha256:1afda7b7022eff9451bd83e3f64c450a1a8cdff4ba8b8e399866dcd2cb861a1e \ - --hash=sha256:1bc33ed9af6d8ebea2d49144cd2317b7ae1105dd51dddfd46982c90c8f0cf6ab \ - --hash=sha256:1c99dba4bf5b1ce10657e9e2885f18ba9179190251b63d1498e7d6d72e64f1ce \ - --hash=sha256:1cdc2619e7b4192b8d6619fd52ba8a2eae18b38b376f8649fb8f0727c4e88ff9 \ - --hash=sha256:22b1ce3a48f28ee7d06ebc9ed94276d0bf1c99051ee1df3d2377b74721bd62ef \ - --hash=sha256:22fb0fdd3b889bc10abbe3aa2abe7a008b30a6367b9ba159412d185d7d8fda9d \ - --hash=sha256:235c230e56d8c8c5f289e665c538f31d967fec302d05ad269dcd64fa9d6eb3b7 \ - --hash=sha256:23f5e2e2bdba1cf7cecbac66dd07de7631a8efca5692efee18ff46ebc087b757 \ - --hash=sha256:2568944db3888996e161b40ad06c1b9e0fbb6cfcb38279a3abb98ece7a8e1c4a \ - --hash=sha256:26bdb7abd5f107b6be422635f03e2cecaa52a5f4c394a205014586abbff9e72a \ - --hash=sha256:2a44a0898dacba4e25cac8778d0ed112e297883fe862204e447081888da78dc4 \ - --hash=sha256:2f4093b95f1f3a1232687fc92f652aaf675eb423db8549c16d146b91ac2f0eba \ - --hash=sha256:33ad813092f8fb8f74578c5b5e37c818c4ae130fd4047cb28f0b256f2f107367 \ - --hash=sha256:3870085a49e5332bc67ecb24f217c586977d5352eb51598244fc7bc278eee3e1 \ - --hash=sha256:41d09e1b2534229b288c37b88c1de3d964317af2c7eec58bfb97e01d679eba27 \ - --hash=sha256:5904d78e61668ec89761d3ae01efd4b42b31d820f612929f449e93cd23ba3c54 \ - --hash=sha256:6019d2939963112662288704f608f31634038bffcfd5cad1bc79cb167edb3cc1 \ - --hash=sha256:72b6599963b6e066998c4b27b7bf207684c243b12b1e5dcc180b2af22802ae6c \ - --hash=sha256:73fac766b448613d7ae26e6b304b2cb8a7ffebccaa373633bad3b3cbcc829935 \ - --hash=sha256:793a93da1521fa66bf02b3b873065e22bf14bda5570e005ce3d5fae0776d7b92 \ - --hash=sha256:79cdc3ed1da3129ba56232127db86279728c4328595e2532ed4d0da6379a5c72 \ - --hash=sha256:82ed3dd560d3fb222d26ce3a7373f46dc3ad1d50b6e6417ef7399e87fa9aefe1 \ - --hash=sha256:8cd806380d362d4cef2d925a6baee6a4b2b151a92cac2cab5c4bfabed4be4849 \ - --hash=sha256:9361593a89c9162fc631baf648a87e2666373382d9d54aacfb19edab9ceb2007 \ - --hash=sha256:97fbd8491ad3ece0adcb321acec6db48b8fe37bc74af4c91bb657d4d9347d634 \ - --hash=sha256:9e3d6fada7fbe7a5f5fafc420673f777bab3f399c78fa44e29de6a8cbc36e515 \ - --hash=sha256:a3f9e7eb813dfeab6d01bf6474049bb76b0521235159d3e969ec82df384eac49 \ - --hash=sha256:aa08b6203b2b5ed5ce47f80d5c529459181300d7e0d0c1e84390a4d01d45e509 \ - --hash=sha256:ab48de09864fa6f49c575ef569f6773981d0cd905ff7288b5b185f8079a5a21f \ - --hash=sha256:ab912d1178d5977e421cf9c4d4071958b223cbe4a2b6dd64611d521aa6bb7187 \ - --hash=sha256:ae02cc1594f0addd748bf5ac1ccc7a73c03846ada9c553663c381b242b586606 \ - --hash=sha256:b0c2b11aca16617cacaf385fb94134e73ba0216a924f9b85778cc7e3d3713361 \ - --hash=sha256:b14cc65369d1425f2fb517609113465a0f55f19a49648160f2d10be4cb43ff4d \ - --hash=sha256:b156b15165f7a0bbb392a124d8e2d678145c93e5bfcfef3b637e4d87eadcc85b \ - --hash=sha256:b16d5880f7028442d6c49c94801ce9bff3af8af0fbda7c6039febb936714aed5 \ - --hash=sha256:b3eb201c402bcf4f5b9399df0bb20d522636d2e87d1c6957a0b6d772ee636c61 \ - --hash=sha256:bac6f355c454f94b0e15a04b7841236e5c5c4ef44d2d1beed00a3ad7b50ccc53 \ - --hash=sha256:c24ba6aedb9b5540b56f3e74bff92b687c6e90c00650823385729c7e55923cf5 \ - --hash=sha256:cbe9058b6520be74463476ff2cdb17bbab5ff60b60b3ed7bd8bd2d086bdfd9bd \ - --hash=sha256:cc13c2e0f1b8efc3a46941de9db768fa59937b5a54081ec0cb0ff0da17d1fff3 \ - --hash=sha256:dd5fe7552edc81628e4242b4671f7bad5ff1ec790bae5c7615d989375620edac \ - --hash=sha256:eb629b5fb0376fbf39d575cf1365e504b84877b19f9e8d53caa5228fed56894a \ - --hash=sha256:ee8ee2c7c227c413ad9b88ddba1cb6a25e28c217ae73ecac1c7a6b8c29003604 \ - --hash=sha256:ef0d29c705db552f9e75230f946b0ca9db0db903c5c9ee79ce8b88ad25ea9670 \ - --hash=sha256:f1791f4627c42fe2d2833c884d036b0c5c8cf628f2cdfa3536191c217acf729e \ - --hash=sha256:f282e701dca155b3e7f1644d7e3b60c201ca5f3be8045bce34042d3c737d63ee \ - --hash=sha256:f2b1da4e68d618c7972e583ae19f386ae620258acb61564e8067c203f27cd769 \ - --hash=sha256:f9737c06b13ca2012b9900185fa3af72a37941c532da2e6373dd7c9ab16abddf \ - --hash=sha256:fb8a7b197aaf466a7577ca6690aa9d747081b653ab212d052d71f3cc10587c3b \ - --hash=sha256:fdd774b26407babd0205ef85a098f90553e6b3da77a22322a1e7d2cb51f742c0 - # via feast (setup.py) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 - # via feast (setup.py) -pynacl==1.6.0 \ - --hash=sha256:04f20784083014e265ad58c1b2dd562c3e35864b5394a14ab54f5d150ee9e53e \ - --hash=sha256:10d755cf2a455d8c0f8c767a43d68f24d163b8fe93ccfaabfa7bafd26be58d73 \ - --hash=sha256:140373378e34a1f6977e573033d1dd1de88d2a5d90ec6958c9485b2fd9f3eb90 \ - --hash=sha256:16c60daceee88d04f8d41d0a4004a7ed8d9a5126b997efd2933e08e93a3bd850 \ - --hash=sha256:16dd347cdc8ae0b0f6187a2608c0af1c8b7ecbbe6b4a06bff8253c192f696990 \ - --hash=sha256:25720bad35dfac34a2bcdd61d9e08d6bfc6041bebc7751d9c9f2446cf1e77d64 \ - --hash=sha256:2d6cd56ce4998cb66a6c112fda7b1fdce5266c9f05044fa72972613bef376d15 \ - --hash=sha256:347dcddce0b4d83ed3f32fd00379c83c425abee5a9d2cd0a2c84871334eaff64 \ - --hash=sha256:4853c154dc16ea12f8f3ee4b7e763331876316cc3a9f06aeedf39bcdca8f9995 \ - --hash=sha256:49c336dd80ea54780bcff6a03ee1a476be1612423010472e60af83452aa0f442 \ - --hash=sha256:4a25cfede801f01e54179b8ff9514bd7b5944da560b7040939732d1804d25419 \ - --hash=sha256:51fed9fe1bec9e7ff9af31cd0abba179d0e984a2960c77e8e5292c7e9b7f7b5d \ - --hash=sha256:536703b8f90e911294831a7fbcd0c062b837f3ccaa923d92a6254e11178aaf42 \ - --hash=sha256:5789f016e08e5606803161ba24de01b5a345d24590a80323379fc4408832d290 \ - --hash=sha256:6b08eab48c9669d515a344fb0ef27e2cbde847721e34bba94a343baa0f33f1f4 \ - --hash=sha256:6b393bc5e5a0eb86bb85b533deb2d2c815666665f840a09e0aa3362bb6088736 \ - --hash=sha256:84709cea8f888e618c21ed9a0efdb1a59cc63141c403db8bf56c469b71ad56f2 \ - --hash=sha256:8bfaa0a28a1ab718bad6239979a5a57a8d1506d0caf2fba17e524dbb409441cf \ - --hash=sha256:bbcc4452a1eb10cd5217318c822fde4be279c9de8567f78bad24c773c21254f8 \ - --hash=sha256:cb36deafe6e2bce3b286e5d1f3e1c246e0ccdb8808ddb4550bb2792f2df298f2 \ - --hash=sha256:cf831615cc16ba324240de79d925eacae8265b7691412ac6b24221db157f6bd1 \ - --hash=sha256:dcdeb41c22ff3c66eef5e63049abf7639e0db4edee57ba70531fc1b6b133185d \ - --hash=sha256:dea103a1afcbc333bc0e992e64233d360d393d1e63d0bc88554f572365664348 \ - --hash=sha256:ef214b90556bb46a485b7da8258e59204c244b1b5b576fb71848819b468c44a7 \ - --hash=sha256:f3482abf0f9815e7246d461fab597aa179b7524628a4bc36f86a7dc418d2608d \ - --hash=sha256:f46386c24a65383a9081d68e9c2de909b1834ec74ff3013271f1bca9c2d233eb \ - --hash=sha256:f4b3824920e206b4f52abd7de621ea7a44fd3cb5c8daceb7c3612345dfc54f2e - # via paramiko -pyodbc==5.3.0 \ - --hash=sha256:01166162149adf2b8a6dc21a212718f205cabbbdff4047dc0c415af3fd85867e \ - --hash=sha256:0263323fc47082c2bf02562f44149446bbbfe91450d271e44bffec0c3143bfb1 \ - --hash=sha256:08b2439500e212625471d32f8fde418075a5ddec556e095e5a4ba56d61df2dc6 \ - --hash=sha256:0df7ff47fab91ea05548095b00e5eb87ed88ddf4648c58c67b4db95ea4913e23 \ - --hash=sha256:101313a21d2654df856a60e4a13763e4d9f6c5d3fd974bcf3fc6b4e86d1bbe8e \ - --hash=sha256:13656184faa3f2d5c6f19b701b8f247342ed581484f58bf39af7315c054e69db \ - --hash=sha256:1629af4706e9228d79dabb4863c11cceb22a6dab90700db0ef449074f0150c0d \ - --hash=sha256:197bb6ddafe356a916b8ee1b8752009057fce58e216e887e2174b24c7ab99269 \ - --hash=sha256:2035c7dfb71677cd5be64d3a3eb0779560279f0a8dc6e33673499498caa88937 \ - --hash=sha256:25b6766e56748eb1fc1d567d863e06cbb7b7c749a41dfed85db0031e696fa39a \ - --hash=sha256:25c4cfb2c08e77bc6e82f666d7acd52f0e52a0401b1876e60f03c73c3b8aedc0 \ - --hash=sha256:2eb7151ed0a1959cae65b6ac0454f5c8bbcd2d8bafeae66483c09d58b0c7a7fc \ - --hash=sha256:2fe0e063d8fb66efd0ac6dc39236c4de1a45f17c33eaded0d553d21c199f4d05 \ - --hash=sha256:349a9abae62a968b98f6bbd23d2825151f8d9de50b3a8f5f3271b48958fdb672 \ - --hash=sha256:363311bd40320b4a61454bebf7c38b243cd67c762ed0f8a5219de3ec90c96353 \ - --hash=sha256:3cc472c8ae2feea5b4512e23b56e2b093d64f7cbc4b970af51da488429ff7818 \ - --hash=sha256:3f1bdb3ce6480a17afaaef4b5242b356d4997a872f39e96f015cabef00613797 \ - --hash=sha256:452e7911a35ee12a56b111ac5b596d6ed865b83fcde8427127913df53132759e \ - --hash=sha256:46185a1a7f409761716c71de7b95e7bbb004390c650d00b0b170193e3d6224bb \ - --hash=sha256:46869b9a6555ff003ed1d8ebad6708423adf2a5c88e1a578b9f029fb1435186e \ - --hash=sha256:58635a1cc859d5af3f878c85910e5d7228fe5c406d4571bffcdd281375a54b39 \ - --hash=sha256:5cbe4d753723c8a8f65020b7a259183ef5f14307587165ce37e8c7e251951852 \ - --hash=sha256:5ceaed87ba2ea848c11223f66f629ef121f6ebe621f605cde9cfdee4fd9f4b68 \ - --hash=sha256:5dd3d5e469f89a3112cf8b0658c43108a4712fad65e576071e4dd44d2bd763c7 \ - --hash=sha256:5ebf6b5d989395efe722b02b010cb9815698a4d681921bf5db1c0e1195ac1bde \ - --hash=sha256:6132554ffbd7910524d643f13ce17f4a72f3a6824b0adef4e9a7f66efac96350 \ - --hash=sha256:6682cdec78f1302d0c559422c8e00991668e039ed63dece8bf99ef62173376a5 \ - --hash=sha256:676031723aac7dcbbd2813bddda0e8abf171b20ec218ab8dfb21d64a193430ea \ - --hash=sha256:705903acf6f43c44fc64e764578d9a88649eb21bf7418d78677a9d2e337f56f2 \ - --hash=sha256:729c535341bb09c476f219d6f7ab194bcb683c4a0a368010f1cb821a35136f05 \ - --hash=sha256:74528fe148980d0c735c0ebb4a4dc74643ac4574337c43c1006ac4d09593f92d \ - --hash=sha256:754d052030d00c3ac38da09ceb9f3e240e8dd1c11da8906f482d5419c65b9ef5 \ - --hash=sha256:7713c740a10f33df3cb08f49a023b7e1e25de0c7c99650876bbe717bc95ee780 \ - --hash=sha256:7e9ab0b91de28a5ab838ac4db0253d7cc8ce2452efe4ad92ee6a57b922bf0c24 \ - --hash=sha256:8339d3094858893c1a68ee1af93efc4dff18b8b65de54d99104b99af6306320d \ - --hash=sha256:8aa396c6d6af52ccd51b8c8a5bffbb46fd44e52ce07ea4272c1d28e5e5b12722 \ - --hash=sha256:9b987a25a384f31e373903005554230f5a6d59af78bce62954386736a902a4b3 \ - --hash=sha256:9cd3f0a9796b3e1170a9fa168c7e7ca81879142f30e20f46663b882db139b7d2 \ - --hash=sha256:a48d731432abaee5256ed6a19a3e1528b8881f9cb25cb9cf72d8318146ea991b \ - --hash=sha256:ac23feb7ddaa729f6b840639e92f83ff0ccaa7072801d944f1332cd5f5b05f47 \ - --hash=sha256:af4d8c9842fc4a6360c31c35508d6594d5a3b39922f61b282c2b4c9d9da99514 \ - --hash=sha256:afe7c4ac555a8d10a36234788fc6cfc22a86ce37fc5ba88a1f75b3e6696665dc \ - --hash=sha256:b180bc5e49b74fd40a24ef5b0fe143d0c234ac1506febe810d7434bf47cb925b \ - --hash=sha256:b35b9983ad300e5aea82b8d1661fc9d3afe5868de527ee6bd252dd550e61ecd6 \ - --hash=sha256:bc834567c2990584b9726cba365834d039380c9dbbcef3030ddeb00c6541b943 \ - --hash=sha256:bfeb3e34795d53b7d37e66dd54891d4f9c13a3889a8f5fe9640e56a82d770955 \ - --hash=sha256:c25dc9c41f61573bdcf61a3408c34b65e4c0f821b8f861ca7531b1353b389804 \ - --hash=sha256:c2eb0b08e24fe5c40c7ebe9240c5d3bd2f18cd5617229acee4b0a0484dc226f2 \ - --hash=sha256:c5c30c5cd40b751f77bbc73edd32c4498630939bcd4e72ee7e6c9a4b982cc5ca \ - --hash=sha256:c67e7f2ce649155ea89beb54d3b42d83770488f025cf3b6f39ca82e9c598a02e \ - --hash=sha256:c68d9c225a97aedafb7fff1c0e1bfe293093f77da19eaf200d0e988fa2718d16 \ - --hash=sha256:c6ccb5315ec9e081f5cbd66f36acbc820ad172b8fa3736cf7f993cdf69bd8a96 \ - --hash=sha256:c79df54bbc25bce9f2d87094e7b39089c28428df5443d1902b0cc5f43fd2da6f \ - --hash=sha256:cf18797a12e70474e1b7f5027deeeccea816372497e3ff2d46b15bec2d18a0cc \ - --hash=sha256:d255f6b117d05cfc046a5201fdf39535264045352ea536c35777cf66d321fbb8 \ - --hash=sha256:d32c3259762bef440707098010035bbc83d1c73d81a434018ab8c688158bd3bb \ - --hash=sha256:d89a7f2e24227150c13be8164774b7e1f9678321a4248f1356a465b9cc17d31e \ - --hash=sha256:e3c39de3005fff3ae79246f952720d44affc6756b4b85398da4c5ea76bf8f506 \ - --hash=sha256:e981db84fee4cebec67f41bd266e1e7926665f1b99c3f8f4ea73cd7f7666e381 \ - --hash=sha256:ebc3be93f61ea0553db88589e683ace12bf975baa954af4834ab89f5ee7bf8ae \ - --hash=sha256:f1ad0e93612a6201621853fc661209d82ff2a35892b7d590106fe8f97d9f1f2a \ - --hash=sha256:f927b440c38ade1668f0da64047ffd20ec34e32d817f9a60d07553301324b364 \ - --hash=sha256:fc5ac4f2165f7088e74ecec5413b5c304247949f9702c8853b0e43023b4187e8 \ - --hash=sha256:fe77eb9dcca5fc1300c9121f81040cc9011d28cff383e2c35416e9ec06d4bc95 - # via - # feast (setup.py) - # ibis-framework -pyopenssl==25.1.0 \ - --hash=sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab \ - --hash=sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b - # via snowflake-connector-python -pyparsing==3.3.1 \ - --hash=sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82 \ - --hash=sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c - # via great-expectations -pypdfium2==4.30.0 \ - --hash=sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e \ - --hash=sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29 \ - --hash=sha256:3d0dd3ecaffd0b6dbda3da663220e705cb563918249bda26058c6036752ba3a2 \ - --hash=sha256:48b5b7e5566665bc1015b9d69c1ebabe21f6aee468b509531c3c8318eeee2e16 \ - --hash=sha256:4e55689f4b06e2d2406203e771f78789bd4f190731b5d57383d05cf611d829de \ - --hash=sha256:4e6e50f5ce7f65a40a33d7c9edc39f23140c57e37144c2d6d9e9262a2a854854 \ - --hash=sha256:5eda3641a2da7a7a0b2f4dbd71d706401a656fea521b6b6faa0675b15d31a163 \ - --hash=sha256:90dbb2ac07be53219f56be09961eb95cf2473f834d01a42d901d13ccfad64b4c \ - --hash=sha256:b33ceded0b6ff5b2b93bc1fe0ad4b71aa6b7e7bd5875f1ca0cdfb6ba6ac01aab \ - --hash=sha256:cc3bf29b0db8c76cdfaac1ec1cde8edf211a7de7390fbf8934ad2aa9b4d6dfad \ - --hash=sha256:ee2410f15d576d976c2ab2558c93d392a25fb9f6635e8dd0a8a3a5241b275e0e \ - --hash=sha256:f1f78d2189e0ddf9ac2b7a9b9bd4f0c66f54d1389ff6c17e9fd9dc034d06eb3f \ - --hash=sha256:f33bd79e7a09d5f7acca3b0b69ff6c8a488869a7fab48fdf400fec6e20b9c8be - # via docling -pyproject-hooks==1.2.0 \ - --hash=sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8 \ - --hash=sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 - # via - # build - # pip-tools -pyspark==4.1.1 \ - --hash=sha256:77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec - # via feast (setup.py) -pytest==7.4.4 \ - --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ - --hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8 - # via - # feast (setup.py) - # pytest-asyncio - # pytest-benchmark - # pytest-cov - # pytest-env - # pytest-lazy-fixture - # pytest-mock - # pytest-ordering - # pytest-timeout - # pytest-xdist -pytest-asyncio==0.23.8 \ - --hash=sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2 \ - --hash=sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3 - # via feast (setup.py) -pytest-benchmark==3.4.1 \ - --hash=sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809 \ - --hash=sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47 - # via feast (setup.py) -pytest-cov==7.0.0 \ - --hash=sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1 \ - --hash=sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861 - # via feast (setup.py) -pytest-env==1.1.3 \ - --hash=sha256:aada77e6d09fcfb04540a6e462c58533c37df35fa853da78707b17ec04d17dfc \ - --hash=sha256:fcd7dc23bb71efd3d35632bde1bbe5ee8c8dc4489d6617fb010674880d96216b - # via feast (setup.py) -pytest-lazy-fixture==0.6.3 \ - --hash=sha256:0e7d0c7f74ba33e6e80905e9bfd81f9d15ef9a790de97993e34213deb5ad10ac \ - --hash=sha256:e0b379f38299ff27a653f03eaa69b08a6fd4484e46fd1c9907d984b9f9daeda6 - # via feast (setup.py) -pytest-mock==1.10.4 \ - --hash=sha256:43ce4e9dd5074993e7c021bb1c22cbb5363e612a2b5a76bc6d956775b10758b7 \ - --hash=sha256:5bf5771b1db93beac965a7347dc81c675ec4090cb841e49d9d34637a25c30568 - # via feast (setup.py) -pytest-ordering==0.6 \ - --hash=sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2 \ - --hash=sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6 \ - --hash=sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6 - # via feast (setup.py) -pytest-timeout==1.4.2 \ - --hash=sha256:20b3113cf6e4e80ce2d403b6fb56e9e1b871b510259206d40ff8d609f48bda76 \ - --hash=sha256:541d7aa19b9a6b4e475c759fd6073ef43d7cdc9a92d95644c260076eb257a063 - # via feast (setup.py) -pytest-xdist==3.8.0 \ - --hash=sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 \ - --hash=sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1 - # via feast (setup.py) -python-bidi==0.6.7 \ - --hash=sha256:01ff2fd676ef8351f32e820b2d3b61eac875a21702d2118263a2641b458e1996 \ - --hash=sha256:05fe5971110013610f0db40505d0b204edc756e92eafac1372a464f8b9162b11 \ - --hash=sha256:06650a164e63e94dc8a291cc9d415b4027cb1cce125bc9b02dac0f34d535ed47 \ - --hash=sha256:0cb75e8a410166fd677d55095e505bf6a4773c066f51efbda72d302ebc56e79b \ - --hash=sha256:0dbb4bbae212cca5bcf6e522fe8f572aff7d62544557734c2f810ded844d9eea \ - --hash=sha256:0f86e447e94ae78db7d56e7da2124c435eaee4425c87d3d92aea271317811112 \ - --hash=sha256:11c51579e01f768446a7e13a0059fea1530936a707abcbeaad9467a55cb16073 \ - --hash=sha256:1395e236c71f11267860b53293a33b19b991b06e0f4ac61045b892e6a99d96f2 \ - --hash=sha256:17572944e6d8fb616d111fc702c759da2bf7cedab85a3e4fa2af0c9eb95ed438 \ - --hash=sha256:19737d217088ef27014f98eac1827c5913e6fb1dea96332ed84ede61791070d9 \ - --hash=sha256:1ba28642928d1c8fdb18b0632fe931f156e888c646326a3ad8eb3e55ee904951 \ - --hash=sha256:1c061207212cd1db27bf6140b96dcd0536246f1e13e99bb5d03f4632f8e2ad7f \ - --hash=sha256:1c5fb99f774748de283fadf915106f130b74be1bade934b7f73a7a8488b95da1 \ - --hash=sha256:1dd0a5ec0d8710905cebb4c9e5018aa8464395a33cb32a3a6c2a951bf1984fe5 \ - --hash=sha256:24388c77cb00b8aa0f9c84beb7e3e523a3dac4f786ece64a1d8175a07b24da72 \ - --hash=sha256:24a4a268289bbe80ad7da3064d7325f1571173859e8ad75d2f99075d5278b02b \ - --hash=sha256:24afff65c581a5d6f658a9ec027d6719d19a1d8a4401000fdb22d2eeb677b8e3 \ - --hash=sha256:257d6dd0e07221f1dc8720fa61158471f5aae30d5f89837c38a026386151c250 \ - --hash=sha256:26a8fe0d532b966708fc5f8aea0602107fde4745a8a5ae961edd3cf02e807d07 \ - --hash=sha256:2a93b0394cc684d64356b0475858c116f1e335ffbaba388db93bf47307deadfa \ - --hash=sha256:2d28e2bdcadf5b6161bb4ee9313ce41eac746ba57e744168bf723a415a11af05 \ - --hash=sha256:349b89c3110bd25aa56d79418239ca4785d4bcc7a596e63bb996a9696fc6a907 \ - --hash=sha256:3a85275dfc24a96629da058c4c2fc93af6390aefe2f7cdde1500b6ac3fd40ca0 \ - --hash=sha256:3b63d19f3f56ff7f99bce5ca9ef8c811dbf0f509d8e84c1bc06105ed26a49528 \ - --hash=sha256:3b96744e4709f4445788a3645cea7ef8d7520ccd4fa8bbbfb3b650702e12c1e6 \ - --hash=sha256:414004fe9cba33d288ff4a04e1c9afe6a737f440595d01b5bbed00d750296bbd \ - --hash=sha256:4283f8b517411cc81b3c92d11998981fe54ac0d2300f4c58d803e0c071aba1ba \ - --hash=sha256:4636d572b357ab9f313c5340915c1cf51e3e54dd069351e02b6b76577fd1a854 \ - --hash=sha256:47deaada8949af3a790f2cd73b613f9bfa153b4c9450f91c44a60c3109a81f73 \ - --hash=sha256:49639743f1230648fd4fb47547f8a48ada9c5ca1426b17ac08e3be607c65394c \ - --hash=sha256:4c73cd980d45bb967799c7f0fc98ea93ae3d65b21ef2ba6abef6a057720bf483 \ - --hash=sha256:4d84e70923392f8c9611f0fb6b341577346ef6224f3809b05f0ae1fbf8f17578 \ - --hash=sha256:4ea928c31c7364098f853f122868f6f2155d6840661f7ea8b2ccfdf6084eb9f4 \ - --hash=sha256:5013ba963e9da606c4c03958cc737ebd5f8b9b8404bd71ab0d580048c746f875 \ - --hash=sha256:5debaab33562fdfc79ffdbd8d9c51cf07b8529de0e889d8cd145d78137aab21e \ - --hash=sha256:5ebc19f24e65a1f5c472e26d88e78b9d316e293bc6f205f32de4c4e99276336e \ - --hash=sha256:630cee960ba9e3016f95a8e6f725a621ddeff6fd287839f5693ccfab3f3a9b5c \ - --hash=sha256:6323e943c7672b271ad9575a2232508f17e87e81a78d7d10d6e93040e210eddf \ - --hash=sha256:6c051f2d28ca542092d01da8b5fe110fb6191ff58d298a54a93dc183bece63bf \ - --hash=sha256:6c19ab378fefb1f09623f583fcfa12ed42369a998ddfbd39c40908397243c56b \ - --hash=sha256:6df7be07af867ec1d121c92ea827efad4d77b25457c06eeab477b601e82b2340 \ - --hash=sha256:6f9fa1257e075eeeed67d21f95e411036b7ca2b5c78f757d4ac66485c191720a \ - --hash=sha256:7336a3c4ba4fc9e6741fbe60c6483266fe39e1f24830724dfce453471d11fa40 \ - --hash=sha256:73a88dc333efc42281bd800d5182c8625c6e11d109fc183fe3d7a11d48ab1150 \ - --hash=sha256:766d5f5a686eb99b53168a7bdfb338035931a609bdbbcb537cef9e050a86f359 \ - --hash=sha256:77bb4cbadf4121db395189065c58c9dd5d1950257cc1983004e6df4a3e2f97ad \ - --hash=sha256:77fea54c2379b93def4ed16db6390e1232e7b235679587295a23dd8b1925475f \ - --hash=sha256:8047c33b85f7790474a1f488bef95689f049976a4e1c6f213a8d075d180a93e4 \ - --hash=sha256:80e6fd06f6e4074d183cea73962c89cf76cb4f70c0ee403689f57a429ebde488 \ - --hash=sha256:849a57d39feaf897955d0b19bbf4796bea53d1bcdf83b82e0a7b059167eb2049 \ - --hash=sha256:8678c2272e7bd60a75f781409e900c9ddb9f01f55c625d83ae0d49dfc6a2674f \ - --hash=sha256:8814db38fa317bebec8eb74b826bae7d0cb978a7eca30dfe4ecf60e61f06ee0b \ - --hash=sha256:8860d67dc04dc530b8b4f588f38b7341a76f2ec44a45685a2d54e9dcffa5d15a \ - --hash=sha256:898db0ea3e4aaa95b7fecba02a7560dfbf368f9d85053f2875f6d610c4d4ec2c \ - --hash=sha256:8a17631e3e691eec4ae6a370f7b035cf0a5767f4457bd615d11728c23df72e43 \ - --hash=sha256:8a18c61817f3210ba74ad5792c8a5048d9550ba233233a0a8fe35800350988f4 \ - --hash=sha256:8d4e621caadfdbc73d36eabdb2f392da850d28c58b020738411d09dda6208509 \ - --hash=sha256:94dbfd6a6ec0ae64b5262290bf014d6063f9ac8688bda9ec668dc175378d2c80 \ - --hash=sha256:95867a07c5dee0ea2340fe1d0e4f6d9f5c5687d473193b6ee6f86fa44aac45d1 \ - --hash=sha256:95c9de7ebc55ffb777548f2ecaf4b96b0fa0c92f42bf4d897b9f4cd164ec7394 \ - --hash=sha256:9adeec7cab0f2c2c291bd7faf9fa3fa233365fd0bf1c1c27a6ddd6cc563d4b32 \ - --hash=sha256:9c463ae15e94b1c6a8a50bd671d6166b0b0d779fd1e56cbf46d8a4a84c9aa2d0 \ - --hash=sha256:9d9de35eb5987da27dd81e371c52142dd8e924bd61c1006003071ea05a735587 \ - --hash=sha256:a2eb8fca918c7381531035c3aae31c29a1c1300ab8a63cad1ec3a71331096c78 \ - --hash=sha256:a4319f478ab1b90bbbe9921606ecb7baa0ebf0b332e821d41c3abdf1a30f0c35 \ - --hash=sha256:a507fe6928a27a308e04ebf2065719b7850d1bf9ff1924f4e601ef77758812bd \ - --hash=sha256:a8892a7da0f617135fe9c92dc7070d13a0f96ab3081f9db7ff5b172a3905bd78 \ - --hash=sha256:a99d898ad1a399d9c8cab5561b3667fd24f4385820ac90c3340aa637aa5adfc9 \ - --hash=sha256:aa4136f8ccb9a8cd32befd1b3882c2597e6791e64e8b3cf3129c55549b5de62f \ - --hash=sha256:ab2a5177522b62426db897b655a02f574e27d9735bbeb6da41bc981b771df636 \ - --hash=sha256:ab806fd026bfd48bade5e21e06d0d799cbfad32f236989ff6f37db03a5fbe34f \ - --hash=sha256:ad5f0847da00687f52d2b81828e8d887bdea9eb8686a9841024ea7a0e153028e \ - --hash=sha256:b0bee27fb596a0f518369c275a965d0448c39a0730e53a030b311bb10562d4d5 \ - --hash=sha256:b31d66b62736b8514982a24a7dedcf8c062b27a8e9b51e52d7a5899045a45fe1 \ - --hash=sha256:b38ddfab41d10e780edb431edc30aec89bee4ce43d718e3896e99f33dae5c1d3 \ - --hash=sha256:be1bdbd52145dfe46880d8bb56eacc25aa75c3bb075fa103de7974295eb2811f \ - --hash=sha256:c10065081c0e137975de5d9ba2ff2306286dbf5e0c586d4d5aec87c856239b41 \ - --hash=sha256:c11c62a3cdb9d1426b1536de9e3446cb09c7d025bd4df125275cae221f214899 \ - --hash=sha256:c3777ae3e088e94df854fbcbd8d59f9239b74aac036cb6bbd19f8035c8e42478 \ - --hash=sha256:c3d93171dd65b36eca5367acf19eef82c79b4df557cb4bd0daf323b7a27f2d3b \ - --hash=sha256:c9a679b24f5c6f366a0dec75745e1abeae2f597f033d0d54c74cbe62e7e6ae28 \ - --hash=sha256:caa71c723f512f8d859fa239573086e16f38ffc426b5b2f7dab5d40fdb356c80 \ - --hash=sha256:ce86d9dfc6b409ad16556384244572bb3cbefa2ca0f0eab7fba0ff2112b2f068 \ - --hash=sha256:d4cd82e65b5aeb31bd73534e61ece1cab625f4bcbdc13bc4ddc5f8cbfb37c24a \ - --hash=sha256:d524a4ba765bae9b950706472a77a887a525ed21144fe4b41f6190f6e57caa2c \ - --hash=sha256:d7310312a68fdb1a8249cf114acb5435aa6b6a958b15810f053c1df5f98476e4 \ - --hash=sha256:d8274ff02d447cca026ba00f56070ba15f95e184b2d028ee0e4b6c9813d2aaf9 \ - --hash=sha256:d879be7fb5296409e18731c7ba666d56ecd45b816b2c9eb35138aa1d7777aeb5 \ - --hash=sha256:d87ed09e5c9b6d2648e8856a4e556147b9d3cd4d63905fa664dd6706bc414256 \ - --hash=sha256:dde1c3f3edb1f0095dcbf79cf8a0bb768f9539e809d0ad010d78200eea97d42a \ - --hash=sha256:df5e9db9539d70426f5d20c7ebb6f7b33da5fbd40620e11261fe3fba7e177145 \ - --hash=sha256:e7cad66317f12f0fd755fe41ee7c6b06531d2189a9048a8f37addb5109f7e3e3 \ - --hash=sha256:ec1694134961b71ac05241ac989b49ccf08e232b5834d5fc46f8a7c3bb1c13a9 \ - --hash=sha256:ec985386bc3cd54155f2ef0434fccbfd743617ed6fc1a84dae2ab1de6062e0c6 \ - --hash=sha256:ef9d103706560c15fecaf7d3cff939e0f68ce5763cf0e64d0e4e5d37f9bdd2d1 \ - --hash=sha256:f1350033431d75be749273236dcfc808e54404cd6ece6204cdb1bc4ccc163455 \ - --hash=sha256:f1fe71c203f66bc169a393964d5702f9251cfd4d70279cb6453fdd42bd2e675f \ - --hash=sha256:f24189dc3aea3a0a94391a047076e1014306b39ba17d7a38ebab510553cd1a97 \ - --hash=sha256:f57726b5a90d818625e6996f5116971b7a4ceb888832337d0e2cf43d1c362a90 \ - --hash=sha256:f7c055a50d068b3a924bd33a327646346839f55bcb762a26ec3fde8ea5d40564 \ - --hash=sha256:f7e5072269c34a1b719910ee4decf13b288159fb320f18aba3885f6b6aab7753 \ - --hash=sha256:f7e507e1e798ebca77ddc9774fd405107833315ad802cfdaa1ab07b6d9154fc8 \ - --hash=sha256:fbbffb948a32f9783d1a28bc0c53616f0a76736ed1e7c1d62e3e99a8dfaab869 \ - --hash=sha256:fd87d112eda1f0528074e1f7c0312881816cb75854133021124269a27c6c48dc \ - --hash=sha256:ff06e4aa781aa4f68fbfaf1e727fe221fa1c552fef8ae70b6d2a0178e1f229ad - # via easyocr -python-dateutil==2.9.0 \ - --hash=sha256:78e73e19c63f5b20ffa567001531680d939dc042bf7850431877645523c66709 \ - --hash=sha256:cbf2f1da5e6083ac2fbfd4da39a25f34312230110440f424a14c7558bb85d82e - # via - # feast (setup.py) - # aiobotocore - # arrow - # botocore - # elasticsearch - # google-cloud-bigquery - # great-expectations - # ibis-framework - # jupyter-client - # kubernetes - # moto - # pandas - # trino -python-docx==1.2.0 \ - --hash=sha256:3fd478f3250fbbbfd3b94fe1e985955737c145627498896a8a6bf81f4baf66c7 \ - --hash=sha256:7bc9d7b7d8a69c9c02ca09216118c86552704edc23bac179283f2e38f86220ce - # via docling -python-dotenv==1.2.1 \ - --hash=sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6 \ - --hash=sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 - # via - # pydantic-settings - # pymilvus - # testcontainers - # uvicorn -python-json-logger==4.0.0 \ - --hash=sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2 \ - --hash=sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f - # via jupyter-events -python-keycloak==4.2.2 \ - --hash=sha256:1d43a1accd4a038ed39317fcb3eb78211df6c75bbcbc4c482c99ee76327136f2 \ - --hash=sha256:5137fd87c69031a372a578df96bae96b9aead2c9dad976613bc978e9e0246a1e - # via feast (setup.py) -python-multipart==0.0.21 \ - --hash=sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92 \ - --hash=sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090 - # via mcp -python-pptx==1.0.2 \ - --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ - --hash=sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095 - # via docling -pytz==2025.2 \ - --hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 \ - --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 - # via - # clickhouse-connect - # great-expectations - # ibis-framework - # pandas - # snowflake-connector-python - # trino -pyyaml==6.0.3 \ - --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ - --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ - --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ - --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ - --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ - --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ - --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ - --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ - --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ - --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ - --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ - --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ - --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ - --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ - --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ - --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ - --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ - --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ - --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ - --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ - --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ - --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ - --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ - --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ - --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ - --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ - --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ - --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ - --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ - --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ - --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ - --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ - --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ - --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ - --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ - --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ - --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ - --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ - --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ - --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ - --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ - --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ - --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ - --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ - --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ - --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ - --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ - --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ - --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ - --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ - --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ - --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ - --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ - --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ - --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ - --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ - --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ - --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ - --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ - --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ - --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ - --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ - --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ - --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ - --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ - --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ - --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ - --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ - --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ - --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ - --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ - --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ - --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 - # via - # feast (setup.py) - # accelerate - # dask - # datasets - # docling-core - # easyocr - # huggingface-hub - # ibis-substrait - # jupyter-events - # kubernetes - # openshift-client - # pre-commit - # ray - # responses - # timm - # transformers - # uvicorn -pyzmq==27.1.0 \ - --hash=sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d \ - --hash=sha256:01f9437501886d3a1dd4b02ef59fb8cc384fa718ce066d52f175ee49dd5b7ed8 \ - --hash=sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e \ - --hash=sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba \ - --hash=sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581 \ - --hash=sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05 \ - --hash=sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386 \ - --hash=sha256:0c996ded912812a2fcd7ab6574f4ad3edc27cb6510349431e4930d4196ade7db \ - --hash=sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28 \ - --hash=sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e \ - --hash=sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea \ - --hash=sha256:18339186c0ed0ce5835f2656cdfb32203125917711af64da64dbaa3d949e5a1b \ - --hash=sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066 \ - --hash=sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97 \ - --hash=sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0 \ - --hash=sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113 \ - --hash=sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92 \ - --hash=sha256:1f8426a01b1c4098a750973c37131cf585f61c7911d735f729935a0c701b68d3 \ - --hash=sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86 \ - --hash=sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd \ - --hash=sha256:346e9ba4198177a07e7706050f35d733e08c1c1f8ceacd5eb6389d653579ffbc \ - --hash=sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233 \ - --hash=sha256:3970778e74cb7f85934d2b926b9900e92bfe597e62267d7499acc39c9c28e345 \ - --hash=sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31 \ - --hash=sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74 \ - --hash=sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc \ - --hash=sha256:49d3980544447f6bd2968b6ac913ab963a49dcaa2d4a2990041f16057b04c429 \ - --hash=sha256:4a19387a3dddcc762bfd2f570d14e2395b2c9701329b266f83dd87a2b3cbd381 \ - --hash=sha256:4c618fbcd069e3a29dcd221739cacde52edcc681f041907867e0f5cc7e85f172 \ - --hash=sha256:50081a4e98472ba9f5a02850014b4c9b629da6710f8f14f3b15897c666a28f1b \ - --hash=sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556 \ - --hash=sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4 \ - --hash=sha256:510869f9df36ab97f89f4cff9d002a89ac554c7ac9cadd87d444aa4cf66abd27 \ - --hash=sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c \ - --hash=sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd \ - --hash=sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e \ - --hash=sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526 \ - --hash=sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e \ - --hash=sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f \ - --hash=sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128 \ - --hash=sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96 \ - --hash=sha256:722ea791aa233ac0a819fc2c475e1292c76930b31f1d828cb61073e2fe5e208f \ - --hash=sha256:726b6a502f2e34c6d2ada5e702929586d3ac948a4dbbb7fed9854ec8c0466027 \ - --hash=sha256:753d56fba8f70962cd8295fb3edb40b9b16deaa882dd2b5a3a2039f9ff7625aa \ - --hash=sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f \ - --hash=sha256:7be883ff3d722e6085ee3f4afc057a50f7f2e0c72d289fd54df5706b4e3d3a50 \ - --hash=sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c \ - --hash=sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2 \ - --hash=sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146 \ - --hash=sha256:849ca054d81aa1c175c49484afaaa5db0622092b5eccb2055f9f3bb8f703782d \ - --hash=sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97 \ - --hash=sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5 \ - --hash=sha256:9541c444cfe1b1c0156c5c86ece2bb926c7079a18e7b47b0b1b3b1b875e5d098 \ - --hash=sha256:96c71c32fff75957db6ae33cd961439f386505c6e6b377370af9b24a1ef9eafb \ - --hash=sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32 \ - --hash=sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62 \ - --hash=sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf \ - --hash=sha256:a1aa0ee920fb3825d6c825ae3f6c508403b905b698b6460408ebd5bb04bbb312 \ - --hash=sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda \ - --hash=sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540 \ - --hash=sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604 \ - --hash=sha256:ad68808a61cbfbbae7ba26d6233f2a4aa3b221de379ce9ee468aa7a83b9c36b0 \ - --hash=sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db \ - --hash=sha256:b1267823d72d1e40701dcba7edc45fd17f71be1285557b7fe668887150a14b78 \ - --hash=sha256:b2e592db3a93128daf567de9650a2f3859017b3f7a66bc4ed6e4779d6034976f \ - --hash=sha256:b721c05d932e5ad9ff9344f708c96b9e1a485418c6618d765fca95d4daacfbef \ - --hash=sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2 \ - --hash=sha256:bd67e7c8f4654bef471c0b1ca6614af0b5202a790723a58b79d9584dc8022a78 \ - --hash=sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b \ - --hash=sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f \ - --hash=sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6 \ - --hash=sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39 \ - --hash=sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f \ - --hash=sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355 \ - --hash=sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a \ - --hash=sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a \ - --hash=sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856 \ - --hash=sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9 \ - --hash=sha256:da96ecdcf7d3919c3be2de91a8c513c186f6762aa6cf7c01087ed74fad7f0968 \ - --hash=sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7 \ - --hash=sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1 \ - --hash=sha256:df7cd397ece96cf20a76fae705d40efbab217d217897a5053267cd88a700c266 \ - --hash=sha256:e2687c2d230e8d8584fbea433c24382edfeda0c60627aca3446aa5e58d5d1831 \ - --hash=sha256:e30a74a39b93e2e1591b58eb1acef4902be27c957a8720b0e368f579b82dc22f \ - --hash=sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7 \ - --hash=sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394 \ - --hash=sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07 \ - --hash=sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496 \ - --hash=sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90 \ - --hash=sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271 \ - --hash=sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6 \ - --hash=sha256:ff8d114d14ac671d88c89b9224c63d6c4e5a613fe8acd5594ce53d752a3aafe9 - # via - # ipykernel - # jupyter-client - # jupyter-server -qdrant-client==1.16.2 \ - --hash=sha256:442c7ef32ae0f005e88b5d3c0783c63d4912b97ae756eb5e052523be682f17d3 \ - --hash=sha256:ca4ef5f9be7b5eadeec89a085d96d5c723585a391eb8b2be8192919ab63185f0 - # via feast (setup.py) -ray[data, default]==2.52.1 \ - --hash=sha256:08eb8f5fd55292ba6bee363a32491136a5e54af54e007f81e0603986fbea41a4 \ - --hash=sha256:24694e60cdc7770b90f123cc578cabb9d1a231c1fe673b5da0027b118de45846 \ - --hash=sha256:2b57ef272a2a0a0dbae6d18d70aa541eab620b4fe3b44d50466d3a533c16f9d9 \ - --hash=sha256:4e8478544fef69a17d865431c0bebdcfeff7c0f76a306f29b73c3bc3cbb0bdb9 \ - --hash=sha256:65bf461fdfe4ffa667c46f9455f8740b2ad6c1fa471b461d5f5cf6b7baf177b5 \ - --hash=sha256:6831592fedf0a122016f5dab4b67d85fa3d4db3b21f588d18834b5c031396d1c \ - --hash=sha256:8045172ad3fcff62b9dab9a4cd2e0991ad0e27fc814fe625a8d3a120306651d6 \ - --hash=sha256:843c0108ad72bb7fc6c23a22e29e6099546a5eaad3ad675c78a146d9080f6ec6 \ - --hash=sha256:993194a8be70540e0f819862031bbf19a64401fbe6c31b42065fd313ba466d34 \ - --hash=sha256:a5a3c268d45060c50cd029979ecc5f1eaaec040b19fa88dd4fe9e927d19ff13e \ - --hash=sha256:b3f9e61b799fb3cc8fd7077a3d2eb676ddfef7db644f6b6a2b657c5c3214cf19 \ - --hash=sha256:b5bc29548abb0a0a7ae9e6ff3b0ccca2824edaf011a4336e15a32793d574fbfd \ - --hash=sha256:bbe492c780a39a64bd3d0766cad10d54cf12222df88d287ec2d8f2d52de37c79 \ - --hash=sha256:e3826aeb4e4399de0c6885bd8be7ce2f629fa0010f0013f1183e0726b3d25e40 \ - --hash=sha256:f59e3b2d1a1466ac0778f2c6fac9ccb5f30107d77e3dddd1d60167248d268474 - # via codeflare-sdk -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c - # via feast (setup.py) -referencing==0.37.0 \ - --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ - --hash=sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8 - # via - # jsonschema - # jsonschema-specifications - # jupyter-events -regex==2026.1.15 \ - --hash=sha256:0057de9eaef45783ff69fa94ae9f0fd906d629d0bd4c3217048f46d1daa32e9b \ - --hash=sha256:008b185f235acd1e53787333e5690082e4f156c44c87d894f880056089e9bc7c \ - --hash=sha256:05d75a668e9ea16f832390d22131fe1e8acc8389a694c8febc3e340b0f810b93 \ - --hash=sha256:069f56a7bf71d286a6ff932a9e6fb878f151c998ebb2519a9f6d1cee4bffdba3 \ - --hash=sha256:0751a26ad39d4f2ade8fe16c59b2bf5cb19eb3d2cd543e709e583d559bd9efde \ - --hash=sha256:08df9722d9b87834a3d701f3fca570b2be115654dbfd30179f30ab2f39d606d3 \ - --hash=sha256:0bda75ebcac38d884240914c6c43d8ab5fb82e74cde6da94b43b17c411aa4c2b \ - --hash=sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c \ - --hash=sha256:0bf650f26087363434c4e560011f8e4e738f6f3e029b85d4904c50135b86cfa5 \ - --hash=sha256:0dcd31594264029b57bf16f37fd7248a70b3b764ed9e0839a8f271b2d22c0785 \ - --hash=sha256:0f0c7684c7f9ca241344ff95a1de964f257a5251968484270e91c25a755532c5 \ - --hash=sha256:124dc36c85d34ef2d9164da41a53c1c8c122cfb1f6e1ec377a1f27ee81deb794 \ - --hash=sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5 \ - --hash=sha256:166551807ec20d47ceaeec380081f843e88c8949780cd42c40f18d16168bed10 \ - --hash=sha256:1704d204bd42b6bb80167df0e4554f35c255b579ba99616def38f69e14a5ccb9 \ - --hash=sha256:18388a62989c72ac24de75f1449d0fb0b04dfccd0a1a7c1c43af5eb503d890f6 \ - --hash=sha256:194312a14819d3e44628a44ed6fea6898fdbecb0550089d84c403475138d0a09 \ - --hash=sha256:1ae6020fb311f68d753b7efa9d4b9a5d47a5d6466ea0d5e3b5a471a960ea6e4a \ - --hash=sha256:1cb740d044aff31898804e7bf1181cc72c03d11dfd19932b9911ffc19a79070a \ - --hash=sha256:1e1808471fbe44c1a63e5f577a1d5f02fe5d66031dcbdf12f093ffc1305a858e \ - --hash=sha256:1e8cd52557603f5c66a548f69421310886b28b7066853089e1a71ee710e1cdc1 \ - --hash=sha256:21ca32c28c30d5d65fc9886ff576fc9b59bbca08933e844fa2363e530f4c8218 \ - --hash=sha256:2748c1ec0663580b4510bd89941a31560b4b439a0b428b49472a3d9944d11cd8 \ - --hash=sha256:27618391db7bdaf87ac6c92b31e8f0dfb83a9de0075855152b720140bda177a2 \ - --hash=sha256:2a8d7b50c34578d0d3bf7ad58cde9652b7d683691876f83aedc002862a35dc5e \ - --hash=sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410 \ - --hash=sha256:2c2b80399a422348ce5de4fe40c418d6299a0fa2803dd61dc0b1a2f28e280fcf \ - --hash=sha256:2f2775843ca49360508d080eaa87f94fa248e2c946bbcd963bb3aae14f333413 \ - --hash=sha256:3038a62fc7d6e5547b8915a3d927a0fbeef84cdbe0b1deb8c99bbd4a8961b52a \ - --hash=sha256:32655d17905e7ff8ba5c764c43cb124e34a9245e45b83c22e81041e1071aee10 \ - --hash=sha256:343db82cb3712c31ddf720f097ef17c11dab2f67f7a3e7be976c4f82eba4e6df \ - --hash=sha256:3601ffb5375de85a16f407854d11cca8fe3f5febbe3ac78fb2866bb220c74d10 \ - --hash=sha256:3d6ce5ae80066b319ae3bc62fd55a557c9491baa5efd0d355f0de08c4ba54e79 \ - --hash=sha256:3d7d92495f47567a9b1669c51fc8d6d809821849063d168121ef801bbc213846 \ - --hash=sha256:40c86d8046915bb9aeb15d3f3f15b6fd500b8ea4485b30e1bbc799dab3fe29f8 \ - --hash=sha256:4161d87f85fa831e31469bfd82c186923070fc970b9de75339b68f0c75b51903 \ - --hash=sha256:41aef6f953283291c4e4e6850607bd71502be67779586a61472beacb315c97ec \ - --hash=sha256:453078802f1b9e2b7303fb79222c054cb18e76f7bdc220f7530fdc85d319f99e \ - --hash=sha256:492534a0ab925d1db998defc3c302dae3616a2fc3fe2e08db1472348f096ddf2 \ - --hash=sha256:4c5ef43b5c2d4114eb8ea424bb8c9cec01d5d17f242af88b2448f5ee81caadbc \ - --hash=sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1 \ - --hash=sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a \ - --hash=sha256:4e3dd93c8f9abe8aa4b6c652016da9a3afa190df5ad822907efe6b206c09896e \ - --hash=sha256:505831646c945e3e63552cc1b1b9b514f0e93232972a2d5bedbcc32f15bc82e3 \ - --hash=sha256:5170907244b14303edc5978f522f16c974f32d3aa92109fabc2af52411c9433b \ - --hash=sha256:55b4ea996a8e4458dd7b584a2f89863b1655dd3d17b88b46cbb9becc495a0ec5 \ - --hash=sha256:55e9d0118d97794367309635df398bdfd7c33b93e2fdfa0b239661cd74b4c14e \ - --hash=sha256:56a5595d0f892f214609c9f76b41b7428bed439d98dc961efafdd1354d42baae \ - --hash=sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4 \ - --hash=sha256:5ef19071f4ac9f0834793af85bd04a920b4407715624e40cb7a0631a11137cdf \ - --hash=sha256:5ff818702440a5878a81886f127b80127f5d50563753a28211482867f8318106 \ - --hash=sha256:619843841e220adca114118533a574a9cd183ed8a28b85627d2844c500a2b0db \ - --hash=sha256:621f73a07595d83f28952d7bd1e91e9d1ed7625fb7af0064d3516674ec93a2a2 \ - --hash=sha256:693b465171707bbe882a7a05de5e866f33c76aa449750bee94a8d90463533cc9 \ - --hash=sha256:6bfc31a37fd1592f0c4fc4bfc674b5c42e52efe45b4b7a6a14f334cca4bcebe4 \ - --hash=sha256:6d220a2517f5893f55daac983bfa9fe998a7dbcaee4f5d27a88500f8b7873788 \ - --hash=sha256:6e42844ad64194fa08d5ccb75fe6a459b9b08e6d7296bd704460168d58a388f3 \ - --hash=sha256:726ea4e727aba21643205edad8f2187ec682d3305d790f73b7a51c7587b64bdd \ - --hash=sha256:74f45d170a21df41508cb67165456538425185baaf686281fa210d7e729abc34 \ - --hash=sha256:7dcc02368585334f5bc81fc73a2a6a0bbade60e7d83da21cead622faf408f32c \ - --hash=sha256:7e1e28be779884189cdd57735e997f282b64fd7ccf6e2eef3e16e57d7a34a815 \ - --hash=sha256:7ef7d5d4bd49ec7364315167a4134a015f61e8266c6d446fc116a9ac4456e10d \ - --hash=sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804 \ - --hash=sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913 \ - --hash=sha256:8355ad842a7c7e9e5e55653eade3b7d1885ba86f124dd8ab1f722f9be6627434 \ - --hash=sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb \ - --hash=sha256:87adf5bd6d72e3e17c9cb59ac4096b1faaf84b7eb3037a5ffa61c4b4370f0f13 \ - --hash=sha256:8db052bbd981e1666f09e957f3790ed74080c2229007c1dd67afdbf0b469c48b \ - --hash=sha256:8dd16fba2758db7a3780a051f245539c4451ca20910f5a5e6ea1c08d06d4a76b \ - --hash=sha256:8e32f7896f83774f91499d239e24cebfadbc07639c1494bb7213983842348337 \ - --hash=sha256:91c5036ebb62663a6b3999bdd2e559fd8456d17e2b485bf509784cd31a8b1705 \ - --hash=sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f \ - --hash=sha256:9479cae874c81bf610d72b85bb681a94c95722c127b55445285fb0e2c82db8e1 \ - --hash=sha256:968c14d4f03e10b2fd960f1d5168c1f0ac969381d3c1fcc973bc45fb06346599 \ - --hash=sha256:97499ff7862e868b1977107873dd1a06e151467129159a6ffd07b66706ba3a9f \ - --hash=sha256:99ad739c3686085e614bf77a508e26954ff1b8f14da0e3765ff7abbf7799f952 \ - --hash=sha256:9d787e3310c6a6425eb346be4ff2ccf6eece63017916fd77fe8328c57be83521 \ - --hash=sha256:a1774cd1981cd212506a23a14dba7fdeaee259f5deba2df6229966d9911e767a \ - --hash=sha256:a30a68e89e5a218b8b23a52292924c1f4b245cb0c68d1cce9aec9bbda6e2c160 \ - --hash=sha256:adc97a9077c2696501443d8ad3fa1b4fc6d131fc8fd7dfefd1a723f89071cf0a \ - --hash=sha256:b0d190e6f013ea938623a58706d1469a62103fb2a241ce2873a9906e0386582c \ - --hash=sha256:b10e42a6de0e32559a92f2f8dc908478cc0fa02838d7dbe764c44dca3fa13569 \ - --hash=sha256:b2a13dd6a95e95a489ca242319d18fc02e07ceb28fa9ad146385194d95b3c829 \ - --hash=sha256:b30bcbd1e1221783c721483953d9e4f3ab9c5d165aa709693d3f3946747b1aea \ - --hash=sha256:b325d4714c3c48277bfea1accd94e193ad6ed42b4bad79ad64f3b8f8a31260a5 \ - --hash=sha256:b5a28980a926fa810dbbed059547b02783952e2efd9c636412345232ddb87ff6 \ - --hash=sha256:b5f7d8d2867152cdb625e72a530d2ccb48a3d199159144cbdd63870882fb6f80 \ - --hash=sha256:bfb0d6be01fbae8d6655c8ca21b3b72458606c4aec9bbc932db758d47aba6db1 \ - --hash=sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681 \ - --hash=sha256:c08c1f3e34338256732bd6938747daa3c0d5b251e04b6e43b5813e94d503076e \ - --hash=sha256:c243da3436354f4af6c3058a3f81a97d47ea52c9bd874b52fd30274853a1d5df \ - --hash=sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5 \ - --hash=sha256:c661fc820cfb33e166bf2450d3dadbda47c8d8981898adb9b6fe24e5e582ba60 \ - --hash=sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d \ - --hash=sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056 \ - --hash=sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa \ - --hash=sha256:c9c08c2fbc6120e70abff5d7f28ffb4d969e14294fb2143b4b5c7d20e46d1714 \ - --hash=sha256:ca89c5e596fc05b015f27561b3793dc2fa0917ea0d7507eebb448efd35274a70 \ - --hash=sha256:cc7cd0b2be0f0269283a45c0d8b2c35e149d1319dcb4a43c9c3689fa935c1ee6 \ - --hash=sha256:cda1ed70d2b264952e88adaa52eea653a33a1b98ac907ae2f86508eb44f65cdc \ - --hash=sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22 \ - --hash=sha256:cfecdaa4b19f9ca534746eb3b55a5195d5c95b88cac32a205e981ec0a22b7d31 \ - --hash=sha256:d426616dae0967ca225ab12c22274eb816558f2f99ccb4a1d52ca92e8baf180f \ - --hash=sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3 \ - --hash=sha256:d639a750223132afbfb8f429c60d9d318aeba03281a5f1ab49f877456448dcf1 \ - --hash=sha256:d920392a6b1f353f4aa54328c867fec3320fa50657e25f64abf17af054fc97ac \ - --hash=sha256:d991483606f3dbec93287b9f35596f41aa2e92b7c2ebbb935b63f409e243c9af \ - --hash=sha256:d9ea2604370efc9a174c1b5dcc81784fb040044232150f7f33756049edfc9026 \ - --hash=sha256:dbaf3c3c37ef190439981648ccbf0c02ed99ae066087dd117fcb616d80b010a4 \ - --hash=sha256:dca3582bca82596609959ac39e12b7dad98385b4fefccb1151b937383cec547d \ - --hash=sha256:e3174a5ed4171570dc8318afada56373aa9289eb6dc0d96cceb48e7358b0e220 \ - --hash=sha256:e43a55f378df1e7a4fa3547c88d9a5a9b7113f653a66821bcea4718fe6c58763 \ - --hash=sha256:e69d0deeb977ffe7ed3d2e4439360089f9c3f217ada608f0f88ebd67afb6385e \ - --hash=sha256:e85dc94595f4d766bd7d872a9de5ede1ca8d3063f3bdf1e2c725f5eb411159e3 \ - --hash=sha256:e90b8db97f6f2c97eb045b51a6b2c5ed69cedd8392459e0642d4199b94fabd7e \ - --hash=sha256:e9bf3f0bbdb56633c07d7116ae60a576f846efdd86a8848f8d62b749e1209ca7 \ - --hash=sha256:ea4e6b3566127fda5e007e90a8fd5a4169f0cf0619506ed426db647f19c8454a \ - --hash=sha256:ec94c04149b6a7b8120f9f44565722c7ae31b7a6d2275569d2eefa76b83da3be \ - --hash=sha256:eddf73f41225942c1f994914742afa53dc0d01a6e20fe14b878a1b1edc74151f \ - --hash=sha256:ee6854c9000a10938c79238de2379bea30c82e4925a371711af45387df35cab8 \ - --hash=sha256:ef71d476caa6692eea743ae5ea23cde3260677f70122c4d258ca952e5c2d4e84 \ - --hash=sha256:f052d1be37ef35a54e394de66136e30fa1191fab64f71fc06ac7bc98c9a84618 \ - --hash=sha256:f1862739a1ffb50615c0fde6bae6569b5efbe08d98e59ce009f68a336f64da75 \ - --hash=sha256:f192a831d9575271a22d804ff1a5355355723f94f31d9eef25f0d45a152fdc1a \ - --hash=sha256:f42e68301ff4afee63e365a5fc302b81bb8ba31af625a671d7acb19d10168a8c \ - --hash=sha256:f7792f27d3ee6e0244ea4697d92b825f9a329ab5230a78c1a68bd274e64b5077 \ - --hash=sha256:f82110ab962a541737bd0ce87978d4c658f06e7591ba899192e2712a517badbb \ - --hash=sha256:f9ca1cbdc0fbfe5e6e6f8221ef2309988db5bcede52443aeaee9a4ad555e0dac \ - --hash=sha256:fd65af65e2aaf9474e468f9e571bd7b189e1df3a61caa59dcbabd0000e4ea839 \ - --hash=sha256:fe2fda4110a3d0bc163c2e0664be44657431440722c5c5315c65155cab92f9e5 \ - --hash=sha256:febd38857b09867d3ed3f4f1af7d241c5c50362e25ef43034995b77a50df494e - # via - # feast (setup.py) - # parsimonious - # transformers -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf - # via - # feast (setup.py) - # azure-core - # datasets - # docker - # docling - # fastapi-mcp - # google-api-core - # google-cloud-bigquery - # google-cloud-storage - # great-expectations - # huggingface-hub - # jupyterlab-server - # kubernetes - # moto - # msal - # python-keycloak - # ray - # requests-oauthlib - # requests-toolbelt - # responses - # singlestoredb - # snowflake-connector-python - # sphinx - # transformers - # trino -requests-oauthlib==2.0.0 \ - --hash=sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36 \ - --hash=sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9 - # via - # google-auth-oauthlib - # kubernetes -requests-toolbelt==1.0.0 \ - --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \ - --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 - # via python-keycloak -responses==0.25.8 \ - --hash=sha256:0c710af92def29c8352ceadff0c3fe340ace27cf5af1bbe46fb71275bcd2831c \ - --hash=sha256:9374d047a575c8f781b94454db5cab590b6029505f488d12899ddb10a4af1cf4 - # via moto -rfc3339-validator==0.1.4 \ - --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ - --hash=sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa - # via - # jsonschema - # jupyter-events -rfc3986-validator==0.1.1 \ - --hash=sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 \ - --hash=sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055 - # via - # jsonschema - # jupyter-events -rfc3987-syntax==1.1.0 \ - --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ - --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d - # via jsonschema -rich==13.9.4 \ - --hash=sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098 \ - --hash=sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90 - # via - # codeflare-sdk - # fastapi-mcp - # ibis-framework - # typer -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 - # via - # jsonschema - # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -rtree==1.4.1 \ - --hash=sha256:12de4578f1b3381a93a655846900be4e3d5f4cd5e306b8b00aa77c1121dc7e8c \ - --hash=sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0 \ - --hash=sha256:a7e48d805e12011c2cf739a29d6a60ae852fb1de9fc84220bbcef67e6e595d7d \ - --hash=sha256:b558edda52eca3e6d1ee629042192c65e6b7f2c150d6d6cd207ce82f85be3967 \ - --hash=sha256:c6b1b3550881e57ebe530cc6cffefc87cd9bf49c30b37b894065a9f810875e46 \ - --hash=sha256:d672184298527522d4914d8ae53bf76982b86ca420b0acde9298a7a87d81d4a4 \ - --hash=sha256:efa8c4496e31e9ad58ff6c7df89abceac7022d906cb64a3e18e4fceae6b77f65 \ - --hash=sha256:efe125f416fd27150197ab8521158662943a40f87acab8028a1aac4ad667a489 \ - --hash=sha256:f155bc8d6bac9dcd383481dee8c130947a4866db1d16cb6dff442329a038a0dc - # via - # docling - # docling-ibm-models -ruamel-yaml==0.17.17 \ - --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ - --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f - # via great-expectations -ruff==0.14.13 \ - --hash=sha256:4acdf009f32b46f6e8864af19cbf6841eaaed8638e65c8dac845aea0d703c841 \ - --hash=sha256:591a7f68860ea4e003917d19b5c4f5ac39ff558f162dc753a2c5de897fd5502c \ - --hash=sha256:6070bd026e409734b9257e03e3ef18c6e1a216f0435c6751d7a8ec69cb59abef \ - --hash=sha256:61f4e40077a1248436772bb6512db5fc4457fe4c49e7a94ea7c5088655dd21ae \ - --hash=sha256:642442b42957093811cd8d2140dfadd19c7417030a7a68cf8d51fcdd5f217427 \ - --hash=sha256:6d02f1428357fae9e98ac7aa94b7e966fd24151088510d32cf6f902d6c09235e \ - --hash=sha256:76f62c62cd37c276cb03a275b198c7c15bd1d60c989f944db08a8c1c2dbec18b \ - --hash=sha256:774c77e841cc6e046fc3e91623ce0903d1cd07e3a36b1a9fe79b81dab3de506b \ - --hash=sha256:78d2b1097750d90ba82ce4ba676e85230a0ed694178ca5e61aa9b459970b3eb9 \ - --hash=sha256:7ab819e14f1ad9fe39f246cfcc435880ef7a9390d81a2b6ac7e01039083dd247 \ - --hash=sha256:7d0bf87705acbbcb8d4c24b2d77fbb73d40210a95c3903b443cd9e30824a5032 \ - --hash=sha256:83cd6c0763190784b99650a20fec7633c59f6ebe41c5cc9d45ee42749563ad47 \ - --hash=sha256:914a8023ece0528d5cc33f5a684f5f38199bbb566a04815c2c211d8f40b5d0ed \ - --hash=sha256:9aaf3870f14d925bbaf18b8a2347ee0ae7d95a2e490e4d4aea6813ed15ebc80e \ - --hash=sha256:a3eb5da8e2c9e9f13431032fdcbe7681de9ceda5835efee3269417c13f1fed5c \ - --hash=sha256:ac5b7f63dd3b27cc811850f5ffd8fff845b00ad70e60b043aabf8d6ecc304e09 \ - --hash=sha256:d24899478c35ebfa730597a4a775d430ad0d5631b8647a3ab368c29b7e7bd063 \ - --hash=sha256:e399341472ce15237be0c0ae5fbceca4b04cd9bebab1a2b2c979e015455d8f0c \ - --hash=sha256:ef720f529aec113968b45dfdb838ac8934e519711da53a0456038a0efecbd680 - # via feast (setup.py) -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf - # via boto3 -safetensors[torch]==0.7.0 \ - --hash=sha256:0071bffba4150c2f46cae1432d31995d77acfd9f8db598b5d1a2ce67e8440ad2 \ - --hash=sha256:07663963b67e8bd9f0b8ad15bb9163606cd27cc5a1b96235a50d8369803b96b0 \ - --hash=sha256:12f49080303fa6bb424b362149a12949dfbbf1e06811a88f2307276b0c131afd \ - --hash=sha256:1d060c70284127fa805085d8f10fbd0962792aed71879d00864acda69dbab981 \ - --hash=sha256:42cb091236206bb2016d245c377ed383aa7f78691748f3bb6ee1bfa51ae2ce6a \ - --hash=sha256:473b32699f4200e69801bf5abf93f1a4ecd432a70984df164fc22ccf39c4a6f3 \ - --hash=sha256:54bef08bf00a2bff599982f6b08e8770e09cc012d7bba00783fc7ea38f1fb37d \ - --hash=sha256:5d72abdb8a4d56d4020713724ba81dac065fedb7f3667151c4a637f1d3fb26c0 \ - --hash=sha256:672132907fcad9f2aedcb705b2d7b3b93354a2aec1b2f706c4db852abe338f85 \ - --hash=sha256:6999421eb8ba9df4450a16d9184fcb7bef26240b9f98e95401f17af6c2210b71 \ - --hash=sha256:7b95a3fa7b3abb9b5b0e07668e808364d0d40f6bbbf9ae0faa8b5b210c97b140 \ - --hash=sha256:8469155f4cb518bafb4acf4865e8bb9d6804110d2d9bdcaa78564b9fd841e104 \ - --hash=sha256:94fd4858284736bb67a897a41608b5b0c2496c9bdb3bf2af1fa3409127f20d57 \ - --hash=sha256:b0f6d66c1c538d5a94a73aa9ddca8ccc4227e6c9ff555322ea40bdd142391dd4 \ - --hash=sha256:c74af94bf3ac15ac4d0f2a7c7b4663a15f8c2ab15ed0fc7531ca61d0835eccba \ - --hash=sha256:c82f4d474cf725255d9e6acf17252991c3c8aac038d6ef363a4bf8be2f6db517 \ - --hash=sha256:cdab83a366799fa730f90a4ebb563e494f28e9e92c4819e556152ad55e43591b \ - --hash=sha256:cfdead2f57330d76aa7234051dadfa7d4eedc0e5a27fd08e6f96714a92b00f09 \ - --hash=sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755 \ - --hash=sha256:dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48 \ - --hash=sha256:dc92bc2db7b45bda4510e4f51c59b00fe80b2d6be88928346e4294ce1c2abe7c \ - --hash=sha256:e07d91d0c92a31200f25351f4acb2bc6aff7f48094e13ebb1d0fb995b54b6542 \ - --hash=sha256:f4729811a6640d019a4b7ba8638ee2fd21fa5ca8c7e7bdf0fed62068fcaac737 - # via - # accelerate - # docling-ibm-models - # timm - # transformers -scikit-image==0.26.0 \ - --hash=sha256:0608aa4a9ec39e0843de10d60edb2785a30c1c47819b67866dd223ebd149acaf \ - --hash=sha256:0660b83968c15293fd9135e8d860053ee19500d52bf55ca4fb09de595a1af650 \ - --hash=sha256:09bad6a5d5949c7896c8347424c4cca899f1d11668030e5548813ab9c2865dcb \ - --hash=sha256:0baa0108d2d027f34d748e84e592b78acc23e965a5de0e4bb03cf371de5c0581 \ - --hash=sha256:163e9afb5b879562b9aeda0dd45208a35316f26cc7a3aed54fd601604e5cf46f \ - --hash=sha256:20ef4a155e2e78b8ab973998e04d8a361d49d719e65412405f4dadd9155a61d9 \ - --hash=sha256:21a818ee6ca2f2131b9e04d8eb7637b5c18773ebe7b399ad23dcc5afaa226d2d \ - --hash=sha256:27d58bc8b2acd351f972c6508c1b557cfed80299826080a4d803dd29c51b707e \ - --hash=sha256:2c1e7bd342f43e7a97e571b3f03ba4c1293ea1a35c3f13f41efdc8a81c1dc8f2 \ - --hash=sha256:3268f13310e6857508bd87202620df996199a016a1d281b309441d227c822394 \ - --hash=sha256:3409e89d66eff5734cd2b672d1c48d2759360057e714e1d92a11df82c87cba37 \ - --hash=sha256:3f5bf622d7c0435884e1e141ebbe4b2804e16b2dd23ae4c6183e2ea99233be70 \ - --hash=sha256:4c717490cec9e276afb0438dd165b7c3072d6c416709cc0f9f5a4c1070d23a44 \ - --hash=sha256:4d57e39ef67a95d26860c8caf9b14b8fb130f83b34c6656a77f191fa6d1d04d8 \ - --hash=sha256:52c496f75a7e45844d951557f13c08c81487c6a1da2e3c9c8a39fcde958e02cc \ - --hash=sha256:6381edf972b32e4f54085449afde64365a57316637496c1325a736987083e2ab \ - --hash=sha256:63af3d3a26125f796f01052052f86806da5b5e54c6abef152edb752683075a9c \ - --hash=sha256:6caec76e16c970c528d15d1c757363334d5cb3069f9cea93d2bead31820511f3 \ - --hash=sha256:724f79fd9b6cb6f4a37864fe09f81f9f5d5b9646b6868109e1b100d1a7019e59 \ - --hash=sha256:74aa5518ccea28121f57a95374581d3b979839adc25bb03f289b1bc9b99c58af \ - --hash=sha256:7af7aa331c6846bd03fa28b164c18d0c3fd419dbb888fb05e958ac4257a78fdd \ - --hash=sha256:7df650e79031634ac90b11e64a9eedaf5a5e06fcd09bcd03a34be01745744466 \ - --hash=sha256:915bb3ba66455cf8adac00dc8fdf18a4cd29656aec7ddd38cb4dda90289a6f21 \ - --hash=sha256:92242351bccf391fc5df2d1529d15470019496d2498d615beb68da85fe7fdf37 \ - --hash=sha256:9490360c8d3f9a7e85c8de87daf7c0c66507960cf4947bb9610d1751928721c7 \ - --hash=sha256:98329aab3bc87db352b9887f64ce8cdb8e75f7c2daa19927f2e121b797b678d5 \ - --hash=sha256:9ea6207d9e9d21c3f464efe733121c0504e494dbdc7728649ff3e23c3c5a4953 \ - --hash=sha256:9eefb4adad066da408a7601c4c24b07af3b472d90e08c3e7483d4e9e829d8c49 \ - --hash=sha256:a07200fe09b9d99fcdab959859fe0f7db8df6333d6204344425d476850ce3604 \ - --hash=sha256:a2d211bc355f59725efdcae699b93b30348a19416cc9e017f7b2fb599faf7219 \ - --hash=sha256:a2e852eccf41d2d322b8e60144e124802873a92b8d43a6f96331aa42888491c7 \ - --hash=sha256:abed017474593cd3056ae0fe948d07d0747b27a085e92df5474f4955dd65aec0 \ - --hash=sha256:ac529eb9dbd5954f9aaa2e3fe9a3fd9661bfe24e134c688587d811a0233127f1 \ - --hash=sha256:aeb14db1ed09ad4bee4ceb9e635547a8d5f3549be67fc6c768c7f923e027e6cd \ - --hash=sha256:b1ede33a0fb3731457eaf53af6361e73dd510f449dac437ab54573b26788baf0 \ - --hash=sha256:b36ab5e778bf50af5ff386c3ac508027dc3aaeccf2161bdf96bde6848f44d21b \ - --hash=sha256:b702c3bb115e1dcf4abf5297429b5c90f2189655888cbed14921f3d26f81d3a4 \ - --hash=sha256:b8d14d3181c21c11170477a42542c1addc7072a90b986675a71266ad17abc37f \ - --hash=sha256:c6624a76c6085218248154cc7e1500e6b488edcd9499004dd0d35040607d7505 \ - --hash=sha256:c9087cf7d0e7f33ab5c46d2068d86d785e70b05400a891f73a13400f1e1faf6a \ - --hash=sha256:cde0bbd57e6795eba83cb10f71a677f7239271121dc950bc060482834a668ad1 \ - --hash=sha256:ce00600cd70d4562ed59f80523e18cdcc1fae0e10676498a01f73c255774aefd \ - --hash=sha256:cefd85033e66d4ea35b525bb0937d7f42d4cdcfed2d1888e1570d5ce450d3932 \ - --hash=sha256:d454b93a6fa770ac5ae2d33570f8e7a321bb80d29511ce4b6b78058ebe176e8c \ - --hash=sha256:d5c244656de905e195a904e36dbc18585e06ecf67d90f0482cbde63d7f9ad59d \ - --hash=sha256:ede4d6d255cc5da9faeb2f9ba7fedbc990abbc652db429f40a16b22e770bb578 \ - --hash=sha256:f5f970ab04efad85c24714321fcc91613fcb64ef2a892a13167df2f3e59199fa \ - --hash=sha256:f775f0e420faac9c2aa6757135f4eb468fb7b70e0b67fa77a5e79be3c30ee331 \ - --hash=sha256:fac96a1f9b06cd771cbbb3cd96c5332f36d4efd839b1d8b053f79e5887acde62 - # via easyocr -scikit-learn==1.8.0 \ - --hash=sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2 \ - --hash=sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a \ - --hash=sha256:146b4d36f800c013d267b29168813f7a03a43ecd2895d04861f1240b564421da \ - --hash=sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9 \ - --hash=sha256:2838551e011a64e3053ad7618dda9310175f7515f1742fa2d756f7c874c05961 \ - --hash=sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6 \ - --hash=sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271 \ - --hash=sha256:35c007dedb2ffe38fe3ee7d201ebac4a2deccd2408e8621d53067733e3c74809 \ - --hash=sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242 \ - --hash=sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4 \ - --hash=sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7 \ - --hash=sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76 \ - --hash=sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6 \ - --hash=sha256:5e30adb87f0cc81c7690a84f7932dd66be5bac57cfe16b91cb9151683a4a2d3b \ - --hash=sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e \ - --hash=sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7 \ - --hash=sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e \ - --hash=sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57 \ - --hash=sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735 \ - --hash=sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb \ - --hash=sha256:8c497fff237d7b4e07e9ef1a640887fa4fb765647f86fbe00f969ff6280ce2bb \ - --hash=sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e \ - --hash=sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd \ - --hash=sha256:a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a \ - --hash=sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9 \ - --hash=sha256:ada8121bcb4dac28d930febc791a69f7cb1673c8495e5eee274190b73a4559c1 \ - --hash=sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde \ - --hash=sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3 \ - --hash=sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f \ - --hash=sha256:c57b1b610bd1f40ba43970e11ce62821c2e6569e4d74023db19c6b26f246cb3b \ - --hash=sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3 \ - --hash=sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e \ - --hash=sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702 \ - --hash=sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c \ - --hash=sha256:f984ca4b14914e6b4094c5d52a32ea16b49832c03bd17a110f004db3c223e8e1 \ - --hash=sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4 \ - --hash=sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd - # via feast (setup.py) -scipy==1.17.0 \ - --hash=sha256:00fb5f8ec8398ad90215008d8b6009c9db9fa924fd4c7d6be307c6f945f9cd73 \ - --hash=sha256:031121914e295d9791319a1875444d55079885bbae5bdc9c5e0f2ee5f09d34ff \ - --hash=sha256:0937a0b0d8d593a198cededd4c439a0ea216a3f36653901ea1f3e4be949056f8 \ - --hash=sha256:0cf46c8013fec9d3694dc572f0b54100c28405d55d3e2cb15e2895b25057996e \ - --hash=sha256:0d5018a57c24cb1dd828bcf51d7b10e65986d549f52ef5adb6b4d1ded3e32a57 \ - --hash=sha256:130d12926ae34399d157de777472bf82e9061c60cc081372b3118edacafe1d00 \ - --hash=sha256:13c4096ac6bc31d706018f06a49abe0485f96499deb82066b94d19b02f664209 \ - --hash=sha256:13e861634a2c480bd237deb69333ac79ea1941b94568d4b0efa5db5e263d4fd1 \ - --hash=sha256:1f9586a58039d7229ce77b52f8472c972448cded5736eaf102d5658bbac4c269 \ - --hash=sha256:1ff269abf702f6c7e67a4b7aad981d42871a11b9dd83c58d2d2ea624efbd1088 \ - --hash=sha256:255c0da161bd7b32a6c898e7891509e8a9289f0b1c6c7d96142ee0d2b114c2ea \ - --hash=sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e \ - --hash=sha256:272a9f16d6bb4667e8b50d25d71eddcc2158a214df1b566319298de0939d2ab7 \ - --hash=sha256:2abd71643797bd8a106dff97894ff7869eeeb0af0f7a5ce02e4227c6a2e9d6fd \ - --hash=sha256:2b531f57e09c946f56ad0b4a3b2abee778789097871fc541e267d2eca081cff1 \ - --hash=sha256:30509da9dbec1c2ed8f168b8d8aa853bc6723fede1dbc23c7d43a56f5ab72a67 \ - --hash=sha256:33af70d040e8af9d5e7a38b5ed3b772adddd281e3062ff23fec49e49681c38cf \ - --hash=sha256:357ca001c6e37601066092e7c89cca2f1ce74e2a520ca78d063a6d2201101df2 \ - --hash=sha256:3625c631a7acd7cfd929e4e31d2582cf00f42fcf06011f59281271746d77e061 \ - --hash=sha256:363ad4ae2853d88ebcde3ae6ec46ccca903ea9835ee8ba543f12f575e7b07e4e \ - --hash=sha256:40052543f7bbe921df4408f46003d6f01c6af109b9e2c8a66dd1cf6cf57f7d5d \ - --hash=sha256:423ca1f6584fc03936972b5f7c06961670dbba9f234e71676a7c7ccf938a0d61 \ - --hash=sha256:474da16199f6af66601a01546144922ce402cb17362e07d82f5a6cf8f963e449 \ - --hash=sha256:4e00562e519c09da34c31685f6acc3aa384d4d50604db0f245c14e1b4488bfa2 \ - --hash=sha256:5194c445d0a1c7a6c1a4a4681b6b7c71baad98ff66d96b949097e7513c9d6742 \ - --hash=sha256:5fb10d17e649e1446410895639f3385fd2bf4c3c7dfc9bea937bddcbc3d7b9ba \ - --hash=sha256:65ec32f3d32dfc48c72df4291345dae4f048749bc8d5203ee0a3f347f96c5ce6 \ - --hash=sha256:6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 \ - --hash=sha256:6e886000eb4919eae3a44f035e63f0fd8b651234117e8f6f29bad1cd26e7bc45 \ - --hash=sha256:7204fddcbec2fe6598f1c5fdf027e9f259106d05202a959a9f1aecf036adc9f6 \ - --hash=sha256:819fc26862b4b3c73a60d486dbb919202f3d6d98c87cf20c223511429f2d1a97 \ - --hash=sha256:8547e7c57f932e7354a2319fab613981cde910631979f74c9b542bb167a8b9db \ - --hash=sha256:85b0ac3ad17fa3be50abd7e69d583d98792d7edc08367e01445a1e2076005379 \ - --hash=sha256:87b411e42b425b84777718cc41516b8a7e0795abfa8e8e1d573bf0ef014f0812 \ - --hash=sha256:88c22af9e5d5a4f9e027e26772cc7b5922fab8bcc839edb3ae33de404feebd9e \ - --hash=sha256:9244608d27eafe02b20558523ba57f15c689357c85bdcfe920b1828750aa26eb \ - --hash=sha256:979c3a0ff8e5ba254d45d59ebd38cde48fce4f10b5125c680c7a4bfe177aab07 \ - --hash=sha256:9eeb9b5f5997f75507814ed9d298ab23f62cf79f5a3ef90031b1ee2506abdb5b \ - --hash=sha256:9fad7d3578c877d606b1150135c2639e9de9cecd3705caa37b66862977cc3e72 \ - --hash=sha256:a38c3337e00be6fd8a95b4ed66b5d988bac4ec888fd922c2ea9fe5fb1603dd67 \ - --hash=sha256:aabf057c632798832f071a8dde013c2e26284043934f53b00489f1773b33527e \ - --hash=sha256:c17514d11b78be8f7e6331b983a65a7f5ca1fd037b95e27b280921fe5606286a \ - --hash=sha256:c5e8647f60679790c2f5c76be17e2e9247dc6b98ad0d3b065861e082c56e078d \ - --hash=sha256:cacbaddd91fcffde703934897c5cd2c7cb0371fac195d383f4e1f1c5d3f3bd04 \ - --hash=sha256:d7425fcafbc09a03731e1bc05581f5fad988e48c6a861f441b7ab729a49a55ea \ - --hash=sha256:dac97a27520d66c12a34fd90a4fe65f43766c18c0d6e1c0a80f114d2260080e4 \ - --hash=sha256:dbf133ced83889583156566d2bdf7a07ff89228fe0c0cb727f777de92092ec6b \ - --hash=sha256:e8c0b331c2c1f531eb51f1b4fc9ba709521a712cce58f1aa627bc007421a5306 \ - --hash=sha256:eb2651271135154aa24f6481cbae5cc8af1f0dd46e6533fb7b56aa9727b6a232 \ - --hash=sha256:ebb7446a39b3ae0fe8f416a9a3fdc6fba3f11c634f680f16a239c5187bc487c0 \ - --hash=sha256:ec0827aa4d36cb79ff1b81de898e948a51ac0b9b1c43e4a372c0508c38c0f9a3 \ - --hash=sha256:edce1a1cf66298cccdc48a1bdf8fb10a3bf58e8b58d6c3883dd1530e103f87c0 \ - --hash=sha256:eec3842ec9ac9de5917899b277428886042a93db0b227ebbe3a333b64ec7643d \ - --hash=sha256:ef28d815f4d2686503e5f4f00edc387ae58dfd7a2f42e348bb53359538f01558 \ - --hash=sha256:f2a4942b0f5f7c23c7cd641a0ca1955e2ae83dedcff537e3a0259096635e186b \ - --hash=sha256:f3cd947f20fe17013d401b64e857c6b2da83cae567adbb75b9dcba865abc66d8 \ - --hash=sha256:f603d8a5518c7426414d1d8f82e253e454471de682ce5e39c29adb0df1efb86b \ - --hash=sha256:f7df7941d71314e60a481e02d5ebcb3f0185b8d799c70d03d8258f6c80f3d467 \ - --hash=sha256:f9eb55bb97d00f8b7ab95cb64f873eb0bf54d9446264d9f3609130381233483f \ - --hash=sha256:fc02c37a5639ee67d8fb646ffded6d793c06c5622d36b35cfa8fe5ececb8f042 \ - --hash=sha256:fe508b5690e9eaaa9467fc047f833af58f1152ae51a0d0aed67aa5801f4dd7d6 - # via - # docling - # easyocr - # great-expectations - # scikit-image - # scikit-learn -semchunk==2.2.2 \ - --hash=sha256:940e89896e64eeb01de97ba60f51c8c7b96c6a3951dfcf574f25ce2146752f52 \ - --hash=sha256:94ca19020c013c073abdfd06d79a7c13637b91738335f3b8cdb5655ee7cc94d2 - # via docling-core -send2trash==2.1.0 \ - --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ - --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 - # via jupyter-server -setuptools==80.9.0 \ - --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ - --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c - # via - # feast (setup.py) - # grpcio-tools - # jupyterlab - # pandas-gbq - # pbr - # pip-tools - # pydata-google-auth - # pymilvus - # singlestoredb -shapely==2.1.2 \ - --hash=sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9 \ - --hash=sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b \ - --hash=sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3 \ - --hash=sha256:136ab87b17e733e22f0961504d05e77e7be8c9b5a8184f685b4a91a84efe3c26 \ - --hash=sha256:16a9c722ba774cf50b5d4541242b4cce05aafd44a015290c82ba8a16931ff63d \ - --hash=sha256:16c5d0fc45d3aa0a69074979f4f1928ca2734fb2e0dde8af9611e134e46774e7 \ - --hash=sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0 \ - --hash=sha256:1d0bfb4b8f661b3b4ec3565fa36c340bfb1cda82087199711f86a88647d26b2f \ - --hash=sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b \ - --hash=sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4 \ - --hash=sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c \ - --hash=sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf \ - --hash=sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40 \ - --hash=sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9 \ - --hash=sha256:2fa78b49485391224755a856ed3b3bd91c8455f6121fee0db0e71cefb07d0ef6 \ - --hash=sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c \ - --hash=sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0 \ - --hash=sha256:40d784101f5d06a1fd30b55fc11ea58a61be23f930d934d86f19a180909908a4 \ - --hash=sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c \ - --hash=sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076 \ - --hash=sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a \ - --hash=sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566 \ - --hash=sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99 \ - --hash=sha256:6ddc759f72b5b2b0f54a7e7cde44acef680a55019eb52ac63a7af2cf17cb9cd2 \ - --hash=sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179 \ - --hash=sha256:7ae48c236c0324b4e139bea88a306a04ca630f49be66741b340729d380d8f52f \ - --hash=sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6 \ - --hash=sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a \ - --hash=sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801 \ - --hash=sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454 \ - --hash=sha256:91121757b0a36c9aac3427a651a7e6567110a4a67c97edf04f8d55d4765f6618 \ - --hash=sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d \ - --hash=sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223 \ - --hash=sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350 \ - --hash=sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0 \ - --hash=sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c \ - --hash=sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af \ - --hash=sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8 \ - --hash=sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735 \ - --hash=sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1 \ - --hash=sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359 \ - --hash=sha256:c64d5c97b2f47e3cd9b712eaced3b061f2b71234b3fc263e0fcf7d889c6559dc \ - --hash=sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf \ - --hash=sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715 \ - --hash=sha256:cc4f7397459b12c0b196c9efe1f9d7e92463cbba142632b4cc6d8bbbbd3e2b09 \ - --hash=sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc \ - --hash=sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd \ - --hash=sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26 \ - --hash=sha256:e38a190442aacc67ff9f75ce60aec04893041f16f97d242209106d502486a142 \ - --hash=sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc \ - --hash=sha256:eba6710407f1daa8e7602c347dfc94adc02205ec27ed956346190d66579eb9ea \ - --hash=sha256:ef4a456cc8b7b3d50ccec29642aa4aeda959e9da2fe9540a92754770d5f0cf1f \ - --hash=sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df \ - --hash=sha256:f6f6cd5819c50d9bcf921882784586aab34a4bd53e7553e175dece6db513a6f0 \ - --hash=sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94 \ - --hash=sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e \ - --hash=sha256:fe9627c39c59e553c90f5bc3128252cb85dc3b3be8189710666d2f8bc3a5503e - # via easyocr -shellingham==1.5.4 \ - --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ - --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de - # via typer -singlestoredb==1.7.2 \ - --hash=sha256:2c5379ae7730b54a5b18f93a3c998bd22394d727837edc76a9cbb2b0eba3b567 \ - --hash=sha256:346ed52cb4280d44472d9f80197c90d220cd5d92ae687423beea89e4b291a701 \ - --hash=sha256:5bebdd48dc40dd670d0ae21f68bab4a14eb69aeabd357f177f5fc88821a4f0a1 \ - --hash=sha256:69c07490e0cd22fcfd823e493b630cfe845ad4c484fee80b340bfcce3427f48a \ - --hash=sha256:92bc932df8b124a3c88b552210f9e0bb11cba4bdfbc9e7568c1582c00f0e8bcb \ - --hash=sha256:c2a23b2b22f1e76cb0d53c99250de9a600bec9621766e25ae379c50914d6436a \ - --hash=sha256:fba7f30f7fddb88e656e4309157d9e0016b6b1127d5adf348ba831bf77872d07 - # via feast (setup.py) -six==1.17.0 \ - --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ - --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 - # via - # happybase - # kubernetes - # mock - # opencensus - # openshift-client - # python-dateutil - # rfc3339-validator - # thriftpy2 -smart-open==7.5.0 \ - --hash=sha256:87e695c5148bbb988f15cec00971602765874163be85acb1c9fb8abc012e6599 \ - --hash=sha256:f394b143851d8091011832ac8113ea4aba6b92e6c35f6e677ddaaccb169d7cb9 - # via ray -sniffio==1.3.1 \ - --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ - --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc - # via - # elastic-transport - # elasticsearch - # httpx -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 - # via sphinx -snowflake-connector-python[pandas]==3.18.0 \ - --hash=sha256:0af10b207af3d2de2b130e89018d49a60f2e5cfe841f3bf459e58f2e1c4c4506 \ - --hash=sha256:1841b60dc376639493dfc520cf39ad4f4da1f30286bba57e878d57414263d628 \ - --hash=sha256:1afbd9e21180d2b4a76500ac2978b11865fdb3230609f2a9d80ba459fc27f2e4 \ - --hash=sha256:1fb9fc9d8c2c7d209ba89282d367a32e75b0688afd4a3f02409e24f153c1a32e \ - --hash=sha256:283366b35df88cd0c71caf0215ba80370ddef4dd37d2adf43b24208c747231ee \ - --hash=sha256:2e4c285cc6a7f6431cff98c8f235a0fe9da2262462dd3dfc2b97120574a95cf9 \ - --hash=sha256:32b1abfea32561d817b0a2f80b06d936cb32712af06bf7b848a428bfd857a10a \ - --hash=sha256:3fee7035f865088f948510b094101c8a0e5b22501891f2115f7fb1cb555de76a \ - --hash=sha256:41a46eb9824574c5f8068e3ed5c02a2dc0a733ed08ee81fa1fb3dd0ebe921728 \ - --hash=sha256:4c068c8d3cd0c9736cb0679a9f544d34327e64415303bbfe07ec8ce3c5dae800 \ - --hash=sha256:4ed2d593f1983939d5d8d88b212d86fd4f14f0ceefc1df9882b4a18534adbde9 \ - --hash=sha256:51eb789a09dc6c62119cfabd044fba1a6b8378206f05a1e83ddb2e9cb49acc0b \ - --hash=sha256:5d89f608fde2fb0597ca5e020c4ac602027dc67f11b61b4d1e5448163bae4edc \ - --hash=sha256:65d37263dd288abb649820b7e34af96dc6b2d2115bf5521a2526245f81ddb0cb \ - --hash=sha256:7116cfa410d517328fd25fabffb54845b88667586718578c4333ce034fead1ba \ - --hash=sha256:783a9ab206563d7b52fdcdd7a72af62de811d3381ca64132fd3445537b4d041b \ - --hash=sha256:7a5fcb9a25a9b77b6cd86dfc6a6324b9910e15a493a916983229011ce3509b5f \ - --hash=sha256:8d3e96e1d09b07edca6c1f6ca675b6fdd05a4a7e428e4cdf6fb697d87b9f60fc \ - --hash=sha256:94e041e347b5151b66d19d6cfc3b3172dac1f51e44bbf7cf58f3989427dd464a \ - --hash=sha256:a8c570edff5a4888840dbe1e9e65c5e4d77d55c5c800cd359fe0903a769201e0 \ - --hash=sha256:aeeb181a156333480f60b5f8ddbb3d087e288b4509adbef7993236defe4d7570 \ - --hash=sha256:b211b4240596a225b895261a4ced2633e0262e82e2e32f6fb8dfc7d4bfedf8ca \ - --hash=sha256:b99f261c82be92224ac20c8c12bdf26ce3ed5dfd8a3df8a97f15a1e11c46ad27 \ - --hash=sha256:bd1de3038b6d7059ca59f93e105aba2a673151c693cc4292f72f38bfaf147df2 \ - --hash=sha256:cfa6b234f53ec624149e21156d0a98e43408d194f2e65bcfaf30acefd35a581e \ - --hash=sha256:e17a9e806823d3a0e578cf9349f6a93810a582b3132903ea9e1683854d08da00 - # via feast (setup.py) -sortedcontainers==2.4.0 \ - --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ - --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via snowflake-connector-python -soupsieve==2.8.3 \ - --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ - --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 - # via beautifulsoup4 -sphinx==6.2.1 \ - --hash=sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b \ - --hash=sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912 - # via feast (setup.py) -sphinxcontrib-applehelp==2.0.0 \ - --hash=sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1 \ - --hash=sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 - # via sphinx -sphinxcontrib-devhelp==2.0.0 \ - --hash=sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad \ - --hash=sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 - # via sphinx -sphinxcontrib-htmlhelp==2.1.0 \ - --hash=sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 \ - --hash=sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9 - # via sphinx -sphinxcontrib-jsmath==1.0.1 \ - --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ - --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 - # via sphinx -sphinxcontrib-qthelp==2.0.0 \ - --hash=sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab \ - --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb - # via sphinx -sphinxcontrib-serializinghtml==2.0.0 \ - --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ - --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d - # via sphinx -sqlalchemy[mypy]==2.0.45 \ - --hash=sha256:0209d9753671b0da74da2cfbb9ecf9c02f72a759e4b018b3ab35f244c91842c7 \ - --hash=sha256:040f6f0545b3b7da6b9317fc3e922c9a98fc7243b2a1b39f78390fc0942f7826 \ - --hash=sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953 \ - --hash=sha256:0f02325709d1b1a1489f23a39b318e175a171497374149eae74d612634b234c0 \ - --hash=sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6 \ - --hash=sha256:12c694ed6468333a090d2f60950e4250b928f457e4962389553d6ba5fe9951ac \ - --hash=sha256:13e27397a7810163440c6bfed6b3fe46f1bfb2486eb540315a819abd2c004128 \ - --hash=sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88 \ - --hash=sha256:1d8b4a7a8c9b537509d56d5cd10ecdcfbb95912d72480c8861524efecc6a3fff \ - --hash=sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4 \ - --hash=sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33 \ - --hash=sha256:2e90a344c644a4fa871eb01809c32096487928bd2038bf10f3e4515cb688cc56 \ - --hash=sha256:3c5f76216e7b85770d5bb5130ddd11ee89f4d52b11783674a662c7dd57018177 \ - --hash=sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b \ - --hash=sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177 \ - --hash=sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a \ - --hash=sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0 \ - --hash=sha256:56ead1f8dfb91a54a28cd1d072c74b3d635bcffbd25e50786533b822d4f2cde2 \ - --hash=sha256:5964f832431b7cdfaaa22a660b4c7eb1dfcd6ed41375f67fd3e3440fd95cb3cc \ - --hash=sha256:59a8b8bd9c6bedf81ad07c8bd5543eedca55fe9b8780b2b628d495ba55f8db1e \ - --hash=sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e \ - --hash=sha256:6d0beadc2535157070c9c17ecf25ecec31e13c229a8f69196d7590bde8082bf1 \ - --hash=sha256:7ae64ebf7657395824a19bca98ab10eb9a3ecb026bf09524014f1bb81cb598d4 \ - --hash=sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774 \ - --hash=sha256:830d434d609fe7bfa47c425c445a8b37929f140a7a44cdaf77f6d34df3a7296a \ - --hash=sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6 \ - --hash=sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce \ - --hash=sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74 \ - --hash=sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1 \ - --hash=sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b \ - --hash=sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8 \ - --hash=sha256:a15b98adb7f277316f2c276c090259129ee4afca783495e212048daf846654b2 \ - --hash=sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee \ - --hash=sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f \ - --hash=sha256:b8c8b41b97fba5f62349aa285654230296829672fc9939cd7f35aab246d1c08b \ - --hash=sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d \ - --hash=sha256:c1c2091b1489435ff85728fafeb990f073e64f6f5e81d5cd53059773e8521eb6 \ - --hash=sha256:c64772786d9eee72d4d3784c28f0a636af5b0a29f3fe26ff11f55efe90c0bd85 \ - --hash=sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b \ - --hash=sha256:d29b2b99d527dbc66dd87c3c3248a5dd789d974a507f4653c969999fc7c1191b \ - --hash=sha256:d2c3684fca8a05f0ac1d9a21c1f4a266983a7ea9180efb80ffeb03861ecd01a0 \ - --hash=sha256:d62e47f5d8a50099b17e2bfc1b0c7d7ecd8ba6b46b1507b58cc4f05eefc3bb1c \ - --hash=sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a \ - --hash=sha256:db6834900338fb13a9123307f0c2cbb1f890a8656fcd5e5448ae3ad5bbe8d312 \ - --hash=sha256:e057f928ffe9c9b246a55b469c133b98a426297e1772ad24ce9f0c47d123bd5b \ - --hash=sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f \ - --hash=sha256:ebd300afd2b62679203435f596b2601adafe546cb7282d5a0cd3ed99e423720f \ - --hash=sha256:ed3635353e55d28e7f4a95c8eda98a5cdc0a0b40b528433fbd41a9ae88f55b3d \ - --hash=sha256:ee580ab50e748208754ae8980cec79ec205983d8cf8b3f7c39067f3d9f2c8e22 \ - --hash=sha256:f7d27a1d977a1cfef38a0e2e1ca86f09c4212666ce34e6ae542f3ed0a33bc606 \ - --hash=sha256:fd93c6f5d65f254ceabe97548c709e073d6da9883343adaa51bf1a913ce93f8e \ - --hash=sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf - # via feast (setup.py) -sqlglot[rs]==25.20.2 \ - --hash=sha256:169fe8308dd70d7bd40117b2221b62bdc7c4e2ea8eb07394b2a6146cdedf05ab \ - --hash=sha256:cdbfd7ce3f2f39f32bd7b4c23fd9e0fd261636a6b14285b914e8def25fd0a567 - # via - # feast (setup.py) - # ibis-framework -sqlglotrs==0.2.12 \ - --hash=sha256:0338c7770a5cb5bb0ec1dcbe5206359fe9b83da0aba8dde53b9e7bd1afc89a22 \ - --hash=sha256:057a8db59a6c4bcdc42831e7ad01f41cf9e7f388ed5b139816adafbcacf2f591 \ - --hash=sha256:065835e7f2be50ba83895b64d044a39dab9d95098fff995427365e4bd8bc7bc6 \ - --hash=sha256:08e8be22da77c964be76ab4438da2c77096f5871088466ca950ee1b4712a97d4 \ - --hash=sha256:147cda8412f45af290ad190d9a98b5829a5f46a575ce768279ccebf9b7b53785 \ - --hash=sha256:155b0d59e34851b119c7ff0b2c7968c7b51667c1a1c2abefe1ac7244b3c1d78e \ - --hash=sha256:17b289ef0f25a7c034d183c588345e2b56622f7f64a85d1020633a75f8e3ac96 \ - --hash=sha256:1fc98b7649445e726a492841b8b8b39a4e5724ec2787cd1436404ebccf42519a \ - --hash=sha256:2554ead3126c83864a4b7e48e8e7e1bc23faf7160a6f28d3db967661cf529c9e \ - --hash=sha256:2824fc87fd7e41a785150ff042c7934e1fff97c6ccd59e4d96bebf6697a90762 \ - --hash=sha256:2db7e6cd41ef88c2ac647ad0258f87906de822955dec8f14e91829083047d784 \ - --hash=sha256:315f7f7bbfedf0c87d98068e62363454e986bdd05baa165b7fb448b5c6fe9f1a \ - --hash=sha256:327bfc2d71449f4dffba93d63f0565c4a1fa818143b1cfbc3f936fa8c9bcce10 \ - --hash=sha256:39a6ef72cf271db93ec6019847b7832defa9f4013c1e66851ca9c0a11c010c0c \ - --hash=sha256:4364116b7b0c72b841de6acd149a002bfc8fe360125989d4f39debd387c874d8 \ - --hash=sha256:4c07d3dba9c3ae8b56a0e45a9e47aa2a2c6ed95870c5bcc67dacaadb873843ff \ - --hash=sha256:4ceb28cf2ee3850cd745167cebe59a5fc3d506b32e9c81307938d8d272c1d670 \ - --hash=sha256:4ec38035523d54ba33de1e2b5562de4938254b61e1df48eb1db0e26ea189de28 \ - --hash=sha256:5026eada48f258ce9ad26fa41994b2ea5404bef2c3df9cb5cb2a159112a6269f \ - --hash=sha256:59499adc27a70a72170db9241404a18d4829cd3a83a076b9e112ad365c4b1452 \ - --hash=sha256:5be231acf95920bed473524dd1cac93e4cb320ed7e6ae937531b232c54cfc232 \ - --hash=sha256:67e288759d2be822db2175d0025c1f61283b019f2cc3e2577f31ad0ef3b5854d \ - --hash=sha256:6aacab6e20d92be3ca76f7358fa12346f29985e2d408660c764b7f1c75cc40ee \ - --hash=sha256:6ef3a827f2980aad17af4f8548297c93c4989d4cd3f64b9bcb7443952c542423 \ - --hash=sha256:732516bffffc70f172306ad8bc747dd9f16512cdbc09475abe6ad6f744479dee \ - --hash=sha256:76e4e1765c6be438329e234e56a6772537f6de16c4bb5ba7170e344664cccdf7 \ - --hash=sha256:7b553cdb9e8afcfea5466815e865f874f6f51aaace4fb4101670e150f7bbfe5a \ - --hash=sha256:7c79c43c5cde1f4017641032f11770ed8111c963dccc096cd15df906d4fb46a4 \ - --hash=sha256:8174aa227193d0a755f4515e6c3883be4681c9b669a65c2316f09be27b84be4d \ - --hash=sha256:8a18b3a09c32788d1ee2d0610ab35af862413c56b65f8ad8bc0131701f03103b \ - --hash=sha256:8f268aea3d2ebc05cb9148bb487f21e532f8af1b0a4aed6b7374703aadfb6a7c \ - --hash=sha256:91971032603d05428fd42a978084110afb2a4c0975e4343b075f69a23889e3da \ - --hash=sha256:9334f6c394a671a630c61339d52fb7da1a72eca057570f039b2a4035d2e39380 \ - --hash=sha256:954ccd912391ab5922adb23159ebcc0c5dccb468381e2a1ce92117cb4b0f0ed3 \ - --hash=sha256:9597865efc40e5c41af7719106c7620e1338aaa64646726652c63bae14225391 \ - --hash=sha256:97b2c74fcdd89f0d4458c0e2b5783989be99a1e0b2d627797688ab716ad9391b \ - --hash=sha256:989ccc5dc6b38da937481b6eb2dc1fc0b13676fe129697b874828e577984d7ef \ - --hash=sha256:9c4c6f6fe1c54fff614f9d0b2dd7a6bf948bda87ce51a245dcd3f447f20c8b74 \ - --hash=sha256:9d5b9a9d6259b72258f6764f88a89faa3c648438bd1b2c3a9598b725d42bf6f2 \ - --hash=sha256:a266c9047726d83c51a8ec3d5278ceb9caf131307c9c93c4ceefd99c0116e538 \ - --hash=sha256:a4a2cacb31f75e242c7b9ff4afae1d95f548df8441444114376d8007cc91b55b \ - --hash=sha256:aaf86275a3388da1ed2161645aa346bfca3ee6e1dc0e2115867db9e78f1caddd \ - --hash=sha256:ab676d2d7da28907a139ad5fc20dee0890054967bac0b18e653ac048837c9ea1 \ - --hash=sha256:acc25d651eb663332157c2e5d2736516cddf4cd0effe67a887723934de5051d1 \ - --hash=sha256:b10bf6b71961b31951bf4dff937d8d5d399ea1b3bd47fb5c5810386710fe7dfb \ - --hash=sha256:b40601e67f5abae5d09d23f92394dbd735539de469ce663b596eb42bf77d2c54 \ - --hash=sha256:b6020825e58af6e2795e6dcb69639f5500e45e1da78f1b1abd74c4d11083a249 \ - --hash=sha256:bc1807c6222e32fc9bf6f5c7e12b85c4b72f12227800d40c1693244c198b33bb \ - --hash=sha256:bd6c4e6a7670f761c8e69b45d6d302a4d37a3cddb1fdca2ad90e54b77858fe80 \ - --hash=sha256:bf3e2eab11f06f1df13c0f85b3e26fbab0b7e8a5d189e5edfed951bc85f6bd48 \ - --hash=sha256:c3d62905ce74a48714b7662ad95efe299fad62f193be4b482a327af060f98710 \ - --hash=sha256:c3e0edde0fdf598561e7404ac56fb4b12276394ee5155b5365e42434c6f287a3 \ - --hash=sha256:c64066d13bd2e5e788b845c933c765af9991faa93982e273b623019a1161fadc \ - --hash=sha256:c8bf7ae29c0fc66e9c998d7f8e6f6fc26309c6eb5a4728e1443cb628218bc307 \ - --hash=sha256:d2827c7bf7e57496f9b95658bcd2395cfb0c51adc3023cd3386988337dfaf6a5 \ - --hash=sha256:e7b2da43b2a6a85807df6c56b2627abe244aff28fdf9a4940d38d749cb4b8e3e \ - --hash=sha256:ebc162a599fac86e59f899631716752fbc7f89598e94729eadb707e54db371b2 \ - --hash=sha256:f0a2ddeab27a94447270b7a240770a31a3afed0a972d60085205baec990ad76a \ - --hash=sha256:f104a98182761d4613f920eda7ec5fc921afb3608f7db648206ce06dd10a6be5 \ - --hash=sha256:f83ad3fb4ea57218c0e65d3499e31c9bb3051bbb5dccbb11593eaf1640964b51 \ - --hash=sha256:fa1ae834fb78bd52bb76e3c8d02cb79f45717ab1f02f4ad8154bf33a5408a502 - # via sqlglot -sqlite-vec==0.1.6 \ - --hash=sha256:77491bcaa6d496f2acb5cc0d0ff0b8964434f141523c121e313f9a7d8088dee3 \ - --hash=sha256:7b0519d9cd96164cd2e08e8eed225197f9cd2f0be82cb04567692a0a4be02da3 \ - --hash=sha256:823b0493add80d7fe82ab0fe25df7c0703f4752941aee1c7b2b02cec9656cb24 \ - --hash=sha256:c65bcfd90fa2f41f9000052bcb8bb75d38240b2dae49225389eca6c3136d3f0c \ - --hash=sha256:fdca35f7ee3243668a055255d4dee4dea7eed5a06da8cad409f89facf4595361 - # via feast (setup.py) -sqlparams==6.2.0 \ - --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ - --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf - # via singlestoredb -sse-starlette==3.2.0 \ - --hash=sha256:5876954bd51920fc2cd51baee47a080eb88a37b5b784e615abb0b283f801cdbf \ - --hash=sha256:8127594edfb51abe44eac9c49e59b0b01f1039d0c7461c6fd91d4e03b70da422 - # via mcp -stack-data==0.6.3 \ - --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ - --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 - # via ipython -starlette==0.50.0 \ - --hash=sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca \ - --hash=sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca - # via - # fastapi - # mcp - # sse-starlette -substrait==0.24.2 \ - --hash=sha256:743cc352e96b0927b2cd37cd5a8fdac0a96a68df9600bd104fc36aebd222a836 \ - --hash=sha256:d1d475833566fa9d67eed3273456883c0568486ccced92b524b31709d2817e19 - # via - # feast (setup.py) - # ibis-substrait -sympy==1.14.0 \ - --hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \ - --hash=sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5 - # via torch -tabulate==0.9.0 \ - --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ - --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f - # via - # feast (setup.py) - # docling-core - # docling-parse -tenacity==8.5.0 \ - --hash=sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78 \ - --hash=sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687 - # via feast (setup.py) -terminado==0.18.1 \ - --hash=sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0 \ - --hash=sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e - # via - # jupyter-server - # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 - # via feast (setup.py) -threadpoolctl==3.6.0 \ - --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ - --hash=sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e - # via scikit-learn -thriftpy2==0.5.3 \ - --hash=sha256:08d8699d318b6a8fe9e9fd4c2234ec7912462d90cc636c371b4f4f6500a44328 \ - --hash=sha256:0f36f80a038dbfc2b3b048151ca4732f310ebd0385cdf20e7864d781d5d6f582 \ - --hash=sha256:13c0316a1a9b6f7840d9c084a5a1fa2e419ae86645e45530593558704e792d7f \ - --hash=sha256:195beb93caa104879d808e87d92962fff8d59d40486590fd653b5aeb7774420e \ - --hash=sha256:1bb6c0482663887f2a9ab98453ab0ca20a3e1f2336a500b7da12af33614c0d75 \ - --hash=sha256:2023abcc504e4fc8825419964ecfab904244b0bc189d0082380d481ecba951d7 \ - --hash=sha256:236a7d4627b1aa692a901ca45d7dfa4e516bcd3f309efc18ac69671b31789e39 \ - --hash=sha256:29b09fa1fb77f1927ac4ce21d8f8f6663d8917f75780aa6bad57ca9473d0a3b3 \ - --hash=sha256:2d3c0403673a3b7fc38304cf89e07c792f44ac6aa3b15c12e6cc411a85d10af3 \ - --hash=sha256:2eb14e24febbeca84d603e88a24db9ccb4a1437f90e9a862dcee02dc0a2194c2 \ - --hash=sha256:2fb20edf082965487bddfba03b2c05bb50db38ceda3111540cb2353949fdb29e \ - --hash=sha256:387c04d02f23ae83415cb2de35a88ba79321619af25cf34a481cabc367ddf1aa \ - --hash=sha256:3c00c340114c3041961906a628e70e6b6b5805ee691e682c290cec3513e77efc \ - --hash=sha256:3da0e3c1a5c17f67a203d9814853dd1d8fe8b0ec69a26d30d6b634e4c0e2c87c \ - --hash=sha256:3e2fa8c3d2b1505d2a463c090d9e771b8fed0eda8b01b0365e7547ba106bf2db \ - --hash=sha256:455440132b01b3a895001dc59ecf6056e8fd041ad6e745ff22391cf3a1f8361e \ - --hash=sha256:523c480a4b3aad480e4738c32f97b3f356ed998e6549f5f55eb6f7852474cfff \ - --hash=sha256:524d69102843fed087e30c6edc5b99f7b42b768d88bf910787add60e37e2a2a5 \ - --hash=sha256:53e761ea5eab24bb3520f8adecdbb633e69dda7cf9678ca2eb6ad1952cc56540 \ - --hash=sha256:5e799f6c4caf79a5566bc14941e768b132c533bed66e0a5ef0a127a74f98acab \ - --hash=sha256:6196d7d5adb6214ed21633ec57a222c90a6a66498cdd9f8da7c85c7514c7c439 \ - --hash=sha256:6384a142514982b380431b7d8811f137c5ec9cf5cf3affa33884b7ce4a51c8c2 \ - --hash=sha256:67ec304d83510d0ec83338ef029ea3bae91fdbb3bf0504f7990dd446b483773e \ - --hash=sha256:6efccde429f93740943bc4c0e2664a49f0799ed21663cc26b16a823e8719040f \ - --hash=sha256:710b7f3d9fdbb5788b37b4b694d30fa37a3c08c0d52aeb1def57a5140fa2f4fd \ - --hash=sha256:716c36885e29a9480bdabe117235967b5fe36dc179aca80cd8ef9e12866e4cef \ - --hash=sha256:72a1cdfd3bcf16b667379f8277e83295a34ae74227e54711c657305bf4c9e63b \ - --hash=sha256:73832e79732bab15920bed700a5efbe2b6e9dbd35710e815e870feb873b15059 \ - --hash=sha256:74dc6ed8c9098b66a17b916dd898abc32801a8ef0b439a407bce4f11c1b3da34 \ - --hash=sha256:772c9c1015d05177e37b9a547bcd27b560fc888ecd1e179ebf7f114ec467914d \ - --hash=sha256:86489105abb39c6ff93c3d270cf1474f7fddd380847f2b6bc8d09e5d0f0a23ab \ - --hash=sha256:8a6652e823e0ae6fa9f73b62c1a2ed04d7c0e1ac402c7ca7c509f9f14fbcc80f \ - --hash=sha256:9460a8284881854e210907eeb1761f44afacb4d164d1b6ecfddc184ed1b03277 \ - --hash=sha256:94806a0c3436189a75efac4ab067cdab7298876fee40cc0006300cc1d7982055 \ - --hash=sha256:9cba3454b4e5e05102d2dbfadd3a9a66c19488c6aa18c147bbeff2097ae67f04 \ - --hash=sha256:9eda43701a94def9d063550b0d8261630c40ade312c35b1f6e4804859c783ed8 \ - --hash=sha256:a57c67a880c9da2d252a6244e9ccf7b08850388c7afa4f0e98cb60fdca904a09 \ - --hash=sha256:a7a00b772783847c0c48a43e098b64f5741ca5a2e52e6c66d9b753765cd93ed3 \ - --hash=sha256:a7f2913ea3beac18767784059f02a67751d99094d4a368b350911784f0e09709 \ - --hash=sha256:ab47f689b0003ec63a881e5ad4f46046f62632da5168b0665fd369a3561eaa2a \ - --hash=sha256:addcc3ba9c106758e9073ab205e4bcf9a9540acb335fafa0184a1fa8e76a78cb \ - --hash=sha256:ade0165ba060b97333bc7a927229e992441bfa17bb8e13ea05590c2ec3551b17 \ - --hash=sha256:b208f3c23f916ca0517285c11748ca1fcf43a2ac2224ea5eef8bcba464a20652 \ - --hash=sha256:b5670936016aeaeb7111c96661ced36541211c0e82eb357a9bee5d4176ebbcff \ - --hash=sha256:be23631c152323dd3d7d51368dadcec75e60e90e4662be4f2b8ada208c61fa34 \ - --hash=sha256:bf69d246c39d0ce4ed922b6e00e643ca514cdf40010b00b46f82b0f758a840b3 \ - --hash=sha256:c01e0da29120709d46cb4310944fc717f28ce097d8845c4c29e111ff98c9deff \ - --hash=sha256:c0cf4418810ecf984f6d7f538988175c459f6bd5c85d94b878ebb11dbdbfa62b \ - --hash=sha256:ca4d554f8fc79c8152119bbd576e5d6a5c11e907e0baf467fb4676b1d274558a \ - --hash=sha256:d5080c1c4bd13c4431613a2c0cd607c5e3a07a496a865a0d01f534401d3b09c7 \ - --hash=sha256:e6a77d3d190f1c2726cfb11d1115678fcfa4b0ff509bd8bb38e451c629d9383c \ - --hash=sha256:eb440b7d8e7460f6969016d77e25ebfdee2aa6d5fed95aecf2bd59310c2c5530 \ - --hash=sha256:ec49907ee15513ca2344540c4ad2bf1945c41a6c0236d589eebd32be8298faa9 \ - --hash=sha256:f2ccb893ae687ff946902d96a5615a93847a7868bc5d66f51caf5ccf46466314 \ - --hash=sha256:f4210c10b686fe4a32b121f618b407aaccc7a72021c6d64fa181a09df72c4d89 \ - --hash=sha256:f4d122a82cf7cd4743a2640199b066a994f6527802c2dd16f2e4fffc15efa2a3 \ - --hash=sha256:f768756c0c105e98a3760fc7b4f4df12e25f5334b204060bb6bdab3ce1599e11 \ - --hash=sha256:f965fff2f2f323ddb5d9cb7fabe33c4c9f008955dbb59728ffc3111557b87793 \ - --hash=sha256:fb86f4c0cfcb39949a53dcc689e3758594a18724753861ba9f59646b72417383 \ - --hash=sha256:fd4c6131ca6e919f03263cc83b713f1797bc20126a858da8518ed49b3e32c334 \ - --hash=sha256:fdc5676b52fa6a3009d205360eb9ba257b8b4813883ed52797a20838bcc45dde - # via happybase -tifffile==2026.1.14 \ - --hash=sha256:29cf4adb43562a4624fc959018ab1b44e0342015d3db4581b983fe40e05f5924 \ - --hash=sha256:a423c583e1eecd9ca255642d47f463efa8d7f2365a0e110eb0167570493e0c8c - # via scikit-image -timm==1.0.24 \ - --hash=sha256:8301ac783410c6ad72c73c49326af6d71a9e4d1558238552796e825c2464913f \ - --hash=sha256:c7b909f43fe2ef8fe62c505e270cd4f1af230dfbc37f2ee93e3608492b9d9a40 - # via feast (setup.py) -tinycss2==1.4.0 \ - --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ - --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 - # via bleach -tokenizers==0.22.2 \ - --hash=sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113 \ - --hash=sha256:1a62ba2c5faa2dd175aaeed7b15abf18d20266189fb3406c5d0550dd34dd5f37 \ - --hash=sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e \ - --hash=sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001 \ - --hash=sha256:1e50f8554d504f617d9e9d6e4c2c2884a12b388a97c5c77f0bc6cf4cd032feee \ - --hash=sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7 \ - --hash=sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd \ - --hash=sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4 \ - --hash=sha256:319f659ee992222f04e58f84cbf407cfa66a65fe3a8de44e8ad2bc53e7d99012 \ - --hash=sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67 \ - --hash=sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a \ - --hash=sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5 \ - --hash=sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917 \ - --hash=sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c \ - --hash=sha256:64d94e84f6660764e64e7e0b22baa72f6cd942279fdbb21d46abd70d179f0195 \ - --hash=sha256:753d47ebd4542742ef9261d9da92cd545b2cacbb48349a1225466745bb866ec4 \ - --hash=sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a \ - --hash=sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc \ - --hash=sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92 \ - --hash=sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5 \ - --hash=sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48 \ - --hash=sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b \ - --hash=sha256:e10bf9113d209be7cd046d40fbabbaf3278ff6d18eb4da4c500443185dc1896c \ - --hash=sha256:f01a9c019878532f98927d2bacb79bbb404b43d3437455522a00a30718cdedb5 - # via transformers -toml==0.10.2 \ - --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ - --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f - # via feast (setup.py) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 - # via - # coverage - # fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 - # via - # poetry-dynamic-versioning - # snowflake-connector-python -toolz==0.12.1 \ - --hash=sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85 \ - --hash=sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d - # via - # altair - # dask - # ibis-framework - # partd -torch==2.9.1 \ - --hash=sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73 \ - --hash=sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7 \ - --hash=sha256:0d06b30a9207b7c3516a9e0102114024755a07045f0c1d2f2a56b1819ac06bcb \ - --hash=sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6 \ - --hash=sha256:1cc208435f6c379f9b8fdfd5ceb5be1e3b72a6bdf1cb46c0d2812aa73472db9e \ - --hash=sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a \ - --hash=sha256:27331cd902fb4322252657f3902adf1c4f6acad9dcad81d8df3ae14c7c4f07c4 \ - --hash=sha256:2af70e3be4a13becba4655d6cc07dcfec7ae844db6ac38d6c1dafeb245d17d65 \ - --hash=sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587 \ - --hash=sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db \ - --hash=sha256:30a3e170a84894f3652434b56d59a64a2c11366b0ed5776fab33c2439396bf9a \ - --hash=sha256:52347912d868653e1528b47cafaf79b285b98be3f4f35d5955389b1b95224475 \ - --hash=sha256:524de44cd13931208ba2c4bde9ec7741fd4ae6bfd06409a604fc32f6520c2bc9 \ - --hash=sha256:545844cc16b3f91e08ce3b40e9c2d77012dd33a48d505aed34b7740ed627a1b2 \ - --hash=sha256:5be4bf7496f1e3ffb1dd44b672adb1ac3f081f204c5ca81eba6442f5f634df8e \ - --hash=sha256:62b3fd888277946918cba4478cf849303da5359f0fb4e3bfb86b0533ba2eaf8d \ - --hash=sha256:81a285002d7b8cfd3fdf1b98aa8df138d41f1a8334fd9ea37511517cedf43083 \ - --hash=sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2 \ - --hash=sha256:9fd35c68b3679378c11f5eb73220fdcb4e6f4592295277fbb657d31fd053237c \ - --hash=sha256:a83b0e84cc375e3318a808d032510dde99d696a85fe9473fc8575612b63ae951 \ - --hash=sha256:c0d25d1d8e531b8343bea0ed811d5d528958f1dcbd37e7245bc686273177ad7e \ - --hash=sha256:c29455d2b910b98738131990394da3e50eea8291dfeb4b12de71ecf1fdeb21cb \ - --hash=sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9 \ - --hash=sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e \ - --hash=sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c \ - --hash=sha256:d033ff0ac3f5400df862a51bdde9bad83561f3739ea0046e68f5401ebfa67c1b \ - --hash=sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d \ - --hash=sha256:da5f6f4d7f4940a173e5572791af238cb0b9e21b1aab592bd8b26da4c99f1cd6 - # via - # feast (setup.py) - # accelerate - # docling-ibm-models - # easyocr - # safetensors - # timm - # torchvision -torchvision==0.24.1 \ - --hash=sha256:056c525dc875f18fe8e9c27079ada166a7b2755cea5a2199b0bc7f1f8364e600 \ - --hash=sha256:1540a9e7f8cf55fe17554482f5a125a7e426347b71de07327d5de6bfd8d17caa \ - --hash=sha256:16274823b93048e0a29d83415166a2e9e0bf4e1b432668357b657612a4802864 \ - --hash=sha256:18f9cb60e64b37b551cd605a3d62c15730c086362b40682d23e24b616a697d41 \ - --hash=sha256:1b495edd3a8f9911292424117544f0b4ab780452e998649425d1f4b2bed6695f \ - --hash=sha256:1e39619de698e2821d71976c92c8a9e50cdfd1e993507dfb340f2688bfdd8283 \ - --hash=sha256:480b271d6edff83ac2e8d69bbb4cf2073f93366516a50d48f140ccfceedb002e \ - --hash=sha256:4aa6cb806eb8541e92c9b313e96192c6b826e9eb0042720e2fa250d021079952 \ - --hash=sha256:54ed17c3d30e718e08d8da3fd5b30ea44b0311317e55647cb97077a29ecbc25b \ - --hash=sha256:66a98471fc18cad9064123106d810a75f57f0838eee20edc56233fd8484b0cc7 \ - --hash=sha256:7fb7590c737ebe3e1c077ad60c0e5e2e56bb26e7bccc3b9d04dbfc34fd09f050 \ - --hash=sha256:8a6696db7fb71eadb2c6a48602106e136c785642e598eb1533e0b27744f2cce6 \ - --hash=sha256:9ef95d819fd6df81bc7cc97b8f21a15d2c0d3ac5dbfaab5cbc2d2ce57114b19e \ - --hash=sha256:a0f106663e60332aa4fcb1ca2159ef8c3f2ed266b0e6df88de261048a840e0df \ - --hash=sha256:a9308cdd37d8a42e14a3e7fd9d271830c7fecb150dd929b642f3c1460514599a \ - --hash=sha256:ab211e1807dc3e53acf8f6638df9a7444c80c0ad050466e8d652b3e83776987b \ - --hash=sha256:af9201184c2712d808bd4eb656899011afdfce1e83721c7cb08000034df353fe \ - --hash=sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388 \ - --hash=sha256:d83e16d70ea85d2f196d678bfb702c36be7a655b003abed84e465988b6128938 \ - --hash=sha256:db2125c46f9cb25dc740be831ce3ce99303cfe60439249a41b04fd9f373be671 \ - --hash=sha256:ded5e625788572e4e1c4d155d1bbc48805c113794100d70e19c76e39e4d53465 \ - --hash=sha256:e3f96208b4bef54cd60e415545f5200346a65024e04f29a26cd0006dbf9e8e66 \ - --hash=sha256:e48bf6a8ec95872eb45763f06499f87bd2fb246b9b96cb00aae260fda2f96193 \ - --hash=sha256:ec9d7379c519428395e4ffda4dbb99ec56be64b0a75b95989e00f9ec7ae0b2d7 \ - --hash=sha256:f035f0cacd1f44a8ff6cb7ca3627d84c54d685055961d73a1a9fb9827a5414c8 \ - --hash=sha256:f231f6a4f2aa6522713326d0d2563538fa72d613741ae364f9913027fa52ea35 \ - --hash=sha256:f476da4e085b7307aaab6f540219617d46d5926aeda24be33e1359771c83778f \ - --hash=sha256:fbdbdae5e540b868a681240b7dbd6473986c862445ee8a138680a6a97d6c34ff - # via - # feast (setup.py) - # docling-ibm-models - # easyocr - # timm -tornado==6.5.4 \ - --hash=sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1 \ - --hash=sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1 \ - --hash=sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 \ - --hash=sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335 \ - --hash=sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8 \ - --hash=sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f \ - --hash=sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84 \ - --hash=sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7 \ - --hash=sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17 \ - --hash=sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 \ - --hash=sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f \ - --hash=sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc - # via - # ipykernel - # jupyter-client - # jupyter-server - # jupyterlab - # notebook - # terminado -tqdm==4.67.1 \ - --hash=sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2 \ - --hash=sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2 - # via - # feast (setup.py) - # datasets - # docling - # docling-ibm-models - # great-expectations - # huggingface-hub - # milvus-lite - # mpire - # semchunk - # transformers -traitlets==5.14.3 \ - --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ - --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f - # via - # ipykernel - # ipython - # ipywidgets - # jupyter-client - # jupyter-core - # jupyter-events - # jupyter-server - # jupyterlab - # matplotlib-inline - # nbclient - # nbconvert - # nbformat -transformers==4.57.6 \ - --hash=sha256:4c9e9de11333ddfe5114bc872c9f370509198acf0b87a832a0ab9458e2bd0550 \ - --hash=sha256:55e44126ece9dc0a291521b7e5492b572e6ef2766338a610b9ab5afbb70689d3 - # via - # feast (setup.py) - # docling-core - # docling-ibm-models -tree-sitter==0.24.0 \ - --hash=sha256:01ea01a7003b88b92f7f875da6ba9d5d741e0c84bb1bd92c503c0eecd0ee6409 \ - --hash=sha256:033506c1bc2ba7bd559b23a6bdbeaf1127cee3c68a094b82396718596dfe98bc \ - --hash=sha256:098a81df9f89cf254d92c1cd0660a838593f85d7505b28249216661d87adde4a \ - --hash=sha256:0b26bf9e958da6eb7e74a081aab9d9c7d05f9baeaa830dbb67481898fd16f1f5 \ - --hash=sha256:0d4a6416ed421c4210f0ca405a4834d5ccfbb8ad6692d4d74f7773ef68f92071 \ - --hash=sha256:14beeff5f11e223c37be7d5d119819880601a80d0399abe8c738ae2288804afc \ - --hash=sha256:23641bd25dcd4bb0b6fa91b8fb3f46cc9f1c9f475efe4d536d3f1f688d1b84c8 \ - --hash=sha256:24a8dd03b0d6b8812425f3b84d2f4763322684e38baf74e5bb766128b5633dc7 \ - --hash=sha256:26a5b130f70d5925d67b47db314da209063664585a2fd36fa69e0717738efaf4 \ - --hash=sha256:2a84ff87a2f2a008867a1064aba510ab3bd608e3e0cd6e8fef0379efee266c73 \ - --hash=sha256:3b1f3cbd9700e1fba0be2e7d801527e37c49fc02dc140714669144ef6ab58dce \ - --hash=sha256:464fa5b2cac63608915a9de8a6efd67a4da1929e603ea86abaeae2cb1fe89921 \ - --hash=sha256:4ddb113e6b8b3e3b199695b1492a47d87d06c538e63050823d90ef13cac585fd \ - --hash=sha256:57277a12fbcefb1c8b206186068d456c600dbfbc3fd6c76968ee22614c5cd5ad \ - --hash=sha256:5fc5c3c26d83c9d0ecb4fc4304fba35f034b7761d35286b936c1db1217558b4e \ - --hash=sha256:772e1bd8c0931c866b848d0369b32218ac97c24b04790ec4b0e409901945dd8e \ - --hash=sha256:7d5d9537507e1c8c5fa9935b34f320bfec4114d675e028f3ad94f11cf9db37b9 \ - --hash=sha256:a7c9c89666dea2ce2b2bf98e75f429d2876c569fab966afefdcd71974c6d8538 \ - --hash=sha256:abd95af65ca2f4f7eca356343391ed669e764f37748b5352946f00f7fc78e734 \ - --hash=sha256:c012e4c345c57a95d92ab5a890c637aaa51ab3b7ff25ed7069834b1087361c95 \ - --hash=sha256:d25fa22766d63f73716c6fec1a31ee5cf904aa429484256bd5fdf5259051ed74 \ - --hash=sha256:de0fb7c18c6068cacff46250c0a0473e8fc74d673e3e86555f131c2c1346fb13 \ - --hash=sha256:e0992d483677e71d5c5d37f30dfb2e3afec2f932a9c53eec4fca13869b788c6c \ - --hash=sha256:f3f00feff1fc47a8e4863561b8da8f5e023d382dd31ed3e43cd11d4cae445445 \ - --hash=sha256:f3f08a2ca9f600b3758792ba2406971665ffbad810847398d180c48cee174ee2 \ - --hash=sha256:f58bb4956917715ec4d5a28681829a8dad5c342cafd4aea269f9132a83ca9b34 \ - --hash=sha256:f733a83d8355fc95561582b66bbea92ffd365c5d7a665bc9ebd25e049c2b2abb \ - --hash=sha256:f9691be48d98c49ef8f498460278884c666b44129222ed6217477dffad5d4831 \ - --hash=sha256:f9e8b1605ab60ed43803100f067eed71b0b0e6c1fb9860a262727dbfbbb74751 - # via docling-core -tree-sitter-c==0.23.4 \ - --hash=sha256:013403e74765d74e523f380f9df8f3d99e9fe94132a3fc0c8b29cba538a7b2bf \ - --hash=sha256:2c92c0571b36b6da06f8882f34151dc11e67a493e9101cc0026a16da27709c05 \ - --hash=sha256:5e42a3519825ca59c91b2b7aec08dd3c89e02690c7b315d54a1e1743f9be3f15 \ - --hash=sha256:9215c7888dd019038f162ea5646178f6e129cd2b49fc506d14becf5e426121d7 \ - --hash=sha256:98c285a23bf4fb6fb34140d6ea0f0d25d0a93e0d93692f9dffe3db6d1fe08534 \ - --hash=sha256:a4d7bdeaca8f1da72352a945853f56aa5d34e7bc22569ec5bda5d7c1a04e5b0f \ - --hash=sha256:c15c7588c3d95872328019073a8d5eaf7c2691b4d4ef0393a0168399b2ad2356 \ - --hash=sha256:edd36e12cc79b8b5bbc81fc336ff7d2577d0fe16afd18163c9aff7ae3ff69e15 - # via docling-core -tree-sitter-javascript==0.23.1 \ - --hash=sha256:041fa22b34250ea6eb313d33104d5303f79504cb259d374d691e38bbdc49145b \ - --hash=sha256:056dc04fb6b24293f8c5fec43c14e7e16ba2075b3009c643abf8c85edc4c7c3c \ - --hash=sha256:5a6bc1055b061c5055ec58f39ee9b2e9efb8e6e0ae970838af74da0afb811f0a \ - --hash=sha256:6ca583dad4bd79d3053c310b9f7208cd597fd85f9947e4ab2294658bb5c11e35 \ - --hash=sha256:94100e491a6a247aa4d14caf61230c171b6376c863039b6d9cd71255c2d815ec \ - --hash=sha256:a11ca1c0f736da42967586b568dff8a465ee148a986c15ebdc9382806e0ce871 \ - --hash=sha256:b2059ce8b150162cda05a457ca3920450adbf915119c04b8c67b5241cd7fcfed \ - --hash=sha256:eb28130cd2fb30d702d614cbf61ef44d1c7f6869e7d864a9cc17111e370be8f7 - # via docling-core -tree-sitter-python==0.23.6 \ - --hash=sha256:28fbec8f74eeb2b30292d97715e60fac9ccf8a8091ce19b9d93e9b580ed280fb \ - --hash=sha256:29dacdc0cd2f64e55e61d96c6906533ebb2791972bec988450c46cce60092f5d \ - --hash=sha256:354bfa0a2f9217431764a631516f85173e9711af2c13dbd796a8815acfe505d9 \ - --hash=sha256:680b710051b144fedf61c95197db0094f2245e82551bf7f0c501356333571f7a \ - --hash=sha256:71334371bd73d5fe080aed39fbff49ed8efb9506edebe16795b0c7567ed6a272 \ - --hash=sha256:7e048733c36f564b379831689006801feb267d8194f9e793fbb395ef1723335d \ - --hash=sha256:8a9dcef55507b6567207e8ee0a6b053d0688019b47ff7f26edc1764b7f4dc0a4 \ - --hash=sha256:a24027248399fb41594b696f929f9956828ae7cc85596d9f775e6c239cd0c2be - # via docling-core -tree-sitter-typescript==0.23.2 \ - --hash=sha256:05db58f70b95ef0ea126db5560f3775692f609589ed6f8dd0af84b7f19f1cbb7 \ - --hash=sha256:3cd752d70d8e5371fdac6a9a4df9d8924b63b6998d268586f7d374c9fba2a478 \ - --hash=sha256:3f730b66396bc3e11811e4465c41ee45d9e9edd6de355a58bbbc49fa770da8f9 \ - --hash=sha256:4b1eed5b0b3a8134e86126b00b743d667ec27c63fc9de1b7bb23168803879e31 \ - --hash=sha256:7b167b5827c882261cb7a50dfa0fb567975f9b315e87ed87ad0a0a3aedb3834d \ - --hash=sha256:8d4f0f9bcb61ad7b7509d49a1565ff2cc363863644a234e1e0fe10960e55aea0 \ - --hash=sha256:c7cc1b0ff5d91bac863b0e38b1578d5505e718156c9db577c8baea2557f66de8 \ - --hash=sha256:e96d36b85bcacdeb8ff5c2618d75593ef12ebaf1b4eace3477e2bdb2abb1752c - # via docling-core -trino==0.336.0 \ - --hash=sha256:389150841446949119c3c2c13c1a51bb4be1a27818e40ae40dd3701f36c02550 \ - --hash=sha256:e82339e9fffe5c6c51de3bfdf28f083e3ae5945a4502739ab2094a0d08d68070 - # via feast (setup.py) -typeguard==4.4.4 \ - --hash=sha256:3a7fd2dffb705d4d0efaed4306a704c89b9dee850b688f060a8b1615a79e5f74 \ - --hash=sha256:b5f562281b6bfa1f5492470464730ef001646128b180769880468bd84b68b09e - # via feast (setup.py) -typer==0.12.5 \ - --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ - --hash=sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722 - # via - # docling - # docling-core - # fastapi-mcp -types-cffi==1.17.0.20250915 \ - --hash=sha256:4362e20368f78dabd5c56bca8004752cc890e07a71605d9e0d9e069dbaac8c06 \ - --hash=sha256:cef4af1116c83359c11bb4269283c50f0688e9fc1d7f0eeb390f3661546da52c - # via types-pyopenssl -types-protobuf==3.19.22 \ - --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ - --hash=sha256:d2b26861b0cb46a3c8669b0df507b7ef72e487da66d61f9f3576aa76ce028a83 - # via - # feast (setup.py) - # mypy-protobuf -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 - # via feast (setup.py) -types-pyopenssl==24.1.0.20240722 \ - --hash=sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39 \ - --hash=sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54 - # via types-redis -types-python-dateutil==2.9.0.20251115 \ - --hash=sha256:8a47f2c3920f52a994056b8786309b43143faa5a64d4cbb2722d6addabdf1a58 \ - --hash=sha256:9cf9c1c582019753b8639a081deefd7e044b9fa36bd8217f565c6c4e36ee0624 - # via feast (setup.py) -types-pytz==2025.2.0.20251108 \ - --hash=sha256:0f1c9792cab4eb0e46c52f8845c8f77cf1e313cb3d68bf826aa867fe4717d91c \ - --hash=sha256:fca87917836ae843f07129567b74c1929f1870610681b4c92cb86a3df5817bdb - # via feast (setup.py) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 - # via feast (setup.py) -types-redis==4.6.0.20241004 \ - --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ - --hash=sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed - # via feast (setup.py) -types-requests==2.30.0.0 \ - --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ - --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 - # via feast (setup.py) -types-setuptools==80.9.0.20251223 \ - --hash=sha256:1b36db79d724c2287d83dc052cf887b47c0da6a2fff044378be0b019545f56e6 \ - --hash=sha256:d3411059ae2f5f03985217d86ac6084efea2c9e9cacd5f0869ef950f308169b2 - # via - # feast (setup.py) - # types-cffi -types-tabulate==0.9.0.20241207 \ - --hash=sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230 \ - --hash=sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85 - # via feast (setup.py) -types-urllib3==1.26.25.14 \ - --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ - --hash=sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e - # via types-requests -typing-extensions==4.15.0 \ - --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ - --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 - # via - # aiosignal - # anyio - # azure-core - # azure-identity - # azure-storage-blob - # beautifulsoup4 - # docling-core - # elasticsearch - # fastapi - # great-expectations - # huggingface-hub - # ibis-framework - # ipython - # jwcrypto - # mcp - # minio - # mypy - # opentelemetry-api - # opentelemetry-sdk - # opentelemetry-semantic-conventions - # psycopg - # psycopg-pool - # pydantic - # pydantic-core - # pyopenssl - # python-docx - # python-pptx - # referencing - # snowflake-connector-python - # sqlalchemy - # starlette - # testcontainers - # torch - # typeguard - # typer - # typing-inspection -typing-inspection==0.4.2 \ - --hash=sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 \ - --hash=sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464 - # via - # mcp - # pydantic - # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 - # via - # arrow - # pandas -tzlocal==5.3.1 \ - --hash=sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd \ - --hash=sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d - # via - # great-expectations - # trino -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -uri-template==1.3.0 \ - --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ - --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 - # via jsonschema -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 - # via - # feast (setup.py) - # botocore - # clickhouse-connect - # docker - # elastic-transport - # great-expectations - # kubernetes - # minio - # qdrant-client - # requests - # responses - # testcontainers -uvicorn[standard]==0.34.0 \ - --hash=sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4 \ - --hash=sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9 - # via - # feast (setup.py) - # fastapi-mcp - # mcp - # uvicorn-worker -uvicorn-worker==0.3.0 \ - --hash=sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b \ - --hash=sha256:ef0fe8aad27b0290a9e602a256b03f5a5da3a9e5f942414ca587b645ec77dd52 - # via feast (setup.py) -uvloop==0.22.1 \ - --hash=sha256:017bd46f9e7b78e81606329d07141d3da446f8798c6baeec124260e22c262772 \ - --hash=sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e \ - --hash=sha256:05e4b5f86e621cf3927631789999e697e58f0d2d32675b67d9ca9eb0bca55743 \ - --hash=sha256:0ae676de143db2b2f60a9696d7eca5bb9d0dd6cc3ac3dad59a8ae7e95f9e1b54 \ - --hash=sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec \ - --hash=sha256:17d4e97258b0172dfa107b89aa1eeba3016f4b1974ce85ca3ef6a66b35cbf659 \ - --hash=sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8 \ - --hash=sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad \ - --hash=sha256:286322a90bea1f9422a470d5d2ad82d38080be0a29c4dd9b3e6384320a4d11e7 \ - --hash=sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35 \ - --hash=sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289 \ - --hash=sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142 \ - --hash=sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77 \ - --hash=sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733 \ - --hash=sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd \ - --hash=sha256:4a968a72422a097b09042d5fa2c5c590251ad484acf910a651b4b620acd7f193 \ - --hash=sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74 \ - --hash=sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0 \ - --hash=sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6 \ - --hash=sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473 \ - --hash=sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21 \ - --hash=sha256:55502bc2c653ed2e9692e8c55cb95b397d33f9f2911e929dc97c4d6b26d04242 \ - --hash=sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705 \ - --hash=sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702 \ - --hash=sha256:57df59d8b48feb0e613d9b1f5e57b7532e97cbaf0d61f7aa9aa32221e84bc4b6 \ - --hash=sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f \ - --hash=sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e \ - --hash=sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d \ - --hash=sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370 \ - --hash=sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4 \ - --hash=sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792 \ - --hash=sha256:80eee091fe128e425177fbd82f8635769e2f32ec9daf6468286ec57ec0313efa \ - --hash=sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079 \ - --hash=sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2 \ - --hash=sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86 \ - --hash=sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6 \ - --hash=sha256:b45649628d816c030dba3c80f8e2689bab1c89518ed10d426036cdc47874dfc4 \ - --hash=sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3 \ - --hash=sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21 \ - --hash=sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c \ - --hash=sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e \ - --hash=sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25 \ - --hash=sha256:c3e5c6727a57cb6558592a95019e504f605d1c54eb86463ee9f7a2dbd411c820 \ - --hash=sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9 \ - --hash=sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88 \ - --hash=sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2 \ - --hash=sha256:ea721dd3203b809039fcc2983f14608dae82b212288b346e0bfe46ec2fab0b7c \ - --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ - --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 - # via uvicorn -virtualenv==20.23.0 \ - --hash=sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e \ - --hash=sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924 - # via - # feast (setup.py) - # pre-commit - # ray -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf - # via uvicorn -wcwidth==0.2.14 \ - --hash=sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605 \ - --hash=sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1 - # via prompt-toolkit -webcolors==25.10.0 \ - --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ - --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf - # via jsonschema -webencodings==0.5.1 \ - --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ - --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 - # via - # bleach - # tinycss2 -websocket-client==1.9.0 \ - --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ - --hash=sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef - # via - # jupyter-server - # kubernetes -websockets==16.0 \ - --hash=sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c \ - --hash=sha256:04cdd5d2d1dacbad0a7bf36ccbcd3ccd5a30ee188f2560b7a62a30d14107b31a \ - --hash=sha256:08d7af67b64d29823fed316505a89b86705f2b7981c07848fb5e3ea3020c1abe \ - --hash=sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e \ - --hash=sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec \ - --hash=sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1 \ - --hash=sha256:1c1b30e4f497b0b354057f3467f56244c603a79c0d1dafce1d16c283c25f6e64 \ - --hash=sha256:2b9f1e0d69bc60a4a87349d50c09a037a2607918746f07de04df9e43252c77a3 \ - --hash=sha256:31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8 \ - --hash=sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206 \ - --hash=sha256:335c23addf3d5e6a8633f9f8eda77efad001671e80b95c491dd0924587ece0b3 \ - --hash=sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156 \ - --hash=sha256:349f83cd6c9a415428ee1005cadb5c2c56f4389bc06a9af16103c3bc3dcc8b7d \ - --hash=sha256:37b31c1623c6605e4c00d466c9d633f9b812ea430c11c8a278774a1fde1acfa9 \ - --hash=sha256:417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad \ - --hash=sha256:485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2 \ - --hash=sha256:4a1aba3340a8dca8db6eb5a7986157f52eb9e436b74813764241981ca4888f03 \ - --hash=sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8 \ - --hash=sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230 \ - --hash=sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8 \ - --hash=sha256:5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea \ - --hash=sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641 \ - --hash=sha256:583b7c42688636f930688d712885cf1531326ee05effd982028212ccc13e5957 \ - --hash=sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6 \ - --hash=sha256:5f451484aeb5cafee1ccf789b1b66f535409d038c56966d6101740c1614b86c6 \ - --hash=sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5 \ - --hash=sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f \ - --hash=sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00 \ - --hash=sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e \ - --hash=sha256:7be95cfb0a4dae143eaed2bcba8ac23f4892d8971311f1b06f3c6b78952ee70b \ - --hash=sha256:7d837379b647c0c4c2355c2499723f82f1635fd2c26510e1f587d89bc2199e72 \ - --hash=sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39 \ - --hash=sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9 \ - --hash=sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79 \ - --hash=sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0 \ - --hash=sha256:8d7f0659570eefb578dacde98e24fb60af35350193e4f56e11190787bee77dac \ - --hash=sha256:8e1dab317b6e77424356e11e99a432b7cb2f3ec8c5ab4dabbcee6add48f72b35 \ - --hash=sha256:8ff32bb86522a9e5e31439a58addbb0166f0204d64066fb955265c4e214160f0 \ - --hash=sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5 \ - --hash=sha256:9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c \ - --hash=sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8 \ - --hash=sha256:a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1 \ - --hash=sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244 \ - --hash=sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3 \ - --hash=sha256:a653aea902e0324b52f1613332ddf50b00c06fdaf7e92624fbf8c77c78fa5767 \ - --hash=sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a \ - --hash=sha256:af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d \ - --hash=sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd \ - --hash=sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e \ - --hash=sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944 \ - --hash=sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82 \ - --hash=sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d \ - --hash=sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4 \ - --hash=sha256:d6297ce39ce5c2e6feb13c1a996a2ded3b6832155fcfc920265c76f24c7cceb5 \ - --hash=sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904 \ - --hash=sha256:df57afc692e517a85e65b72e165356ed1df12386ecb879ad5693be08fac65dde \ - --hash=sha256:e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f \ - --hash=sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c \ - --hash=sha256:eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89 \ - --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ - --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 - # via uvicorn -werkzeug==3.1.5 \ - --hash=sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc \ - --hash=sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67 - # via moto -wheel==0.45.1 \ - --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ - --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 - # via - # pip-tools - # singlestoredb -widgetsnbextension==4.0.15 \ - --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ - --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 - # via ipywidgets -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c - # via - # aiobotocore - # smart-open - # testcontainers -xlsxwriter==3.2.9 \ - --hash=sha256:254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c \ - --hash=sha256:9a5db42bc5dff014806c58a20b9eae7322a134abb6fce3c92c181bfb275ec5b3 - # via python-pptx -xmltodict==1.0.2 \ - --hash=sha256:54306780b7c2175a3967cad1db92f218207e5bc1aba697d887807c0fb68b7649 \ - --hash=sha256:62d0fddb0dcbc9f642745d8bbf4d81fd17d6dfaec5a15b5c1876300aad92af0d - # via moto -xxhash==3.6.0 \ - --hash=sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad \ - --hash=sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c \ - --hash=sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3 \ - --hash=sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004 \ - --hash=sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b \ - --hash=sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796 \ - --hash=sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f \ - --hash=sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c \ - --hash=sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1 \ - --hash=sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1 \ - --hash=sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0 \ - --hash=sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec \ - --hash=sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d \ - --hash=sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919 \ - --hash=sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67 \ - --hash=sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360 \ - --hash=sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799 \ - --hash=sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679 \ - --hash=sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef \ - --hash=sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d \ - --hash=sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7 \ - --hash=sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8 \ - --hash=sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa \ - --hash=sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e \ - --hash=sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa \ - --hash=sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec \ - --hash=sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4 \ - --hash=sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad \ - --hash=sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7 \ - --hash=sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5 \ - --hash=sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11 \ - --hash=sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae \ - --hash=sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d \ - --hash=sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4 \ - --hash=sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6 \ - --hash=sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df \ - --hash=sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058 \ - --hash=sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850 \ - --hash=sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2 \ - --hash=sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d \ - --hash=sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89 \ - --hash=sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e \ - --hash=sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa \ - --hash=sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6 \ - --hash=sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb \ - --hash=sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3 \ - --hash=sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b \ - --hash=sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4 \ - --hash=sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db \ - --hash=sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119 \ - --hash=sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec \ - --hash=sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518 \ - --hash=sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296 \ - --hash=sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033 \ - --hash=sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729 \ - --hash=sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca \ - --hash=sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063 \ - --hash=sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5 \ - --hash=sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d \ - --hash=sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f \ - --hash=sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8 \ - --hash=sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42 \ - --hash=sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e \ - --hash=sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392 \ - --hash=sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222 \ - --hash=sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f \ - --hash=sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd \ - --hash=sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77 \ - --hash=sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802 \ - --hash=sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d \ - --hash=sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1 \ - --hash=sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41 \ - --hash=sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374 \ - --hash=sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263 \ - --hash=sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71 \ - --hash=sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13 \ - --hash=sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8 \ - --hash=sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc \ - --hash=sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62 \ - --hash=sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11 \ - --hash=sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65 \ - --hash=sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0 \ - --hash=sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b \ - --hash=sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2 \ - --hash=sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788 \ - --hash=sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6 \ - --hash=sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f \ - --hash=sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc \ - --hash=sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e \ - --hash=sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702 \ - --hash=sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 \ - --hash=sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f \ - --hash=sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6 \ - --hash=sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87 \ - --hash=sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3 \ - --hash=sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a \ - --hash=sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b \ - --hash=sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b \ - --hash=sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b \ - --hash=sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8 \ - --hash=sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db \ - --hash=sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99 \ - --hash=sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a \ - --hash=sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2 \ - --hash=sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204 \ - --hash=sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b \ - --hash=sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546 \ - --hash=sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95 \ - --hash=sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9 \ - --hash=sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54 \ - --hash=sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06 \ - --hash=sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c \ - --hash=sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152 \ - --hash=sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86 \ - --hash=sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4 \ - --hash=sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93 \ - --hash=sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd \ - --hash=sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd \ - --hash=sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a \ - --hash=sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2 \ - --hash=sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248 \ - --hash=sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd \ - --hash=sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6 \ - --hash=sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf \ - --hash=sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7 \ - --hash=sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490 \ - --hash=sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0 \ - --hash=sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536 \ - --hash=sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb \ - --hash=sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829 \ - --hash=sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746 \ - --hash=sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07 \ - --hash=sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292 \ - --hash=sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6 \ - --hash=sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd \ - --hash=sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7 \ - --hash=sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d \ - --hash=sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0 \ - --hash=sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee \ - --hash=sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6 - # via datasets -yarl==1.22.0 \ - --hash=sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a \ - --hash=sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8 \ - --hash=sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b \ - --hash=sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da \ - --hash=sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf \ - --hash=sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890 \ - --hash=sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093 \ - --hash=sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6 \ - --hash=sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79 \ - --hash=sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683 \ - --hash=sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed \ - --hash=sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2 \ - --hash=sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff \ - --hash=sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02 \ - --hash=sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b \ - --hash=sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03 \ - --hash=sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511 \ - --hash=sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c \ - --hash=sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124 \ - --hash=sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c \ - --hash=sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da \ - --hash=sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2 \ - --hash=sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0 \ - --hash=sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba \ - --hash=sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d \ - --hash=sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53 \ - --hash=sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138 \ - --hash=sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4 \ - --hash=sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748 \ - --hash=sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7 \ - --hash=sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d \ - --hash=sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503 \ - --hash=sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d \ - --hash=sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2 \ - --hash=sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa \ - --hash=sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737 \ - --hash=sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f \ - --hash=sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1 \ - --hash=sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d \ - --hash=sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694 \ - --hash=sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3 \ - --hash=sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a \ - --hash=sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d \ - --hash=sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b \ - --hash=sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a \ - --hash=sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6 \ - --hash=sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b \ - --hash=sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea \ - --hash=sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5 \ - --hash=sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f \ - --hash=sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df \ - --hash=sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f \ - --hash=sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b \ - --hash=sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba \ - --hash=sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9 \ - --hash=sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0 \ - --hash=sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6 \ - --hash=sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b \ - --hash=sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967 \ - --hash=sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2 \ - --hash=sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708 \ - --hash=sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda \ - --hash=sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8 \ - --hash=sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10 \ - --hash=sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c \ - --hash=sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b \ - --hash=sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028 \ - --hash=sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e \ - --hash=sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147 \ - --hash=sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33 \ - --hash=sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca \ - --hash=sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590 \ - --hash=sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c \ - --hash=sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53 \ - --hash=sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74 \ - --hash=sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60 \ - --hash=sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f \ - --hash=sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1 \ - --hash=sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27 \ - --hash=sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520 \ - --hash=sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e \ - --hash=sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467 \ - --hash=sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca \ - --hash=sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859 \ - --hash=sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273 \ - --hash=sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e \ - --hash=sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601 \ - --hash=sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054 \ - --hash=sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376 \ - --hash=sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7 \ - --hash=sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b \ - --hash=sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb \ - --hash=sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65 \ - --hash=sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784 \ - --hash=sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71 \ - --hash=sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b \ - --hash=sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a \ - --hash=sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c \ - --hash=sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face \ - --hash=sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d \ - --hash=sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e \ - --hash=sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e \ - --hash=sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca \ - --hash=sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9 \ - --hash=sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb \ - --hash=sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95 \ - --hash=sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed \ - --hash=sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf \ - --hash=sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca \ - --hash=sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2 \ - --hash=sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62 \ - --hash=sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df \ - --hash=sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a \ - --hash=sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67 \ - --hash=sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f \ - --hash=sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529 \ - --hash=sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486 \ - --hash=sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a \ - --hash=sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e \ - --hash=sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b \ - --hash=sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74 \ - --hash=sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d \ - --hash=sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b \ - --hash=sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc \ - --hash=sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2 \ - --hash=sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e \ - --hash=sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8 \ - --hash=sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82 \ - --hash=sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd \ - --hash=sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249 - # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 - # via importlib-metadata -zstandard==0.25.0 \ - --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ - --hash=sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a \ - --hash=sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3 \ - --hash=sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f \ - --hash=sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6 \ - --hash=sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936 \ - --hash=sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431 \ - --hash=sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250 \ - --hash=sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa \ - --hash=sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f \ - --hash=sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851 \ - --hash=sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3 \ - --hash=sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9 \ - --hash=sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6 \ - --hash=sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362 \ - --hash=sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649 \ - --hash=sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb \ - --hash=sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5 \ - --hash=sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439 \ - --hash=sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137 \ - --hash=sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa \ - --hash=sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd \ - --hash=sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701 \ - --hash=sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0 \ - --hash=sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043 \ - --hash=sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1 \ - --hash=sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860 \ - --hash=sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611 \ - --hash=sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53 \ - --hash=sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b \ - --hash=sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088 \ - --hash=sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e \ - --hash=sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa \ - --hash=sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2 \ - --hash=sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0 \ - --hash=sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7 \ - --hash=sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf \ - --hash=sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388 \ - --hash=sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530 \ - --hash=sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577 \ - --hash=sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902 \ - --hash=sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc \ - --hash=sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98 \ - --hash=sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a \ - --hash=sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097 \ - --hash=sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea \ - --hash=sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09 \ - --hash=sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb \ - --hash=sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7 \ - --hash=sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74 \ - --hash=sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b \ - --hash=sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b \ - --hash=sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b \ - --hash=sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91 \ - --hash=sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150 \ - --hash=sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049 \ - --hash=sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27 \ - --hash=sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a \ - --hash=sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00 \ - --hash=sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd \ - --hash=sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072 \ - --hash=sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c \ - --hash=sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c \ - --hash=sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065 \ - --hash=sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512 \ - --hash=sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1 \ - --hash=sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f \ - --hash=sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2 \ - --hash=sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df \ - --hash=sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab \ - --hash=sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7 \ - --hash=sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b \ - --hash=sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550 \ - --hash=sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0 \ - --hash=sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea \ - --hash=sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277 \ - --hash=sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2 \ - --hash=sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7 \ - --hash=sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778 \ - --hash=sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859 \ - --hash=sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d \ - --hash=sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751 \ - --hash=sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12 \ - --hash=sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2 \ - --hash=sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d \ - --hash=sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0 \ - --hash=sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3 \ - --hash=sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd \ - --hash=sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e \ - --hash=sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f \ - --hash=sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e \ - --hash=sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94 \ - --hash=sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708 \ - --hash=sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313 \ - --hash=sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4 \ - --hash=sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c \ - --hash=sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344 \ - --hash=sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551 \ - --hash=sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01 - # via - # clickhouse-connect - # trino diff --git a/sdk/python/requirements/py3.11-requirements.txt b/sdk/python/requirements/py3.11-requirements.txt index 21385a1150d..b48c5d698f5 100644 --- a/sdk/python/requirements/py3.11-requirements.txt +++ b/sdk/python/requirements/py3.11-requirements.txt @@ -8,144 +8,195 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # starlette # watchfiles -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via requests -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask @@ -158,25 +209,25 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via feast (pyproject.toml) -fsspec==2026.2.0 \ - --hash=sha256:6544e34b16869f5aacd5b90bdf1a71acb37792ea3ddf6125ee69a22a53fb8bff \ - --hash=sha256:98de475b5cb3bd66bedd5c4679e87b4fdfe1a3bf4d707b151b3c07e58c9a2437 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -184,60 +235,67 @@ h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 # via uvicorn -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # requests -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc # via dask jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -251,97 +309,97 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -547,206 +605,136 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask # pandas -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -813,23 +801,23 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -protobuf==7.34.0 \ - --hash=sha256:3871a3df67c710aaf7bb8d214cc997342e63ceebd940c8c7fc65c9b3d697591a \ - --hash=sha256:4a72a8ec94e7a9f7ef7fe818ed26d073305f347f8b3b5ba31e22f81fd85fca02 \ - --hash=sha256:8e329966799f2c271d5e05e236459fe1cbfdb8755aaa3b0914fa60947ddea408 \ - --hash=sha256:964cf977e07f479c0697964e83deda72bcbc75c3badab506fb061b352d991b01 \ - --hash=sha256:9d7a5005fb96f3c1e64f397f91500b0eb371b28da81296ae73a6b08a5b76cdd6 \ - --hash=sha256:9f9079f1dde4e32342ecbd1c118d76367090d4aaa19da78230c38101c5b3dd40 \ - --hash=sha256:e3b914dd77fa33fa06ab2baa97937746ab25695f389869afdf03e81f34e45dc7 \ - --hash=sha256:f791ec509707a1d91bd02e07df157e75e4fb9fbdad12a81b7396201ec244e2e3 +protobuf==7.35.0 \ + --hash=sha256:4c4617b83ade0e279d1d2bfe04025a1adb87f9ed657de038620dc0ff959357f6 \ + --hash=sha256:4cbf5cc286130e06a6c9bbefac442431173906dfcc979712183d4adcc01b37ee \ + --hash=sha256:66be6c513931c794fa92c080ffee41671390da3d79da219cf9c0c0907f035dda \ + --hash=sha256:6c0f98f10c8a05ea30f8993dfef2de093d27b490fdae78bb60c8343795d55011 \ + --hash=sha256:a2efd84605f41e559f1881b0912b44099d0a2ac9bf46b3474823f10fb393b0e6 \ + --hash=sha256:c13f325cf242bad135c350629eeb5d54b24228eb472fb3e2e9ebbd4c5dc20ca0 \ + --hash=sha256:f05bcadf9a2a6b8dda047007075135fb7d08c73d9177aabc067e1be46881a201 \ + --hash=sha256:fcbe42a4ac09d3ec9c987ddfcd956afd0b15f1ff613bd8371bde9405ffd5c8e5 # via feast (pyproject.toml) psutil==7.2.2 \ --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ @@ -854,196 +842,195 @@ psutil==7.2.2 \ --hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \ --hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8 # via feast (pyproject.toml) -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via feast (pyproject.toml) -pyjwt==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via feast (pyproject.toml) python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -1053,9 +1040,9 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via uvicorn -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via pandas pyyaml==6.0.3 \ --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ @@ -1141,126 +1128,141 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via feast (pyproject.toml) -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing @@ -1268,75 +1270,72 @@ six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 # via python-dateutil -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 - # via fastapi +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 + # via + # feast (pyproject.toml) + # fastapi tabulate==0.10.0 \ --hash=sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d \ --hash=sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 @@ -1355,13 +1354,13 @@ toolz==1.1.0 \ # via # dask # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -1383,13 +1382,13 @@ typing-inspection==0.4.2 \ # via # fastapi # pydantic -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via pandas -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via requests uvicorn[standard]==0.34.0 \ --hash=sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4 \ @@ -1452,116 +1451,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websockets==16.0 \ --hash=sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c \ @@ -1626,7 +1623,7 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata diff --git a/sdk/python/requirements/py3.12-ci-requirements.txt b/sdk/python/requirements/py3.12-ci-requirements.txt index 9b9bd41e436..3b1c16c643d 100644 --- a/sdk/python/requirements/py3.12-ci-requirements.txt +++ b/sdk/python/requirements/py3.12-ci-requirements.txt @@ -4,139 +4,140 @@ accelerate==1.13.0 \ --hash=sha256:cf1a3efb96c18f7b152eb0fa7490f3710b19c3f395699358f08decca2b8b62e0 \ --hash=sha256:d631b4e0f5b3de4aff2d7e9e6857d164810dfc3237d54d017f075122d057b236 # via docling-ibm-models -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a # via # aiobotocore # aiohttp-cors # fsspec + # kubernetes + # mlflow # ray aiohttp-cors==0.8.1 \ --hash=sha256:3180cf304c5c712d626b9162b195b1db7ddf976a2a25172b35bb2448b890a80d \ @@ -154,6 +155,10 @@ alabaster==0.7.16 \ --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 # via sphinx +alembic==1.18.4 \ + --hash=sha256:a5ed4adcf6d8a4cb575f3d759f071b03cd6e5c7618eb796cb52497be25bfe19a \ + --hash=sha256:cb6e1fd84b6174ab8dbb2329f86d631ba9559dd78df550b57804d607672cedbc + # via mlflow altair==4.2.2 \ --hash=sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5 \ --hash=sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87 @@ -166,9 +171,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # elasticsearch # httpx @@ -230,9 +235,9 @@ asttokens==3.0.1 \ --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 # via stack-data -async-lru==2.2.0 \ - --hash=sha256:80abae2a237dbc6c60861d621619af39f0d920aea306de34cb992c879e01370c \ - --hash=sha256:e2c1cf731eba202b59c5feedaef14ffd9d02ad0037fcda64938699f2c380eafe +async-lru==2.3.0 \ + --hash=sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6 \ + --hash=sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315 # via jupyterlab async-property==0.2.2 \ --hash=sha256:17d9bd6ca67e27915a75d92549df64b5c7174e9dc806b30a3934dc4ff0506380 \ @@ -242,28 +247,28 @@ atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonlines # jsonschema # openlineage-python # referencing -azure-core==1.38.2 \ - --hash=sha256:074806c75cf239ea284a33a66827695ef7aeddac0b4e19dda266a93e4665ead9 \ - --hash=sha256:67562857cb979217e48dc60980243b61ea115b77326fa93d83b729e7ff0482e7 +azure-core==1.41.0 \ + --hash=sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d \ + --hash=sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a # via # azure-identity # azure-storage-blob -azure-identity==1.25.2 \ - --hash=sha256:030dbaa720266c796221c6cdbd1999b408c079032c919fef725fcc348a540fe9 \ - --hash=sha256:1b40060553d01a72ba0d708b9a46d0f61f56312e215d8896d836653ffdc6753d +azure-identity==1.25.3 \ + --hash=sha256:ab23c0d63015f50b630ef6c6cf395e7262f439ce06e5d07a64e874c724f8d9e6 \ + --hash=sha256:f4d0b956a8146f30333e071374171f3cfa7bdb8073adb8c3814b65567aa7447c # via feast (pyproject.toml) -azure-storage-blob==12.28.0 \ - --hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \ - --hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41 +azure-storage-blob==12.29.0 \ + --hash=sha256:2824ddd7ebc9056034ebc76b17971a38e9aa5835abb0d565b9700493f2a6c657 \ + --hash=sha256:ccf8a1bcd5e49df83ab85aab793b579e5ba2eeea2ad8900b2f62ca3a37dc391f # via feast (pyproject.toml) babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ @@ -342,73 +347,79 @@ beautifulsoup4==4.14.3 \ # via # docling # nbconvert -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -bleach[css]==6.3.0 \ - --hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \ - --hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6 +bleach[css]==6.4.0 \ + --hash=sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452 \ + --hash=sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081 # via nbconvert -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +blinker==1.9.0 \ + --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ + --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc + # via flask +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # moto # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # moto # s3transfer # snowflake-connector-python -build==1.4.0 \ - --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ - --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 +build==1.5.0 \ + --hash=sha256:13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f \ + --hash=sha256:302c22c3ba2a0fd5f3911918651341ebb3896176cbdec15bd421f80b1afc7647 # via # feast (pyproject.toml) # pip-tools # singlestoredb -cassandra-driver==3.29.3 \ - --hash=sha256:064bf45d3ca87239e11168c0110676fc64f7fdbddb4bcba9be787b8ad5f6d734 \ - --hash=sha256:0785f6e0986089e922378ae3b64b5f696440aeb595fb84c2cf3ccef220c6ae91 \ - --hash=sha256:158f7e5cb894a76a592aa0ca659a8e7c2a57ef603e04c07bbbc289a70e9ac893 \ - --hash=sha256:1c241ba08473baf31a333feb59793190d01625541c2368d3bbb0f43a586f1d6a \ - --hash=sha256:26013d768b2ea4728c09144b08c0eb86ad692e85cb15f4e52e3107abca83683c \ - --hash=sha256:27adf8869937461ad08c5fefb47857532e467b408db496db4dbf8b132a4bd623 \ - --hash=sha256:281f67af1b8df88741eef551afbb49f78e4f366a7ab23e7060a1f0d6ba655752 \ - --hash=sha256:29fc241475801872dc27c3dd1a3976373536223dd4fd1c01868ff86bdbbfd48b \ - --hash=sha256:2b72312a8b62a905da6133effbba9b0731c8e30af96e10ca77fc5c34532c6827 \ - --hash=sha256:2cb72808dfc46c40a6ee352ace181ce3170adde1cfd1447da91709a8cf482e20 \ - --hash=sha256:38216e13d6f2e0d4513a5b8806e70ce4a8f28a82962793a67371582fc2c7141b \ - --hash=sha256:3f654b01d8d49f68deedfaff1edcff314e3103d29130b2a034df6c490c522351 \ - --hash=sha256:51d6a5390e2454b599500049f0a5c72aa701db155c1e542f9a1157c1c45814b1 \ - --hash=sha256:54afde4aaa5b55fbc2c075e1c55fb14a5739459428f3bb81f849ad020f7d5bcf \ - --hash=sha256:572bd5a01089ab92da12f4f52b32b878547bbc544a798d8cfd042e7fc2601c75 \ - --hash=sha256:5a0113020d86e8f61c7a2ae3d508720cd036df7462a55926b85dd97ada27e143 \ - --hash=sha256:5f9858b5ccdf75dd89c20d74474b59dd3a2e2f86c7251b310011c46acdef3874 \ - --hash=sha256:638047c1f70fb14c9d8f743931d4f4f42aff6793b47afded3097c002ef8c1165 \ - --hash=sha256:63adca0f9219be3fe8789f4aa7b77c5f6a7bf65d6442959db52c653140ca4185 \ - --hash=sha256:7552fb7189acd06161f8feac7045a387dc9e03b3b9f7dcb5675178906cee792e \ - --hash=sha256:7a2f371af54cd1d153ef373a733889ebfbcc9c30e00429fc12a2569bad9239e1 \ - --hash=sha256:84b24f69a7bbe76302330d47422a7fcc1998a6a96ffd414a795d7d95992b49cb \ - --hash=sha256:891a1b6a111a591ad9f1c9e088846848dc9e6be030a6086c8c3aa5d2d837f266 \ - --hash=sha256:96ad742f5cbfb771df512959ab5de36e248ce9aa2c487fd81c37d5c0a627c094 \ - --hash=sha256:9abedc832e9a6636741299aae46c032d8c1248b507d8cebbaa2f48ec202904bc \ - --hash=sha256:9b7032b44769c454e96aa11483bfd167a87ea341268f1075b0ff84f780c910a9 \ - --hash=sha256:c935431682557ffcd3efc1c7bcb01b0f6769a1c90751a7154d5e3c905a6a2042 \ - --hash=sha256:e1d09691d757f5b1900a98cc3b6cc7d8506683a2188c01eca86545f91edbbaf5 \ - --hash=sha256:facd488c2b9be8bffcad5903566581e96d2863d2ec4bcad7f114d1b2b2f39ad0 \ - --hash=sha256:fcf45725ae1751cb934b9b827a7d9cd899bbd09eb1ad28e2160b4584de35ba77 \ - --hash=sha256:ff6b82ee4533f6fd4474d833e693b44b984f58337173ee98ed76bce08721a636 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via + # mlflow-skinny + # mlflow-tracing + # pymilvus +cassandra-driver==3.30.0 \ + --hash=sha256:0c28a8e84917acebecbaed39844047c2f135739c3627dd7b9f8541af33e11df3 \ + --hash=sha256:0f4225082a11d9529416c223553ab38a29c4e65da6646b40159c554480dc002c \ + --hash=sha256:136b46437b9902673264e101cdaab309d3e40607bff34430bda86b785badc6e4 \ + --hash=sha256:137498e2a9b6f578d1902e1af8a988e50b8fe134c76a176f1b8a774e906bc66c \ + --hash=sha256:17fb53587c9fc6a27b5c4a89b4f3d9169be43fc572d6f3f67494aa74708be936 \ + --hash=sha256:1d64cbdce764c33e284d339b9a749736d68971edf8b537888f2d13c4b0d1313f \ + --hash=sha256:212af4d8ff934c30538f4bdf7da61f14dc9a30349f6cac2161c8125e56fad928 \ + --hash=sha256:2637644eac9274e46b0c2a7f729158bdf8582b6842dc48e18297211dd3ee1fec \ + --hash=sha256:289e86c81be2543cb9055600c0819850db921e6e138a84e5c88ec160662c7207 \ + --hash=sha256:2a0679ebcfdcecb3763c690b5bc6a517e0c0803f7bc88e0a6c793e5e421b558a \ + --hash=sha256:385134eba72f048707cd800de0a61cf3c23246113edffe9bc6bc2eb86282d26b \ + --hash=sha256:5c6cbb396ad6fe456efc799d3b8b6bda360ffc06552c5be2ce1a88ac381a305c \ + --hash=sha256:61d7eeb17d8f76d5b4a9b1239145250f2a9f7bf949c30e2cc36196b5a0523ce1 \ + --hash=sha256:6a5c8982f2b9eb4e789fc12cdd930b1e1511b6d046dde31d0703f855745556a3 \ + --hash=sha256:6d449f49ce866ac20a1c3d80b1f9245ecdfd1e67b843dccd3d6eccdfe519c02e \ + --hash=sha256:7e4cfd6ec3023576ed0ffa34882d9778e4bacfd918048ae9139ccdd00628ed85 \ + --hash=sha256:83a9148d408a3dbb48ea1802d643d60fa53cd69dc7b9a244511ecf5b917e4f53 \ + --hash=sha256:8c4acd28791854c23ca68be50a7a750c9413ba80fec0ca5c27c2be05f6f3fe0a \ + --hash=sha256:8d5e3575ec01d8c043b56ff25de6f61ff4c9ed5cb3ea4c3d9df98def71ba710c \ + --hash=sha256:923a6e1c3fa5f98f846a028b1a7207ec9e7d8cfa54ea47a507d41122efa2f54f \ + --hash=sha256:c1b4aa6c7706dec839134adb6a2094d90c5f6f35efa08028ed6aae6e67c8643e \ + --hash=sha256:c64e20bf46b49f8ef64569208d4a395b0928c27d5960559922a2d13471924d0d \ + --hash=sha256:d2f9e00127f70dff42d4ef932df8a6b81170c2861d4e75c8b13f4b4816b4450c \ + --hash=sha256:d73c0429813045ba86b92fc033fbcfd495aa10e9d4a40fe30b6e9dfe8b5d3ab4 \ + --hash=sha256:e12dfcd3f0074c16f4bfe650242edb406b935864373ae86160e09e3f5e437e84 \ + --hash=sha256:ff2e9fbdc1be54c1d041ea3f7d09812442f334be14bb5ad7aede175544765d25 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # clickhouse-connect # docling @@ -513,203 +524,218 @@ cfgv==3.5.0 \ --hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \ --hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132 # via pre-commit -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.2.1 \ - --hash=sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202 \ - --hash=sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask + # flask # geomet # great-expectations + # mlflow-skinny # pip-tools # ray # typer # uvicorn -clickhouse-connect==0.13.0 \ - --hash=sha256:0f7223ccfc24394e24c6376c32f63325e3eb56df7e0a7e3e7b23040d7a73e180 \ - --hash=sha256:170e39ef6d76a2da322aa8f06ee4b0f2a91954a9a894b5dbb24e3e0ebaf994ff \ - --hash=sha256:17a6c60fddcc7894245692729fac88769036ae2e9243c45882dcd0234227a1a9 \ - --hash=sha256:18303de2a0058bf594dc7991d5bba95d4258249c80d7c04770cfd410a5238924 \ - --hash=sha256:1b2b1258d8fa4e840be929142f0cd60e534d4763c9132d59f1be7bc9529042d3 \ - --hash=sha256:2b8bbf54bd5cb69791201a4cf4fd4c4a677d7e4cc2a6f60c58af6092f715d0cc \ - --hash=sha256:33fd35aa22ef3a5b44a46ef2fc7510723db2bc5b1c466d147da34c2da974fd9c \ - --hash=sha256:4d4266f5bf7f26a00d335de4eaabb74cf7dbf71056ee256673b040ac68378805 \ - --hash=sha256:4fb2394c9300265f2cb9739ae8acc71630b2aa6e53d829706fe3da9a05c26599 \ - --hash=sha256:52ced166cff735db529780d388c3192d8ec4fb09d5e5acf46ed6dc43e9aa5d80 \ - --hash=sha256:56bb65b08bb40e0c356559666a47c164e55266181601367f8165524052019079 \ - --hash=sha256:56edc95c954e14ec4d5360ee93382566a48c7f00196c4b8d75d5f4874f93c730 \ - --hash=sha256:5a1a654db64fca213920c2dc07524a99b8ecab64f1c0dca321c9f389694dc5af \ - --hash=sha256:5a5e58fb3229f06fb0c60a9e893cda1d181e21ff2e31fb8c51641dd035d12c34 \ - --hash=sha256:5c4ea58b450a0815a85550ce6e10b7ed9a6e0b902bf4d97286c9cf73f9692e4c \ - --hash=sha256:7121fa8c80554dc3facc65c930e04e43033e7fa5d7fc3359e2c0d85c39854d58 \ - --hash=sha256:7322aec94c8e337a6cb120c806fa13b8fd9b1286c89ed755b2cfa9937953f2ed \ - --hash=sha256:746254b0c6c97fc912f0b4b11909d4576b57db614fbc408cfcc45804474fb7de \ - --hash=sha256:804c4be52695ddd8a87b870bbab38dc071f5bf33bbe29566d4378321dbc67d04 \ - --hash=sha256:8569a33c5c884da1c8442172603f1376871876e726d0b679901834e767918ad4 \ - --hash=sha256:859d58c8f0ddc632885ee206bf96e27f02cec6e985995d77f18a458929cd808a \ - --hash=sha256:8832c907756b8564f3b9cdc1a41c22cddcb69801613eefd15b2a9eea2e40ed53 \ - --hash=sha256:8d4283d6e8a41ebbd304574f2da2773c74e12b6e9fd32ed2ea133494e4f6ca7e \ - --hash=sha256:913a53f6b0d948b60fbafe5cb5ae2c10fc2347cf0e17917c842223e571bdbaa5 \ - --hash=sha256:974b0800656b372aa001c9e0fd958a4b43086e4650bbc571aaed3993607bdc69 \ - --hash=sha256:97d00f52f7611ff2e7a0b58d8e3cb0ea470dcbfc56ac6469163c36e4caf7d14c \ - --hash=sha256:993eb2887b01a9714da4d68c1b8c97d91e267ba5510374955c0dc5ae34554923 \ - --hash=sha256:99f198ed4cb99924cc80b69270a4fea1f25cde8cf2f6fb26fde4f9ac9e99cc97 \ - --hash=sha256:9ff33742d7380a1b072e19f84ae9dd7863ae00483731f3a5ff3b18cdcc9a60e9 \ - --hash=sha256:a373713c1f2c3964474cdfc69cff29090ead1d142c41c6fa8cda3ab34dce2916 \ - --hash=sha256:a4712c2ce29f70c1f194f3f92c98169d600390f288295271c6eb0feda8b24548 \ - --hash=sha256:a668810f0b670d7c284c119100af019a3e405cd3d61e08a4a2dff3ecea802c4d \ - --hash=sha256:ae8b308a34b4c6b1e0d77c977a46fbd2841d926bedea37f57618c4dd6cef636d \ - --hash=sha256:af5a6e924111b2fa4e6c17d7425f842f54fb2a014ad7a793a91462dccbdbca4e \ - --hash=sha256:af703d0477c081e2d32297abf8af2fe9aa61a9aa818b1f3b7a473de9c58d822e \ - --hash=sha256:b11ae56992f7d972692ae4d38e79de2a52333a5e38a55a144fb47f644b921cc5 \ - --hash=sha256:b1b0c92c91f2f3d0f2422d1c938af221abad2d6fda50bb4c816ebac373d5ddf1 \ - --hash=sha256:b5a2eb5851dfd8469d4b6253f5ec4666fb9fba018b47ac35d15fa2bca62b4979 \ - --hash=sha256:b60b54ffbbd65a630bc551fa979bfa47f0ca3dceeccd6ebdc043c66b30eed714 \ - --hash=sha256:b7f4cdc2b34f7b88e4c96c3e13a2574732c3bd6c21a6b2b2ab2b1fc3914301f1 \ - --hash=sha256:b9ae5a28c511e7680224f868acd461f7cd3d8793ea8545f22bafb71d4235b663 \ - --hash=sha256:bb8e8d508ff0331e34aef747d0cf5748ca0736e982c785b4aa08fca984459db5 \ - --hash=sha256:cc9781d0fdd31108d1c707cd3c3b7e50f97f819c6dc10d71b86c2d3bb6b83a49 \ - --hash=sha256:ccbb7d8e43904074eb66ac99dd58750b4d68501d2e794169ca8e3b27ba6c35db \ - --hash=sha256:d30ce9f85033325ab042e9f515dc2d9375fd972f71169d46181bc41ede77305b \ - --hash=sha256:d7756cac9afa4dde22549f271b3bbf6739f4f4a533e45f1ffc3faaaf87086371 \ - --hash=sha256:d7a574b53d41769e352a149fe52904859ffccd423cf11c69dc21938ff94235e7 \ - --hash=sha256:d96fb3c6912cd570b37a4de5e93cc7528afe56f10e5d8f33ed8c7a26fe24e7d1 \ - --hash=sha256:dbc8871ead7d06db00980bd6d59d899add80b0184e52b33a14ed23ac4a8109ea \ - --hash=sha256:dcc6c5106b436cb63af4b47b22dd75f38497e61857b3fefb2226562040884a5b \ - --hash=sha256:e04d4b11b54e33d12218add69a6eac2d4fa3262b522489663ab948c08eb27f1f \ - --hash=sha256:e2267b41e69203e334761f28f1102ad47d3ff218e565b06b215b61f1f62e4171 \ - --hash=sha256:e449006b1606e22822695c85d4fc1faf3c1d0a5a3622d4b8fc28bfa014dbb295 \ - --hash=sha256:e72aded5dbb2e2fa8d6a2d70ef061556ff94baec3eca8b800c45e103507aa90f \ - --hash=sha256:ed741ab68b6226669f3b09fc663710764b985f83c0c9f753a8ae98276893284b \ - --hash=sha256:efa3d8d968e66ef0fe79fc880b824368787329e63b61feab86194e113a7795ff \ - --hash=sha256:f0c9efea902187f1de351bc32995d08d1f1f27350798508f8a6c238ecac4ccb0 \ - --hash=sha256:f1ee372499dfa784653cba035df6a6b12ed67c74c8c42ace13c3af99db4491f0 \ - --hash=sha256:fa9ef035faaa60f06470b15f6c1912b4b402b03dc9d4de07d445b9e817c933f0 +clickhouse-connect==1.1.1 \ + --hash=sha256:0b602967810358408ebd55693fd582f3a20e08800f721fb72ae320f0f74686ff \ + --hash=sha256:0bb2c8f82bb2bd5f645c0114d5d766a95dc1e0dec33c07deafa5a68dbb75f898 \ + --hash=sha256:0e9e294601aac4de51ac7cd2423176fe5111da41b5d120047606eb855795853c \ + --hash=sha256:0ec2f574530c65412a490ac6a29445509ca6346dbb15d39a825e27c73d680f3a \ + --hash=sha256:10055ae880742ffc61244eb129bbbafa6fe97731aa959d717b16513b5094255a \ + --hash=sha256:10c0354b858f500f4f26195dc37cd6047eb4d324b0b08ca6873e2241ea4a2ea8 \ + --hash=sha256:11ca173d36405d446f97dfea0a3e1531389d90d23c686ec18ebcbc0eed17200e \ + --hash=sha256:1284cb2a73b6af208aac06ad04d9121a8aa33f4b971b9d5a65264d2137b5cf0f \ + --hash=sha256:1781f330cd0678b203dc35d5df85c3b212577412c0dcf664432edbfc71a20489 \ + --hash=sha256:1e2b000c55e698220cba80e660349c60d7acb3b82172c320a51519d191e24826 \ + --hash=sha256:22ed08e9a361e1d21762c68275610ee0e023f281fe9a1653763b62fc5585a6f0 \ + --hash=sha256:233cc6eae3dbec122ed7ff694f657aa9676b36c2acbcef64e97166e4f75f5040 \ + --hash=sha256:27b665a01711e9a5b08e4412d501baf76ce4ccbeb937ec67e73040094492adbc \ + --hash=sha256:2913a4c96c3aede2b39489731eb8c39e37792755df9b56548b162ab1e09df4f3 \ + --hash=sha256:2c9a1bdb1d9705a270ec8036cd89113db04f4437a4d3b5db0774312ec4d06e30 \ + --hash=sha256:3cdae5ce54cc7d5fdaced13857612b25ae58f0830987a4b17ebcf376d71df3b2 \ + --hash=sha256:43e1fb7d588a799a3e55a4982946d59484edf1e960abc9e7ac330a3330ee4fc5 \ + --hash=sha256:49cb0d82e3f68d7304275bf350419095c080ddd49f99704dd44a956273fa7c09 \ + --hash=sha256:4f0c6c52245322c04bdccc71565ac8db9731e1787c90665df9167928101f0b89 \ + --hash=sha256:4ff227719006516877b5152e89cba514ceee9807e6b030a1ddba8d9355b87412 \ + --hash=sha256:6062c400d67dd4ab03fc3f9473134fc0a240593c242998d032d32cb04a65f083 \ + --hash=sha256:646408372c2a4b0e4068145897a35100cefc6974a409c68b20ba22403665fe5a \ + --hash=sha256:68d6e245db80ea42c59c32dbed655f28e82337d61405dde6aa5e009c507a6eee \ + --hash=sha256:70b9dee3c4629e06f2b5788d02b6cded0a32d2509966bc293cf1c39abc395a29 \ + --hash=sha256:763f7fabc921ee9fb4c07d180447a6324980bfeb981c3f53065d04bda5f133b7 \ + --hash=sha256:770da683bf65d3536c46d564e5a9311d6cd40d191a0357a762ac702813774965 \ + --hash=sha256:784a1c9513a33f6f8df0c260e43ea5cdc5fde0a2c91bca7e69ce26bc4990abcd \ + --hash=sha256:7fb296b2c51e5ad8d7f677a08a093b3b122cd4411619678a968567f3b34bf075 \ + --hash=sha256:8857676711197c981afc317a38ad1b92aedcf81b7052e67098f40adcf4b5d4ba \ + --hash=sha256:8b0590065a4c6551d1145229adf3405befc053843f6b1ffeb3802ae7221d53dc \ + --hash=sha256:8f2f9029f6589d2d349912a94a17d9997c550a7f19dd5b747f6b452764dc0e54 \ + --hash=sha256:92d885943b1b0a1489501408d6af91ec2d96189dbc475f3552f22cd43c9c6270 \ + --hash=sha256:9de3999bad13146823e9c6811dbe9a66653bf5c71980472f8fe5165d186451ee \ + --hash=sha256:a4639a1c6291358a0dd40ba0a6a6059eb5fcc9acd6f4cd61eb52b3cb5165d37e \ + --hash=sha256:a4740e012dc4ed2fab769dba4b13be92142e2df2bfb0de547b0b73f13296bcb8 \ + --hash=sha256:a6c0a8f1c4e4954161051b26bee8d24f1e53254125d2bf6e18c9360cd41fe059 \ + --hash=sha256:a706631a540ac21aac4434a446d50263c0872c9507bc6a0ccfb51467c0ff74a4 \ + --hash=sha256:ad6b32a1bb391f15345c6af4ecee152e04362c6331cd93472f2fa5e64f8a9aaa \ + --hash=sha256:b1e83e71d5b0df09cb807657ab0457eb1fd116a331039d3c5d3051387092ff6a \ + --hash=sha256:c336452cd5aeada902ac41d57296498766f95a175cb1dcf13d48479b5b31ac6b \ + --hash=sha256:c54bdd8870a644a9baa7cd68fdfc5100f5b19aa246657be863788a6a7bf4052e \ + --hash=sha256:ca28e361a51afe2e7e2fcff47c1423fd61271d26af7d19e37f6ff0ab67bf086f \ + --hash=sha256:cd501e3ccee60d4cccf5cde4b4c92632b62763563b08aa07dbfd3e2583c12005 \ + --hash=sha256:d1df245b5c21fa7bd70193164cc97f3937ccee3087dbc7906daf2e97b226b2a8 \ + --hash=sha256:d3b3806986340192ed2b197241be193649717cc58f7ef9bdf86d119758289a0f \ + --hash=sha256:d4a5e4b36219d678d495120007d0ba8b7d1bf4c5105292b35fa4473038fc2892 \ + --hash=sha256:d749389301b201ae7329c8fc96599fc116de8aadc16a5a4416e399483c569ea9 \ + --hash=sha256:d84c8ed4cc26976d2cc6725e36b85d4e24f1c43c11d82483b3060116ac0bcfd4 \ + --hash=sha256:dcdfee2f707225bfbd80ba2da5c995a38393aa02920adf770264c6f5b041e9ed \ + --hash=sha256:e762f70ebf57cb43a6257daa6196f5beb574d69915dd06c29735d5811dfd8dce \ + --hash=sha256:ee7d8308c8a688c6851b19d2bc743a02ed5d6f8679203a13872a80cf4066dd57 \ + --hash=sha256:f205be896551d7ea0a0140a86e36d261e249f99541d68a3dfdd47dd8c7c2bbbb \ + --hash=sha256:f552668320b8c533b6f2b93d03dd4840cfe0e8f5f01c76ea0d2989e4127fa60e \ + --hash=sha256:f75e0d62bdb53ba72fa2aa962950c5c107627158c9fe8900ca14da557295bdb2 # via feast (pyproject.toml) cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ --hash=sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a - # via dask -codeflare-sdk==0.33.1 \ - --hash=sha256:6622a73edde5042455ae7d76279a5279c55db4950533ea7f12aac2fc51d49bb8 \ - --hash=sha256:ad41ec5260217fd030904fb4b9fe62e26c3f51ac7999a5d607eb4b1359edd5e5 + # via + # dask + # mlflow-skinny +codeflare-sdk==0.37.0 \ + --hash=sha256:2106118d9341db7e329da59f296bc635c08e365d4a644013bb9a55ce38c54da5 \ + --hash=sha256:a5f86b9541a3ef2498bc920465b0e106c4e58bfa2004d14ff177f83761afd469 # via feast (pyproject.toml) colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ @@ -727,6 +753,80 @@ comm==0.2.3 \ # via # ipykernel # ipywidgets +contourpy==1.3.3 \ + --hash=sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69 \ + --hash=sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc \ + --hash=sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880 \ + --hash=sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a \ + --hash=sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8 \ + --hash=sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc \ + --hash=sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470 \ + --hash=sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5 \ + --hash=sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 \ + --hash=sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b \ + --hash=sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5 \ + --hash=sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 \ + --hash=sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3 \ + --hash=sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4 \ + --hash=sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e \ + --hash=sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f \ + --hash=sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772 \ + --hash=sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286 \ + --hash=sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 \ + --hash=sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301 \ + --hash=sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77 \ + --hash=sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7 \ + --hash=sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411 \ + --hash=sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1 \ + --hash=sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 \ + --hash=sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a \ + --hash=sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b \ + --hash=sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db \ + --hash=sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6 \ + --hash=sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620 \ + --hash=sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989 \ + --hash=sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea \ + --hash=sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67 \ + --hash=sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5 \ + --hash=sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d \ + --hash=sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36 \ + --hash=sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99 \ + --hash=sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1 \ + --hash=sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e \ + --hash=sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b \ + --hash=sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8 \ + --hash=sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d \ + --hash=sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7 \ + --hash=sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7 \ + --hash=sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339 \ + --hash=sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1 \ + --hash=sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659 \ + --hash=sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4 \ + --hash=sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f \ + --hash=sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20 \ + --hash=sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36 \ + --hash=sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb \ + --hash=sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d \ + --hash=sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8 \ + --hash=sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0 \ + --hash=sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b \ + --hash=sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7 \ + --hash=sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe \ + --hash=sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77 \ + --hash=sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497 \ + --hash=sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd \ + --hash=sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 \ + --hash=sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216 \ + --hash=sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13 \ + --hash=sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae \ + --hash=sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae \ + --hash=sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77 \ + --hash=sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3 \ + --hash=sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f \ + --hash=sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff \ + --hash=sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9 \ + --hash=sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a + # via matplotlib couchbase==4.3.2 \ --hash=sha256:032a180afd6621358b2c73543b9c5db9939b442fc3ad6d54417c36c8a8f65838 \ --hash=sha256:11ce688ed46edf8387bf51866618c7b4e06399e7fb34a6df002764996c109d1f \ @@ -793,142 +893,164 @@ couchbase-columnar==1.0.0 \ --hash=sha256:fc0fad2d386c5b5df7aaaccd8751e01caa886cc640cc8c92523dd07c4e7be519 \ --hash=sha256:fc4efa3e15190c3731478006de494b046bc57785e9c8ae99ac8b375a91683e38 # via feast (pyproject.toml) -coverage[toml]==7.13.4 \ - --hash=sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246 \ - --hash=sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459 \ - --hash=sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 \ - --hash=sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6 \ - --hash=sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415 \ - --hash=sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf \ - --hash=sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80 \ - --hash=sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 \ - --hash=sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0 \ - --hash=sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b \ - --hash=sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9 \ - --hash=sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b \ - --hash=sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f \ - --hash=sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505 \ - --hash=sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47 \ - --hash=sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55 \ - --hash=sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def \ - --hash=sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689 \ - --hash=sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012 \ - --hash=sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5 \ - --hash=sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3 \ - --hash=sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95 \ - --hash=sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9 \ - --hash=sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601 \ - --hash=sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997 \ - --hash=sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c \ - --hash=sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac \ - --hash=sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c \ - --hash=sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa \ - --hash=sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750 \ - --hash=sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3 \ - --hash=sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d \ - --hash=sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12 \ - --hash=sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a \ - --hash=sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932 \ - --hash=sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356 \ - --hash=sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92 \ - --hash=sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148 \ - --hash=sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39 \ - --hash=sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634 \ - --hash=sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6 \ - --hash=sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72 \ - --hash=sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98 \ - --hash=sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef \ - --hash=sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3 \ - --hash=sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9 \ - --hash=sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0 \ - --hash=sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a \ - --hash=sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9 \ - --hash=sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552 \ - --hash=sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc \ - --hash=sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f \ - --hash=sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525 \ - --hash=sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940 \ - --hash=sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a \ - --hash=sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23 \ - --hash=sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f \ - --hash=sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc \ - --hash=sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b \ - --hash=sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056 \ - --hash=sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7 \ - --hash=sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb \ - --hash=sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a \ - --hash=sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd \ - --hash=sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea \ - --hash=sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126 \ - --hash=sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299 \ - --hash=sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9 \ - --hash=sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b \ - --hash=sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00 \ - --hash=sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf \ - --hash=sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda \ - --hash=sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2 \ - --hash=sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5 \ - --hash=sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d \ - --hash=sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9 \ - --hash=sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 \ - --hash=sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b \ - --hash=sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa \ - --hash=sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092 \ - --hash=sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58 \ - --hash=sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea \ - --hash=sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26 \ - --hash=sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea \ - --hash=sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9 \ - --hash=sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053 \ - --hash=sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f \ - --hash=sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0 \ - --hash=sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3 \ - --hash=sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256 \ - --hash=sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a \ - --hash=sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903 \ - --hash=sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91 \ - --hash=sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd \ - --hash=sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505 \ - --hash=sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7 \ - --hash=sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0 \ - --hash=sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2 \ - --hash=sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a \ - --hash=sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71 \ - --hash=sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985 \ - --hash=sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242 \ - --hash=sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d \ - --hash=sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af \ - --hash=sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c \ - --hash=sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0 +coverage[toml]==7.14.1 \ + --hash=sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86 \ + --hash=sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd \ + --hash=sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d \ + --hash=sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5 \ + --hash=sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42 \ + --hash=sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de \ + --hash=sha256:10274a1fbeb8ec5d72966e17bb198a3104257aca4ac09d98667c5f8aca8c8548 \ + --hash=sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1 \ + --hash=sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7 \ + --hash=sha256:1238cb94638e610e972c60dac68e813f868dc7d6e982535270558443058d9d59 \ + --hash=sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906 \ + --hash=sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af \ + --hash=sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1 \ + --hash=sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d \ + --hash=sha256:196a13319ad88d6d8ef5ab489ec4f44ddde2143c0c7d5b27786f6c3ffd56a7e1 \ + --hash=sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be \ + --hash=sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02 \ + --hash=sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42 \ + --hash=sha256:23bf7fa51ac02e07fc7c96849b82946da47ae862dc8f86d183b2a4864fc38129 \ + --hash=sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e \ + --hash=sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be \ + --hash=sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e \ + --hash=sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65 \ + --hash=sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54 \ + --hash=sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1 \ + --hash=sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5 \ + --hash=sha256:3a56abc20a472baf0304c455721bc601477440d28ecfde8a03dde79ede07e0df \ + --hash=sha256:3c18ebc343e15be53049b3a2dce38fe82d58f37e20ab9094b3a39c0aa4f6bb47 \ + --hash=sha256:3d452fd08b5c72c5167c93e6867b5c08500bd40f2a21e1e854a500550b6cc36f \ + --hash=sha256:3e3680291c4a1d0dadfa84a2c459576a4af5133abb617905714339a0c73138cf \ + --hash=sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37 \ + --hash=sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4 \ + --hash=sha256:478b5bcd63c2e1357c5c7e16c070690df7b07f676b1c114d7b93e533c664309f \ + --hash=sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84 \ + --hash=sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1 \ + --hash=sha256:4ea1c034f95c9b056e856b794630b17f9fa3d57e4800ff1e503d3be0f9c9078c \ + --hash=sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8 \ + --hash=sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e \ + --hash=sha256:59baf88468dbc8d63b1887afd92bda52e40bb1561696e5819670601403810cec \ + --hash=sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d \ + --hash=sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54 \ + --hash=sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890 \ + --hash=sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b \ + --hash=sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d \ + --hash=sha256:62a9f70b52e0b5a95cfef4a5c5641b06983cadc5e538a3feeb5c00211f523ac2 \ + --hash=sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33 \ + --hash=sha256:6a3cb83d1552c0cd1b4906655b6a33fd4a8473229633a901c6b73bf86914dee9 \ + --hash=sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e \ + --hash=sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6 \ + --hash=sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce \ + --hash=sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247 \ + --hash=sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901 \ + --hash=sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36 \ + --hash=sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69 \ + --hash=sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416 \ + --hash=sha256:7f02d09f70776579b926d889a4c9c235070a1f47c40458aeaca563fae5acfdb5 \ + --hash=sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500 \ + --hash=sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad \ + --hash=sha256:84ac9499e48700399a5dd0ea7085b5091961fec52c68d66b4ec0d3cf7f4441b1 \ + --hash=sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b \ + --hash=sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b \ + --hash=sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a \ + --hash=sha256:87ebdf787d4888e3f3f2d523eadc6e18c6d18c6d0eb173801a189641627fb37e \ + --hash=sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee \ + --hash=sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07 \ + --hash=sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a \ + --hash=sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d \ + --hash=sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c \ + --hash=sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343 \ + --hash=sha256:a24a81f9715ee42ef59a316cc11611c98fe23920f7c81861315c9f3ff4a230f4 \ + --hash=sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2 \ + --hash=sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8 \ + --hash=sha256:a5274669f37f2343635a347b91a60777621341ab3378e9c6ac9335eee704bddf \ + --hash=sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb \ + --hash=sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c \ + --hash=sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff \ + --hash=sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e \ + --hash=sha256:b84ffdf877644e7096aa936991efeed873f7f3df57b9cd001312b7668ab08550 \ + --hash=sha256:bcaa50684dcaadfa599ac48f81103c756d791cfd85c97203d2217c593d48b860 \ + --hash=sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793 \ + --hash=sha256:c643734307300234fafa36bf2a040a7235f8f177ea1fd6ec1423aea6fb7b929f \ + --hash=sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851 \ + --hash=sha256:c7e057326434e441306226fbeb5d1aaf14a2637efe97ba668306635835f32ad7 \ + --hash=sha256:c912c259304cfb5ee584481cfb7ce1ff932b4d61e6c9140b8f19cb7b5ed82332 \ + --hash=sha256:ce66d8e46da2bb5ee313a745cbd2e391d319176c1f7a9451bfcd3a2fb920859b \ + --hash=sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2 \ + --hash=sha256:cfe5a5fec635799ef33428f1e5e61bafa45a92a96190ba731561ba558ccc214d \ + --hash=sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a \ + --hash=sha256:d34d75f892b3ab73ba11cab5442cce7b3e168fd64162b16f0e1e0d09c508edef \ + --hash=sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474 \ + --hash=sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee \ + --hash=sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43 \ + --hash=sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034 \ + --hash=sha256:dd34767fa19848d35659ffc0a75314f58c7af3f1cd87ec521e8292a1238398a3 \ + --hash=sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c \ + --hash=sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d \ + --hash=sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7 \ + --hash=sha256:e854312c4103f2ad4c0dc023b69b77ebfd2c89db5f86c4c94dc2353f9a92167e \ + --hash=sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d \ + --hash=sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4 \ + --hash=sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9 \ + --hash=sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52 \ + --hash=sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a \ + --hash=sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c \ + --hash=sha256:fc459e5d73be2d6332fcfe8dbf3d8994671fe33c700f4565988ecfa511547253 \ + --hash=sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c # via pytest-cov -cryptography==43.0.3 \ - --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ - --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ - --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ - --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ - --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ - --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ - --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ - --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ - --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ - --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ - --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ - --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ - --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ - --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ - --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ - --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ - --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ - --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ - --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ - --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ - --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ - --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ - --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ - --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ - --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ - --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ - --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 +cryptography==46.0.7 \ + --hash=sha256:04959522f938493042d595a736e7dbdff6eb6cc2339c11465b3ff89343b65f65 \ + --hash=sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832 \ + --hash=sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067 \ + --hash=sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de \ + --hash=sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4 \ + --hash=sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0 \ + --hash=sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b \ + --hash=sha256:3986ac1dee6def53797289999eabe84798ad7817f3e97779b5061a95b0ee4968 \ + --hash=sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef \ + --hash=sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b \ + --hash=sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4 \ + --hash=sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3 \ + --hash=sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308 \ + --hash=sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e \ + --hash=sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163 \ + --hash=sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f \ + --hash=sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee \ + --hash=sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77 \ + --hash=sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85 \ + --hash=sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99 \ + --hash=sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7 \ + --hash=sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83 \ + --hash=sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85 \ + --hash=sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006 \ + --hash=sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb \ + --hash=sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e \ + --hash=sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba \ + --hash=sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325 \ + --hash=sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d \ + --hash=sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1 \ + --hash=sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1 \ + --hash=sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2 \ + --hash=sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0 \ + --hash=sha256:d02c738dacda7dc2a74d1b2b3177042009d5cab7c7079db74afc19e56ca1b455 \ + --hash=sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842 \ + --hash=sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457 \ + --hash=sha256:d3b99c535a9de0adced13d159c5a9cf65c325601aa30f4be08afd680643e9c15 \ + --hash=sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2 \ + --hash=sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c \ + --hash=sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb \ + --hash=sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5 \ + --hash=sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4 \ + --hash=sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902 \ + --hash=sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246 \ + --hash=sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022 \ + --hash=sha256:fc9ab8856ae6cf7c9358430e49b368f3108f050031442eaeb6b9d87e4dcf4e4f \ + --hash=sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e \ + --hash=sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298 \ + --hash=sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce # via # feast (pyproject.toml) # azure-identity @@ -937,6 +1059,7 @@ cryptography==43.0.3 \ # google-auth # great-expectations # jwcrypto + # mlflow # moto # msal # oracledb @@ -946,59 +1069,69 @@ cryptography==43.0.3 \ # snowflake-connector-python # types-pyopenssl # types-redis -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +cycler==0.12.1 \ + --hash=sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 \ + --hash=sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c + # via matplotlib +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.6.1 \ - --hash=sha256:140ce500bc41939ff6ce995702d66b1f4b2ee7f117bb9b07512fab6804d4070a \ - --hash=sha256:f53228e6dadc9f837037b1bf3051d7d8c054abbb3eb29f1f022926e08090e0da +databricks-sdk==0.114.0 \ + --hash=sha256:25a40b83d76fa6c8a621f884da41e45e3ae5267218dafa71db9b363dd9238f57 \ + --hash=sha256:d62e6fcb1dc98b0b390d369261d1d68a6cf9f91139c34cf659865faf50b1d044 + # via + # mlflow-skinny + # mlflow-tracing +datasets==5.0.0 \ + --hash=sha256:7dd34927a0fd7046e98aad5cb9430e699c373238a15befa7b9bf22b991a7fee6 \ + --hash=sha256:83dbbbdb07a33b82192b8c419deb18739b138ee2ce1a322d55ce6b100954ec1a # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.12.0 \ - --hash=sha256:3db93df7969c3f22c6fbf75a51b0af4c21b189d8db6f3c54e8471102c775bb0d \ - --hash=sha256:9d1c0ed41926102c1c39fdd780e1a332f58c9b794e94dba0dcf5dfefc847d6ea +dbt-artifacts-parser==0.13.2 \ + --hash=sha256:9eca1e413f7eee522cc1556634b0b9effe790b70d8ffcc46ae2328b9868efaf1 \ + --hash=sha256:abb798aa73ff8cc295b4ecf03ee02d6a3bc48ad79f7d093d4bb3ffef68e77fb4 # via feast (pyproject.toml) -debugpy==1.8.20 \ - --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ - --hash=sha256:0dfd9adb4b3c7005e9c33df430bcdd4e4ebba70be533e0066e3a34d210041b66 \ - --hash=sha256:157e96ffb7f80b3ad36d808646198c90acb46fdcfd8bb1999838f0b6f2b59c64 \ - --hash=sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb \ - --hash=sha256:20d6e64ea177ab6732bffd3ce8fc6fb8879c60484ce14c3b3fe183b1761459ca \ - --hash=sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f \ - --hash=sha256:3ca85463f63b5dd0aa7aaa933d97cbc47c174896dcae8431695872969f981893 \ - --hash=sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390 \ - --hash=sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d \ - --hash=sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33 \ - --hash=sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 \ - --hash=sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a \ - --hash=sha256:60f89411a6c6afb89f18e72e9091c3dfbcfe3edc1066b2043a1f80a3bbb3e11f \ - --hash=sha256:70ad9ae09b98ac307b82c16c151d27ee9d68ae007a2e7843ba621b5ce65333b5 \ - --hash=sha256:760813b4fff517c75bfe7923033c107104e76acfef7bda011ffea8736e9a66f8 \ - --hash=sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec \ - --hash=sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344 \ - --hash=sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf \ - --hash=sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b \ - --hash=sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173 \ - --hash=sha256:9eeed9f953f9a23850c85d440bf51e3c56ed5d25f8560eeb29add815bd32f7ee \ - --hash=sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3 \ - --hash=sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be \ - --hash=sha256:b773eb026a043e4d9c76265742bc846f2f347da7e27edf7fe97716ea19d6bfc5 \ - --hash=sha256:bff8990f040dacb4c314864da95f7168c5a58a30a66e0eea0fb85e2586a92cd6 \ - --hash=sha256:c1178ae571aff42e61801a38b007af504ec8e05fde1c5c12e5a7efef21009642 \ - --hash=sha256:c29dd9d656c0fbd77906a6e6a82ae4881514aa3294b94c903ff99303e789b4a2 \ - --hash=sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393 \ - --hash=sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b \ - --hash=sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7 +debugpy==1.8.21 \ + --hash=sha256:0042da0ecd0a8b50dc4a54395ecd870d258d73fa18776f50c91fdcabdcad2675 \ + --hash=sha256:0fddfdc130ac6d8bfc0415b0409822fa901c8f310e5c945ac5653a0352532344 \ + --hash=sha256:13678151fc401e2d68c9880b91e28714f797d40422994572b24560ef80910a88 \ + --hash=sha256:15d4963bd5ffa48f0da0947fd06757fa7621945048a14ad7705431566d3c0e7c \ + --hash=sha256:2c2ae706dec41d99a9ca1f7ebc987a83e65578363be6f6b3ac9067504917fae1 \ + --hash=sha256:3d6922439bf33fd38a3e2c447869ebc7b97da5cd3d329ff1ef9bc06c4903437e \ + --hash=sha256:4743373c1cac7f9e74a1b9915bf1dbe0e900eca657ffb170ae07ac8363205ae9 \ + --hash=sha256:4e70cc8b5079f885cb43910924ee0aab73b8b6b2a14eff23afdd9895d86e79eb \ + --hash=sha256:4e7c2d784d78ad4b71a5f8cd7b59c167719ec8a7a0211dbb3eb1bfeda78bc4e2 \ + --hash=sha256:72b5d676c4cbfac3bac5bb01c138a4656e843f93f03ce2a5f4e394ad49fbee73 \ + --hash=sha256:84c564d8cc701d41843b29a92814c1f1bef6798724ca9d675c284ad9f6a547d7 \ + --hash=sha256:8eeab7b5462f683452c57c0126aaa5ec4e974ddb705f39ba87dff8818c8e08f9 \ + --hash=sha256:9bb2a685287a2ac9b181cde89edcec64845cb51de7faaa75badb9a698bc24782 \ + --hash=sha256:9f5171176a0084b95d2ebe55a4d1f7b2a75b74c5dbec577ebd3a85c740551c36 \ + --hash=sha256:9f96713896f39c3dff0ee841f47320c3f2983d33c341e009361bb0ebc79adc4e \ + --hash=sha256:a3c53278e84c94e11bd87c53970ec391d1a67396c8b22609fcac576520e611a6 \ + --hash=sha256:a7fe47fd23da57b9e0bec3f4a8ee65a2dc55782455ed7f2141d75ab5d2eaeef5 \ + --hash=sha256:aa648733047443eb1d07682c4ef287d36a54507b643ffdf38b09a3ef002c72a0 \ + --hash=sha256:aa9d941d6dfe3d0407e4b3ca0b9ec466030e260fbf1174094f68785680f66db6 \ + --hash=sha256:b1e37d333663c8851516a47364ef473da127f9caebe4417e6df6f5825a7e9a92 \ + --hash=sha256:bd7ba9dd3daa7c2f942c6ca8d4695a16bf9ac16b63615261c7982bc74f7ed20c \ + --hash=sha256:c193d474f0a211191f2b4449d2d06157c689013035bd952f3b617e0ef422b176 \ + --hash=sha256:da456226c7b4c69e35dbe35dcee6623d912000a77816db7856a41af1c72a0264 \ + --hash=sha256:e935f9dc0501be523c8a8e1853c39432e1354e9ece717ae5998fd2371c4542c3 \ + --hash=sha256:ecbd158386c31ffe71d46f72d44d56e66331ab9b16cad649156d514368f23ab2 \ + --hash=sha256:f15c10084f9861b5e8414a48f18f8e4aadf51a98a59e72c16aa28281ca994672 \ + --hash=sha256:f68b891688e61bdc08b8d364d919ff0051e0b94657b39dcd027bc3173edb7cdc \ + --hash=sha256:f843a8b08c2edeaf9b1582eed4f25441af21a297c22ff16bf76a662557aa9c9e \ + --hash=sha256:fe0744a12353406de0ae8ccff0d0a4a666f00801a3db8fd04e7a5f761cd520e8 \ + --hash=sha256:ffd932c6796afadab6993ec96745918a8cb2444dbd392074f769db5ea40ab440 # via ipykernel -decorator==5.2.1 \ - --hash=sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360 \ - --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a +decorator==5.3.1 \ + --hash=sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82 \ + --hash=sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c # via ipython defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ @@ -1015,6 +1148,10 @@ deltalake==0.25.5 \ --hash=sha256:cb1c7e826fd7c3bdd3676c7471d3b551e1a3674e44cd8e3747a0017a2c0292b7 \ --hash=sha256:e8f0d24bf64455f702da8402307b22e01f91e0f76694f7c5e33c9513011e8d29 # via feast (pyproject.toml) +deprecated==1.3.1 \ + --hash=sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f \ + --hash=sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223 + # via cassandra-driver deprecation==2.1.0 \ --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a @@ -1026,28 +1163,36 @@ dill==0.3.9 \ # feast (pyproject.toml) # datasets # multiprocess -distlib==0.4.0 \ - --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ - --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d +distlib==0.4.1 \ + --hash=sha256:9c2c552c68cbadc619f2d0ed3a69e27c351a3f4c9baa9ffb7df9e9cdc3d19a97 \ + --hash=sha256:c3804d0d2d4b5fcd44036eb860cb6660485fcdf5c2aba53dc324d805837ea65b # via virtualenv +dnspython==2.8.0 \ + --hash=sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af \ + --hash=sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f + # via + # feast (pyproject.toml) + # pymongo docker==7.1.0 \ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 - # via testcontainers + # via + # mlflow + # testcontainers docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.69.0 \ - --hash=sha256:4c3817ce00c7cb5622e59ddb4e5268a58083ae67f6e1436b36a84b6b4bbf6899 \ - --hash=sha256:9760e13063de5f373dbc3417de3ef9a3709c6eb18c0e60ada3c1f96c8b37c14e +docling-core[chunking]==2.78.1 \ + --hash=sha256:7463a2ce3e70590f330cf16dce11a7dbb761ece007a50e9082b44b7fed849820 \ + --hash=sha256:a700d4dc98592e95c05c57ae8d25698f514b8dfbe25e97f36a314f85e9cc0684 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.12.0 \ - --hash=sha256:008fe1f5571db413782efe510c1d6327ea9df20b5255d416d0f4b56cfd090238 \ - --hash=sha256:85c2b6c9dbb7fbb8eaf0f2a462b5984626457a6dc33148643491270c27767b46 +docling-ibm-models==3.13.3 \ + --hash=sha256:50fc83d244ce2dc43158e02155d1caa68374d7a169d0f34e67d7eb14f396ffe6 \ + --hash=sha256:8c8b55e80b3d20fc74d85ca49a4d064578ef75b9f7251eec42fc9df6af426218 # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1082,42 +1227,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1126,13 +1271,13 @@ durationpy==0.10 \ easyocr==1.7.2 \ --hash=sha256:5be12f9b0e595d443c9c3d10b0542074b50f0ec2d98b141a109cd961fd1c177c # via docling -elastic-transport==9.2.1 \ - --hash=sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4 \ - --hash=sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d +elastic-transport==9.4.1 \ + --hash=sha256:186a29e6c66ff269487e33f7b17176316e18b6061702c25eb0bb15681302e91d \ + --hash=sha256:d12c86ea73528690ebf63a488d9ae323292e6aa5ee55e1e29f14293472f4197f # via elasticsearch -elasticsearch==9.3.0 \ - --hash=sha256:67bd2bb4f0800f58c2847d29cd57d6e7bf5bc273483b4f17421f93e75ba09f39 \ - --hash=sha256:f76e149c0a22d5ccbba58bdc30c9f51cf894231b359ef4fd7e839b558b59f856 +elasticsearch==9.4.1 \ + --hash=sha256:1d78fdfba97a903ec35a5eb5808a74e33392b7c620bd5f742d465a3a26c27d75 \ + --hash=sha256:71ab71c3d1b20fd88c2922fb82c3277cce7ea03c160686e7b9368b265c2b4cac # via feast (pyproject.toml) entrypoints==0.4 \ --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ @@ -1146,9 +1291,9 @@ execnet==2.1.2 \ --hash=sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd \ --hash=sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # via pytest-xdist -executing==1.2.0 \ - --hash=sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc \ - --hash=sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107 +executing==2.2.1 \ + --hash=sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4 \ + --hash=sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017 # via # codeflare-sdk # stack-data @@ -1179,12 +1324,13 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp + # mlflow-skinny fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d @@ -1193,9 +1339,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via # datasets # huggingface-hub @@ -1208,6 +1354,68 @@ filetype==1.2.0 \ --hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \ --hash=sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25 # via docling +flask==3.1.3 \ + --hash=sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb \ + --hash=sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c + # via + # flask-cors + # mlflow +flask-cors==6.0.2 \ + --hash=sha256:6e118f3698249ae33e429760db98ce032a8bf9913638d085ca0f4c5534ad2423 \ + --hash=sha256:e57544d415dfd7da89a9564e1e3a9e515042df76e12130641ca6f3f2f03b699a + # via mlflow +fonttools==4.63.0 \ + --hash=sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69 \ + --hash=sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c \ + --hash=sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac \ + --hash=sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096 \ + --hash=sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d \ + --hash=sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68 \ + --hash=sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616 \ + --hash=sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78 \ + --hash=sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f \ + --hash=sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b \ + --hash=sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b \ + --hash=sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02 \ + --hash=sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d \ + --hash=sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f \ + --hash=sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8 \ + --hash=sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272 \ + --hash=sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49 \ + --hash=sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419 \ + --hash=sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001 \ + --hash=sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03 \ + --hash=sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196 \ + --hash=sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9 \ + --hash=sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e \ + --hash=sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5 \ + --hash=sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007 \ + --hash=sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380 \ + --hash=sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8 \ + --hash=sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27 \ + --hash=sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40 \ + --hash=sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e \ + --hash=sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0 \ + --hash=sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263 \ + --hash=sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb \ + --hash=sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94 \ + --hash=sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b \ + --hash=sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6 \ + --hash=sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579 \ + --hash=sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4 \ + --hash=sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59 \ + --hash=sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0 \ + --hash=sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e \ + --hash=sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be \ + --hash=sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd \ + --hash=sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18 \ + --hash=sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22 \ + --hash=sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0 \ + --hash=sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b \ + --hash=sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b \ + --hash=sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af \ + --hash=sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745 + # via matplotlib fqdn==1.5.1 \ --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 @@ -1346,9 +1554,9 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec[http]==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec[http]==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask @@ -1360,9 +1568,17 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +gitdb==4.0.12 \ + --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ + --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + # via gitpython +gitpython==3.1.50 \ + --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \ + --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 + # via mlflow-skinny +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1373,10 +1589,11 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-storage # opencensus # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via + # databricks-sdk # google-api-core # google-auth-oauthlib # google-cloud-bigquery @@ -1387,37 +1604,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -1461,88 +1678,100 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status +graphene==3.4.3 \ + --hash=sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa \ + --hash=sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71 + # via mlflow +graphql-core==3.2.11 \ + --hash=sha256:0b3e35ff41e9adba53021ab0cef475eb18f57c7f53f0f2ca55567fbf3c537ea0 \ + --hash=sha256:e7e156d10beb127cab5c89ff0da71416fc73d27c484a4757d3b2d35633774802 + # via + # graphene + # graphql-relay +graphql-relay==3.2.0 \ + --hash=sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c \ + --hash=sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5 + # via graphene great-expectations==0.18.8 \ --hash=sha256:ab41cfa3de829a4f77bdcd4a23244684cbb67fdacc734d38910164cd02ec95b6 \ --hash=sha256:c1205bede593f679e22e0b3826d6ae1623c439cafd553f9f0bc2b0fd441f6ed9 # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1554,77 +1783,81 @@ grpcio==1.62.3 \ # pymilvus # qdrant-client # ray -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -grpcio-testing==1.62.3 \ - --hash=sha256:06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb \ - --hash=sha256:f63577f28aaa95ea525124a0fd63c3429d71f769f4179b13f5e6cbc54979bfab +grpcio-testing==1.81.0 \ + --hash=sha256:32370bdffc0cd09abade928fd880f919bf070afe5d012a2de1412427b2dc1921 \ + --hash=sha256:f754ea3efd110127920513f0177f31b5c9bcbdc7e4af9ac568d8b3a5684df3c6 # via feast (pyproject.toml) -grpcio-tools==1.62.3 \ - --hash=sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133 \ - --hash=sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e \ - --hash=sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e \ - --hash=sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7 \ - --hash=sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf \ - --hash=sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa \ - --hash=sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5 \ - --hash=sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c \ - --hash=sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373 \ - --hash=sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184 \ - --hash=sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1 \ - --hash=sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950 \ - --hash=sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61 \ - --hash=sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0 \ - --hash=sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26 \ - --hash=sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5 \ - --hash=sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1 \ - --hash=sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23 \ - --hash=sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d \ - --hash=sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833 \ - --hash=sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492 \ - --hash=sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43 \ - --hash=sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7 \ - --hash=sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3 \ - --hash=sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc \ - --hash=sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed \ - --hash=sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a \ - --hash=sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557 \ - --hash=sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193 \ - --hash=sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325 \ - --hash=sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b \ - --hash=sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf \ - --hash=sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d \ - --hash=sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10 \ - --hash=sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9 \ - --hash=sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc \ - --hash=sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5 \ - --hash=sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5 \ - --hash=sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f \ - --hash=sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc \ - --hash=sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f \ - --hash=sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6 \ - --hash=sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29 \ - --hash=sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434 \ - --hash=sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14 \ - --hash=sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667 \ - --hash=sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57 \ - --hash=sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d +grpcio-tools==1.81.0 \ + --hash=sha256:0034997767960644f0f4a2aecf35df5fc426d43fa5639dd1b8317da835bab2a4 \ + --hash=sha256:012d580d98db189e4bd231a6529b162bc27a5f52c4854e2d21a4016edc47c760 \ + --hash=sha256:019f05a17b5495d561603f75a74a4a76ad22456a95dc7623c7be4e4b44391b88 \ + --hash=sha256:0733d773eca8cb461f4f2a1b79c64c123db9661be41b08184b81497b2b991ccb \ + --hash=sha256:1e21049aeedd9d62e5e58146e5d00f3b75674d8d8d3cc69709ab950082be8421 \ + --hash=sha256:1ecb833118bfa2c3051e534692f2b43f7c6db14e1eac9b1e7f6e66b6b6dc5074 \ + --hash=sha256:23831f5c66038c5793cb5d2651120bc24a33705e1ce2887a88f54272b73b240f \ + --hash=sha256:244619491a12d1f8d4119bb5930272827084a1e7caa8f9d5a0d4ca6595bb1dea \ + --hash=sha256:283bb3465331a4034b14dce35425c47b0cfbd287b09a6e9d15c9f26fbb17e799 \ + --hash=sha256:2a369a9e27fcb6279387744778d67a64551de82db0e9cf7e1e9451c22f719e07 \ + --hash=sha256:33c579bf24040dbdce751e05b5bcedc13dafffa8f2dfa07193bc05960dc95b49 \ + --hash=sha256:3401d6d4668c064c9ed344825fe97ff076cd8ba719a24e3d3c7169b604cbf00f \ + --hash=sha256:374fe0435447f283e3c69f719ef1bc66f2e187a239ce25444b2de45cb3a6a744 \ + --hash=sha256:3f1ac691debbdbf00e7635ecacf28647f48f67fb4b14120a4541c8bb0f8333ae \ + --hash=sha256:404ca893d54f26fddb868bbd4a54b203fbf914264d26c52e2f2aff35851a9f72 \ + --hash=sha256:40b7a17629e5c944c8ba98a438f051b9affaf30794e6e096578ba0030725f90c \ + --hash=sha256:42e1eaa98199bd4f900f8af091e27aef804dd53b59c92adafcc9faabc0a92240 \ + --hash=sha256:475286558410e4d0394fc8129559080c22835ece3c23cac194b46c5ad7d0fad1 \ + --hash=sha256:4a8d9fdf42537cd1924f7e95013771aa73c89501ccf112b7517c22ca825be9f5 \ + --hash=sha256:52687858c044a6a4dd3fc4049b012b131254a3061360d6de2f97c3e38a7aedd9 \ + --hash=sha256:564624654f5a0377adc69f226f93ec5ff52715030c2f846af6c54ccc4ca2d225 \ + --hash=sha256:5783b6758244f6eaceb41a0e651828824b0d0c92724ddf4b68879ced9bfd9b50 \ + --hash=sha256:58e65dd13f7ffc25f5a9cd9890fddfd39b3c51e5c3c1acd987813b1dc1173704 \ + --hash=sha256:5a7c89432a3b200be306e76307b866716663b4c71d7816bdf382af81e00abd51 \ + --hash=sha256:5c5f44305786c1295320fed477f5673be4ca5f6ed1b31f8696f0791d4b12906d \ + --hash=sha256:61d9ad6b5c0f3857663701bdc2cbb3da7f7d835ce9a8d597ffca443124a96894 \ + --hash=sha256:677207d88b659048f63697c237bf650b123a7a1de36158db57176f84c5bca84a \ + --hash=sha256:69f8355b723db7b5e26a3bff76f9deb3a407d22fe289bca486ccf95d6133cad0 \ + --hash=sha256:760775f79bbefa321cd327fe1019a9d6ad0d93acb1ede7b7905c712679542fd7 \ + --hash=sha256:78c2514bf172b20631685840fea0c5d1bec5518b649d0a498f6dd8f91dfce56a \ + --hash=sha256:7af4faf34376c57f4f3c42aa05f065d3b10e774b8a8d8b27d659d5cc351e5c75 \ + --hash=sha256:98b57a592a75553f4dd38db3993b037953245991b8df9f06927a8978962dcd82 \ + --hash=sha256:a741007631248dd903f880b575a63c0662433ed4b966262ab0f437ea860c9b7e \ + --hash=sha256:a87ea8056beea56b24353d27b7f0ab814daabb372aa517d2e179470e66fd8f6b \ + --hash=sha256:b2b26111795d0e7a72fa483d377a75b57203edaac8bbbac1e9b8f174e7b01ff3 \ + --hash=sha256:bac1c6ddc5eb3762257e773829b4e00ea7d0592f02498f27e5bdb75cd3182d69 \ + --hash=sha256:bf19fdc8b6258fbf36ea65f5672206483ef4639a16d33e3367d77e4523b4089b \ + --hash=sha256:bf2ffd98c754d54a5affddfe3a18d4822b972c5c37ca6a33a456c94e6f3dd82b \ + --hash=sha256:d56060281599d87e66a0dc6840b68730d81c215dbb1b5c50882f819bc9b6aba5 \ + --hash=sha256:d744ea354c9ca33ca17522436825e2842df9b731bcc924a73f4a7d205ed53006 \ + --hash=sha256:dce33d09851bc15dead814bd9d21023bffdf0f838ecf65995a2456e5692831fd \ + --hash=sha256:e5d241c694a226bada06dae9accc47c5c25e586f49464823498e84cff63eedea \ + --hash=sha256:e9945945edc14022abab07caec0ebc16bf51219e586b4f008d09334cc479655c \ + --hash=sha256:f02d796474e58bba879965d228874c2c34164b6a5d96c0faf6bf896a6c3d8a0b \ + --hash=sha256:f1f407697873acbf1d961c6fb9223114a3e679938469d4186623b8b872dbdae0 \ + --hash=sha256:f35da7b3b9537ecce9a5cfd967b1316a815378d5a3729e9ea556b22a14f6e315 \ + --hash=sha256:f37ce0440e5dc563662da89d7d1edd20654e6fb615ada5c8027f15f881bd40d0 \ + --hash=sha256:fa529a1f7a946cdb6881141a07d8fc8fb074af2fd17323e5f3530c8718101680 \ + --hash=sha256:fbe12f98aeddfeaa74d3dbe41dc451f008edf3ab1b82eb62f7a61011003d4833 \ + --hash=sha256:ffa74b84d201bea407f22e00ac0367f12df48a0073b0ffd9f3be9d8126a55245 \ + --hash=sha256:ffb1e507f9849ee013473f732b1ca5d732457f9b1d0d298efe8a77c33bb65d3a # via feast (pyproject.toml) -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) + # mlflow # uvicorn-worker h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -1644,128 +1877,146 @@ hazelcast-python-client==5.6.0 \ --hash=sha256:834b87076a47c781ef80bdcb522b86abc75ff28992dfe384e47f669f06cabb18 \ --hash=sha256:e2cec409068990ca9b4381fe97160cc2375412334782bef45ab4c8fe4d10536c # via feast (pyproject.toml) -hf-xet==1.3.2 \ - --hash=sha256:06b724a361f670ae557836e57801b82c75b534812e351a87a2c739f77d1e0635 \ - --hash=sha256:06cdbde243c85f39a63b28e9034321399c507bcd5e7befdd17ed2ccc06dfe14e \ - --hash=sha256:1c88fbd90ad0d27c46b77a445f0a436ebaa94e14965c581123b68b1c52f5fd30 \ - --hash=sha256:211f30098512d95e85ad03ae63bd7dd2c4df476558a5095d09f9e38e78cbf674 \ - --hash=sha256:305f5489d7241a47e0458ef49334be02411d1d0f480846363c1c8084ed9916f7 \ - --hash=sha256:3155a02e083aa21fd733a7485c7c36025e49d5975c8d6bda0453d224dd0b0ac4 \ - --hash=sha256:31612ba0629046e425ba50375685a2586e11fb9144270ebabd75878c3eaf6378 \ - --hash=sha256:335a8f36c55fd35a92d0062f4e9201b4015057e62747b7e7001ffb203c0ee1d2 \ - --hash=sha256:35b855024ca37f2dd113ac1c08993e997fbe167b9d61f9ef66d3d4f84015e508 \ - --hash=sha256:433c77c9f4e132b562f37d66c9b22c05b5479f243a1f06a120c1c06ce8b1502a \ - --hash=sha256:4a6817c41de7c48ed9270da0b02849347e089c5ece9a0e72ae4f4b3a57617f82 \ - --hash=sha256:4bc995d6c41992831f762096020dc14a65fdf3963f86ffed580b596d04de32e3 \ - --hash=sha256:7c2a054a97c44e136b1f7f5a78f12b3efffdf2eed3abc6746fc5ea4b39511633 \ - --hash=sha256:83d8ec273136171431833a6957e8f3af496bee227a0fe47c7b8b39c106d1749a \ - --hash=sha256:91b1dc03c31cbf733d35dc03df7c5353686233d86af045e716f1e0ea4a2673cf \ - --hash=sha256:9298b47cce6037b7045ae41482e703c471ce36b52e73e49f71226d2e8e5685a1 \ - --hash=sha256:959083c89dee30f7d6f890b36cdadda823386c4de63b1a30384a75bfd2ae995d \ - --hash=sha256:a85d3d43743174393afe27835bde0cd146e652b5fcfdbcd624602daef2ef3259 \ - --hash=sha256:c1980abfb68ecf6c1c7983379ed7b1e2b49a1aaf1a5aca9acc7d48e5e2e0a961 \ - --hash=sha256:c1ae4d3a716afc774e66922f3cac8206bfa707db13f6a7e62dfff74bfc95c9a8 \ - --hash=sha256:c34e2c7aefad15792d57067c1c89b2b02c1bbaeabd7f8456ae3d07b4bbaf4094 \ - --hash=sha256:cfa760888633b08c01b398d212ce7e8c0d7adac6c86e4b20dfb2397d8acd78ee \ - --hash=sha256:d6dbdf231efac0b9b39adcf12a07f0c030498f9212a18e8c50224d0e84ab803d \ - --hash=sha256:e130ee08984783d12717444e538587fa2119385e5bd8fc2bb9f930419b73a7af \ - --hash=sha256:f93b7595f1d8fefddfede775c18b5c9256757824f7f6832930b49858483cd56f +hf-xet==1.5.0 \ + --hash=sha256:1e60df5a42e9bed8628b6416af2cba4cba57ae9f02de226a06b020d98e1aab18 \ + --hash=sha256:2806c7c17b4d23f8d88f7c4814f838c3b6150773fe339c20af23e1cfaf2797e4 \ + --hash=sha256:2baea1b0b989e5c152fe81425f7745ddc8901280ba3d97c98d8cdece7b706c60 \ + --hash=sha256:3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949 \ + --hash=sha256:4b35549ce62601b84da4ff9b24d970032ace3d4430f52d91bcbb26c901d6c690 \ + --hash=sha256:526345b3ed45f374f6317349df489167606736c876241ba984105afe7fd4839d \ + --hash=sha256:5906bf7718d3636dc13402914736abe723492cb730f744834f5f5b67d3a12702 \ + --hash=sha256:5f3dc2248fc01cc0a00cd392ab497f1ca373fcbc7e3f2da1f452480b384e839e \ + --hash=sha256:73a0dae8c71de3b0633a45c73f4a4a5ed09e94b43441d82981a781d4f12baa42 \ + --hash=sha256:786d28e2eb8315d5035544b9d137b4a842d600c434bb91bf7d0d953cce906ad4 \ + --hash=sha256:7d70fe2ce97b9db73b9c9b9c81fe3693640aec83416a966c446afea54acfae3c \ + --hash=sha256:872d5601e6deea30d15865ede55d29eac6daf5a534ab417b99b6ef6b076dd96c \ + --hash=sha256:8dbcbab554c9ef158ef2c991545c3e970ddd8cc7acdcd0a78c5a41095dab4ded \ + --hash=sha256:9929561f5abf4581c8ea79587881dfef6b8abb2a0d8a51915936fc2a614f4e73 \ + --hash=sha256:9a0ee58cd18d5ea799f7ed11290bbccbe56bdd8b1d97ca74b9cc49a3945d7a3b \ + --hash=sha256:a60290ec57e9b71767fba7c3645ddafdd0759974b540441510c629c6db6db24a \ + --hash=sha256:b285cea1b5bab46b758772716ba8d6854a1a0310fed1c249d678a8b38601e5a0 \ + --hash=sha256:b6c9df403040248c76d808d3e047d64db2d923bae593eb244c41e425cf6cd7be \ + --hash=sha256:c799d49f1a5544a0ef7591c0ee75e0d6b93d6f56dc7a4979f59f7518d2872216 \ + --hash=sha256:cf7b2dc6f31a4ea754bb50f74cde482dcf5d366d184076d8530b9872787f3761 \ + --hash=sha256:dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56 \ + --hash=sha256:e0fb0a34d9f406eed88233e829a67ec016bec5af19e480eac65a233ea289a948 \ + --hash=sha256:e5de0f6deada0dada870bb376a11bcd1f08abf3a968a6d118f33e72d1b1eb480 \ + --hash=sha256:f7b7bbae318e583a86fb21e5a4a175d6721d628a2874f4bd022d0e660c32a682 \ + --hash=sha256:fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a # via huggingface-hub -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1775,50 +2026,57 @@ httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx[http2]==0.27.2 \ --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ @@ -1836,6 +2094,10 @@ httpx-sse==0.4.3 \ --hash=sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc \ --hash=sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d # via mcp +huey==3.0.1 \ + --hash=sha256:5de8ff852021da670efe8d4d78db8719c0255ebbde0772766a0114f997ea61f6 \ + --hash=sha256:83ca54fa77c4ee27349393212fc13088142244f491be903f620a9e46e8fca4ce + # via mlflow huggingface-hub==0.36.2 \ --hash=sha256:1934304d2fb224f8afa3b87007d58501acfda9215b334eed53072dd5e815ff7a \ --hash=sha256:48f0c8eac16145dfce371e9d2d7772854a4f591bcb56c9cf548accf531d54270 @@ -1844,6 +2106,7 @@ huggingface-hub==0.36.2 \ # datasets # docling # docling-ibm-models + # sentence-transformers # timm # tokenizers # transformers @@ -1855,13 +2118,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.17 \ - --hash=sha256:be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0 \ - --hash=sha256:f816b0b596b204c9fdf076ded172322f2723cf958d02f9c3587504834c8ff04d +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1877,29 +2140,29 @@ imagesize==2.0.0 \ --hash=sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 \ --hash=sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3 # via sphinx -importlib-metadata==8.7.1 \ - --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ - --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 - # via opentelemetry-api -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec +importlib-metadata==9.0.0 \ + --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \ + --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc + # via mlflow-skinny +importlib-resources==7.1.0 \ + --hash=sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708 \ + --hash=sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1 # via happybase iniconfig==2.3.0 \ --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # via pytest -invoke==2.2.1 \ - --hash=sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 \ - --hash=sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707 +invoke==3.0.3 \ + --hash=sha256:437b6a622223824380bfb4e64f612711a6b648c795f565efc8625af66fb57f0c \ + --hash=sha256:f11327165e5cbb89b2ad1d88d3292b5113332c43b8553b494da435d6ec6f5053 # via paramiko ipykernel==7.2.0 \ --hash=sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e \ --hash=sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661 # via jupyterlab -ipython==9.11.0 \ - --hash=sha256:2a94bc4406b22ecc7e4cb95b98450f3ea493a76bec8896cda11b78d7752a6667 \ - --hash=sha256:6922d5bcf944c6e525a76a0a304451b60a2b6f875e86656d8bc2dfda5d710e19 +ipython==9.12.0 \ + --hash=sha256:01daa83f504b693ba523b5a407246cabde4eb4513285a3c6acaff11a66735ee4 \ + --hash=sha256:0f2701e8ee86e117e37f50563205d36feaa259d2e08d4a6bc6b6d74b18ce128d # via # great-expectations # ipykernel @@ -1922,9 +2185,13 @@ isoduration==20.11.0 \ --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 # via jsonschema -jedi==0.19.2 \ - --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ - --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 +itsdangerous==2.2.0 \ + --hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \ + --hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173 + # via flask +jedi==0.20.0 \ + --hash=sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67 \ + --hash=sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011 # via ipython jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -1932,6 +2199,7 @@ jinja2==3.1.6 \ # via # feast (pyproject.toml) # altair + # flask # great-expectations # jupyter-server # jupyterlab @@ -1951,9 +2219,9 @@ joblib==1.5.3 \ --hash=sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 \ --hash=sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3 # via scikit-learn -json5==0.13.0 \ - --hash=sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc \ - --hash=sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf +json5==0.14.0 \ + --hash=sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a \ + --hash=sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb # via jupyterlab-server jsonlines==4.0.0 \ --hash=sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74 \ @@ -1963,9 +2231,9 @@ jsonpatch==1.33 \ --hash=sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade \ --hash=sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c # via great-expectations -jsonpointer==3.0.0 \ - --hash=sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 \ - --hash=sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef +jsonpointer==3.1.1 \ + --hash=sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900 \ + --hash=sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca # via # jsonpatch # jsonschema @@ -1990,9 +2258,9 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -jupyter-client==8.8.0 \ - --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ - --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a +jupyter-client==8.9.0 \ + --hash=sha256:23c0c182e1901ffdab96b5a02cb7bc6f0b04524fd7fc43688a14c4ff2308fb77 \ + --hash=sha256:a0efc16adcec2bb6669d2cf91e3ba5337b338bd1ecd0d9c70940752fcb1144b2 # via # ipykernel # jupyter-server @@ -2008,17 +2276,17 @@ jupyter-core==5.9.1 \ # nbclient # nbconvert # nbformat -jupyter-events==0.12.0 \ - --hash=sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb \ - --hash=sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b +jupyter-events==0.12.1 \ + --hash=sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf \ + --hash=sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3 # via jupyter-server -jupyter-lsp==2.3.0 \ - --hash=sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245 \ - --hash=sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f +jupyter-lsp==2.3.1 \ + --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ + --hash=sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6 # via jupyterlab -jupyter-server==2.17.0 \ - --hash=sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5 \ - --hash=sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f +jupyter-server==2.19.0 \ + --hash=sha256:1731236bc32b680223e1ceb9d68209a845203475012ef68773a81434b46a31a7 \ + --hash=sha256:cb76591b76d7093584c2ad2ae72ac3d58614a4b597507a1bb04e1f9f683cf9ea # via # jupyter-lsp # jupyterlab @@ -2029,9 +2297,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.5 \ - --hash=sha256:a35694a40a8e7f2e82f387472af24e61b22adcce87b5a8ab97a5d9c486202a6d \ - --hash=sha256:eac620698c59eb810e1729909be418d9373d18137cac66637141abba613b3fda +jupyterlab==4.5.8 \ + --hash=sha256:7d514c856d0d607601ec7692374da4f26e2aaf3b6e7cd363136b422a50588d6c \ + --hash=sha256:af54d7242cc689a1e6c3ad213cc9b6d9781787d9ec67c52ec9a8f4707088cadd # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -2047,23 +2315,147 @@ jupyterlab-widgets==3.0.16 \ --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 # via ipywidgets -jwcrypto==1.5.6 \ - --hash=sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 \ - --hash=sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039 +jwcrypto==1.5.7 \ + --hash=sha256:70204d7cca406eda8c82352e3c41ba2d946610dafd19e54403f0a1f4f18633c6 \ + --hash=sha256:729463fefe28b6de5cf1ebfda3e94f1a1b41d2799148ef98a01cb9678ebe2bb0 # via python-keycloak -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kiwisolver==1.5.0 \ + --hash=sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9 \ + --hash=sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679 \ + --hash=sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0 \ + --hash=sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8 \ + --hash=sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 \ + --hash=sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96 \ + --hash=sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e \ + --hash=sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac \ + --hash=sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f \ + --hash=sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a \ + --hash=sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15 \ + --hash=sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7 \ + --hash=sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368 \ + --hash=sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02 \ + --hash=sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9 \ + --hash=sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681 \ + --hash=sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57 \ + --hash=sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 \ + --hash=sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4 \ + --hash=sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920 \ + --hash=sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374 \ + --hash=sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 \ + --hash=sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa \ + --hash=sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23 \ + --hash=sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859 \ + --hash=sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb \ + --hash=sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d \ + --hash=sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc \ + --hash=sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581 \ + --hash=sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c \ + --hash=sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099 \ + --hash=sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05 \ + --hash=sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9 \ + --hash=sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd \ + --hash=sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc \ + --hash=sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796 \ + --hash=sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303 \ + --hash=sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca \ + --hash=sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314 \ + --hash=sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489 \ + --hash=sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57 \ + --hash=sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1 \ + --hash=sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797 \ + --hash=sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021 \ + --hash=sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db \ + --hash=sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22 \ + --hash=sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028 \ + --hash=sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083 \ + --hash=sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65 \ + --hash=sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588 \ + --hash=sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0 \ + --hash=sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a \ + --hash=sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1 \ + --hash=sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c \ + --hash=sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac \ + --hash=sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476 \ + --hash=sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53 \ + --hash=sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3 \ + --hash=sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4 \ + --hash=sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615 \ + --hash=sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb \ + --hash=sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18 \ + --hash=sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b \ + --hash=sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1 \ + --hash=sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2 \ + --hash=sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c \ + --hash=sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac \ + --hash=sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d \ + --hash=sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf \ + --hash=sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2 \ + --hash=sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f \ + --hash=sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f \ + --hash=sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4 \ + --hash=sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9 \ + --hash=sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e \ + --hash=sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737 \ + --hash=sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b \ + --hash=sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed \ + --hash=sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3 \ + --hash=sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7 \ + --hash=sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08 \ + --hash=sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e \ + --hash=sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902 \ + --hash=sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd \ + --hash=sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6 \ + --hash=sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310 \ + --hash=sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537 \ + --hash=sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554 \ + --hash=sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e \ + --hash=sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87 \ + --hash=sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a \ + --hash=sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c \ + --hash=sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79 \ + --hash=sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e \ + --hash=sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16 \ + --hash=sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1 \ + --hash=sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875 \ + --hash=sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd \ + --hash=sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0 \ + --hash=sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9 \ + --hash=sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646 \ + --hash=sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657 \ + --hash=sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4 \ + --hash=sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232 \ + --hash=sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819 \ + --hash=sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384 \ + --hash=sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309 \ + --hash=sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede \ + --hash=sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2 \ + --hash=sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203 \ + --hash=sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7 \ + --hash=sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df \ + --hash=sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c \ + --hash=sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167 \ + --hash=sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3 \ + --hash=sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09 \ + --hash=sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398 + # via matplotlib +kube-authkit==0.4.0 \ + --hash=sha256:1df61ac392fca96c8f5ae8c3d6e9918f1e1655d212434b3c3da5f92cc23b660d \ + --hash=sha256:3bf5fc6ddc882498040118c907628ea68789f9a947454c241972008be59601a3 + # via codeflare-sdk +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via # feast (pyproject.toml) # codeflare-sdk + # kube-authkit lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.78.1 \ - --hash=sha256:f089b6d75e85b937f99693c93e8c16c0804008672c3dd2a3d25affd36f238100 \ - --hash=sha256:f941db80bf41db33f31df87b304e8b588f8166b813b0257c11c98f7a9d0aac71 +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2275,13 +2667,17 @@ makefun==1.16.0 \ --hash=sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4 \ --hash=sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947 # via great-expectations -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +mako==1.3.12 \ + --hash=sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9 \ + --hash=sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a + # via alembic +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich -marko==2.2.2 \ - --hash=sha256:6940308e655f63733ca518c47a68ec9510279dbb916c83616e4c4b5829f052e8 \ - --hash=sha256:f064ae8c10416285ad1d96048dc11e98ef04e662d3342ae416f662b70aa7959e +marko==2.2.3 \ + --hash=sha256:8e1d7a0387281e59dfbc52a381b58c570156970e36b2bbe047f8a3a2f368cacc \ + --hash=sha256:e31ec2875383bc62f9093d16babed5a2c2cde601c00d834ea935a2222120ec19 # via docling markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -2374,22 +2770,81 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via + # flask # jinja2 + # mako # nbconvert # werkzeug marshmallow==3.26.2 \ --hash=sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73 \ --hash=sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57 # via great-expectations -matplotlib-inline==0.2.1 \ - --hash=sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76 \ - --hash=sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe +matplotlib==3.10.9 \ + --hash=sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9 \ + --hash=sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42 \ + --hash=sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d \ + --hash=sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b \ + --hash=sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37 \ + --hash=sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b \ + --hash=sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456 \ + --hash=sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc \ + --hash=sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f \ + --hash=sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6 \ + --hash=sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2 \ + --hash=sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4 \ + --hash=sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320 \ + --hash=sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20 \ + --hash=sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf \ + --hash=sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c \ + --hash=sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80 \ + --hash=sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9 \ + --hash=sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716 \ + --hash=sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585 \ + --hash=sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb \ + --hash=sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38 \ + --hash=sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4 \ + --hash=sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2 \ + --hash=sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217 \ + --hash=sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838 \ + --hash=sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4 \ + --hash=sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda \ + --hash=sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb \ + --hash=sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f \ + --hash=sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f \ + --hash=sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f \ + --hash=sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c \ + --hash=sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb \ + --hash=sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b \ + --hash=sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285 \ + --hash=sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294 \ + --hash=sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65 \ + --hash=sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e \ + --hash=sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d \ + --hash=sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f \ + --hash=sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8 \ + --hash=sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39 \ + --hash=sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6 \ + --hash=sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f \ + --hash=sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf \ + --hash=sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2 \ + --hash=sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe \ + --hash=sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99 \ + --hash=sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb \ + --hash=sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8 \ + --hash=sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1 \ + --hash=sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 \ + --hash=sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba \ + --hash=sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358 + # via mlflow +matplotlib-inline==0.2.2 \ + --hash=sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6 \ + --hash=sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79 # via # ipykernel # ipython -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -2400,19 +2855,29 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) minio==7.2.11 \ --hash=sha256:153582ed52ff3b5005ba558e1f25bfe1e9e834f7f0745e594777f28e3e81e1a0 \ --hash=sha256:4db95a21fe1e2022ec975292d8a1f83bd5b18f830d23d42a4518ac7a5281d7c5 # via feast (pyproject.toml) -mistune==3.2.0 \ - --hash=sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a \ - --hash=sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 +mistune==3.2.1 \ + --hash=sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048 \ + --hash=sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28 # via # great-expectations # nbconvert +mlflow==3.13.0 \ + --hash=sha256:7ca9cb2f623f300dabadaf5e985c85af77c5db3d7c36f56769d22c101b132f6c \ + --hash=sha256:a95198d592a8a15fad3db7f56b228acc9422c09f0daa7c6c976a9996ab73c3e2 + # via feast (pyproject.toml) +mlflow-skinny==3.13.0 \ + --hash=sha256:ced3d9a580564fae093d14732df8531fb180574f6483d4c642b6083879eb86fc \ + --hash=sha256:d2273bfa21f776359f7d6ab2267967e3a6732a5fb00996ad433d0e777dfa3b71 + # via mlflow +mlflow-tracing==3.13.0 \ + --hash=sha256:2f8187ce2b1af7419be71d2d8ab5fec53d207d4b8d703cd15e5db64939098d72 \ + --hash=sha256:42c435b0fdcab00f1865cab4a52f7a85a2a08d68a959f36bcf90a1c9fe65db0a + # via mlflow mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -2538,9 +3003,9 @@ mpmath==1.3.0 \ --hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \ --hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c # via sympy -msal==1.35.1 \ - --hash=sha256:70cac18ab80a053bff86219ba64cfe3da1f307c74b009e2da57ef040eb1b5656 \ - --hash=sha256:8f4e82f34b10c19e326ec69f44dc6b30171f2f7098f3720ea8a9f0c11832caa3 +msal==1.37.0 \ + --hash=sha256:1b1672a33ee467c1d70b341bb16cafd51bb3c817147a95b93263794b03971bec \ + --hash=sha256:dd17e95a7c71bce75e8108113438ba7c4a086b3bcad4f57a8c09b7af3d753c2d # via # azure-identity # msal-extensions @@ -2822,13 +3287,17 @@ mypy-protobuf==3.3.0 \ --hash=sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d \ --hash=sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248 # via feast (pyproject.toml) -nbclient==0.10.4 \ - --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ - --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 +narwhals==2.22.1 \ + --hash=sha256:60567d774edf77db53906f89d9fbd164e66e56d66d388e1e6990f17ac33cfb53 \ + --hash=sha256:d62920805a0a43b7ff8b54b0c0d3142d796f8a9301836ada37e573d6a33cbcd9 + # via scikit-learn +nbclient==0.11.0 \ + --hash=sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a \ + --hash=sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895 # via nbconvert -nbconvert==7.17.0 \ - --hash=sha256:1b2696f1b5be12309f6c7d707c24af604b87dfaf6d950794c7b07acab96dda78 \ - --hash=sha256:4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518 +nbconvert==7.17.1 \ + --hash=sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2 \ + --hash=sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8 # via jupyter-server nbformat==5.10.4 \ --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ @@ -2873,9 +3342,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.4 \ - --hash=sha256:860e31782b3d3a25ca0819ff039f5cf77845d1bf30c78ef9528b88b25e0a9850 \ - --hash=sha256:b928b2ba22cb63aa83df2e0e76fe3697950a0c1c4a41b84ebccf1972b1bb5771 +notebook==7.5.7 \ + --hash=sha256:1f95f79d117e47d20b5555b5c85a397d2cfecf136978aaab767cf0314b09165b \ + --hash=sha256:d6d59288a25303b25e1dcb71e9b017ec3a785f7d92f38b9bc288ca1970d5b0a8 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -2883,83 +3352,84 @@ notebook-shim==0.2.4 \ # via # jupyterlab # notebook -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # accelerate # altair + # contourpy # dask # datasets # db-dtypes @@ -2969,6 +3439,8 @@ numpy==2.4.3 \ # great-expectations # ibis-framework # imageio + # matplotlib + # mlflow # opencv-python-headless # pandas # pandas-gbq @@ -2978,7 +3450,9 @@ numpy==2.4.3 \ # scikit-image # scikit-learn # scipy + # sentence-transformers # shapely + # skops # tifffile # torchvision # transformers @@ -3004,8 +3478,8 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.44.1 \ - --hash=sha256:cc121f82cb15dcf5f2f1347bd30d4c83cae1d510809e6ccce111b98298271503 +openlineage-python==1.48.0 \ + --hash=sha256:107f460e5836f5a2d618c3b30f816ee5cd18974c7be899c86cac879a379b54c9 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ @@ -3015,145 +3489,168 @@ openshift-client==1.0.18 \ --hash=sha256:be3979440cfd96788146a3a1650dabe939d4d516eea0b39f87e66d2ab39495b1 \ --hash=sha256:d8a84080307ccd9556f6c62a3707a3e6507baedee36fa425754f67db9ded528b # via codeflare-sdk -opentelemetry-api==1.40.0 \ - --hash=sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f \ - --hash=sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9 +opentelemetry-api==1.42.1 \ + --hash=sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714 \ + --hash=sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716 # via + # mlflow-skinny + # mlflow-tracing # opentelemetry-exporter-prometheus # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-exporter-prometheus==0.61b0 \ - --hash=sha256:3013b41f4370143d48d219a2351473761423e5882fa4c213811eaefacba39cb7 \ - --hash=sha256:7c4919bd8e79abd62b610767e80f42c9c3a06c5183f4dd9141eedeb57aea284b +opentelemetry-exporter-prometheus==0.63b1 \ + --hash=sha256:0efd00aa6b1939345ddcc6de141b83ebffa2b4401a37a68f880e54217602701d \ + --hash=sha256:31902e22c89431058a95b6dcdb644f9309f226aa4872cc755f0a780d2895e97f # via ray -opentelemetry-proto==1.27.0 \ - --hash=sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6 \ - --hash=sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace - # via ray -opentelemetry-sdk==1.40.0 \ - --hash=sha256:18e9f5ec20d859d268c7cb3c5198c8d105d073714db3de50b593b8c1345a48f2 \ - --hash=sha256:787d2154a71f4b3d81f20524a8ce061b7db667d24e46753f32a7bc48f1c1f3f1 +opentelemetry-proto==1.42.1 \ + --hash=sha256:c6a51e6b4f05ae63565f3a113217f3d2bfaec68f78c02d7a6c85f9010d1cfca6 \ + --hash=sha256:dedb74cba2886c59c7789b227a7a670613025a07489040050aedff6e5c0fb43c + # via + # mlflow-skinny + # mlflow-tracing + # ray +opentelemetry-sdk==1.42.1 \ + --hash=sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d \ + --hash=sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7 # via + # mlflow-skinny + # mlflow-tracing # opentelemetry-exporter-prometheus # ray -opentelemetry-semantic-conventions==0.61b0 \ - --hash=sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a \ - --hash=sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2 +opentelemetry-semantic-conventions==0.63b1 \ + --hash=sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9 \ + --hash=sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682 # via opentelemetry-sdk -oracledb==3.4.2 \ - --hash=sha256:00c79448017f367bb7ab6900efe0706658a53768abea2b4519a4c9b2d5743890 \ - --hash=sha256:0e16fe3d057e0c41a23ad2ae95bfa002401690773376d476be608f79ac74bf05 \ - --hash=sha256:0f04a2d62073407672f114d02529921de0677c6883ed7c64d8d1a3c04caa3238 \ - --hash=sha256:1617a1db020346883455af005efbefd51be2c4d797e43b1b38455a19f8526b48 \ - --hash=sha256:19fa80ef84f85ad74077aa626067bbe697e527bd39604b4209f9d86cb2876b89 \ - --hash=sha256:1e4930d7f6584832dcc15b8ca415a7957b0c45f5aa7c4f88702e070e5c53bf93 \ - --hash=sha256:23aa07c1eaca17ae74c6fdc86b218f58484d56452958aead1aa460c0596a76c1 \ - --hash=sha256:31b7ee83c23d0439778303de8a675717f805f7e8edb5556d48c4d8343bcf14f5 \ - --hash=sha256:3df8eee1410d25360599968b1625b000f10c5ae0e47274031a7842a9dc418890 \ - --hash=sha256:404ec1451d0448653ee074213b87d6c5bd65eaa74b50083ddf2c9c3e11c71c71 \ - --hash=sha256:46e0f2278ff1fe83fbc33a3b93c72d429323ec7eed47bc9484e217776cd437e5 \ - --hash=sha256:55397e7eb43bb7017c03a981c736c25724182f5210951181dfe3fab0e5d457fb \ - --hash=sha256:574c8280d49cbbe21dbe03fc28356d9b9a5b9e300ebcde6c6d106e51453a7e65 \ - --hash=sha256:59ad6438f56a25e8e1a4a3dd1b42235a5d09ab9ba417ff2ad14eae6596f3d06f \ - --hash=sha256:5d7befb014174c5ae11c3a08f5ed6668a25ab2335d8e7104dca70d54d54a5b3a \ - --hash=sha256:5ed78d7e7079a778062744ccf42141ce4806818c3f4dd6463e4a7edd561c9f86 \ - --hash=sha256:643c25d301a289a371e37fcedb59e5fa5e54fb321708e5c12821c4b55bdd8a4d \ - --hash=sha256:6d85622664cc88d5a82bbd7beccb62cd53bd272c550a5e15e7d5f8ae6b86f1f1 \ - --hash=sha256:9f434a739405557bd57cb39b62238142bb27855a524a70dc6d397a2a8c576c9d \ - --hash=sha256:a7396664e592881225ba66385ee83ce339d864f39003d6e4ca31a894a7e7c552 \ - --hash=sha256:ac25a0448fc830fb7029ad50cd136cdbfcd06975d53967e269772cc5cb8c203a \ - --hash=sha256:b1095d95d0c8b37e4d0e17cf1928919cb59222b6344362a1cf6a2f3ca205a28a \ - --hash=sha256:b26a10f9c790bd141ffc8af68520803ed4a44a9258bf7d1eea9bfdd36bd6df7f \ - --hash=sha256:b8e4b8a852251cef09038b75f30fce1227010835f4e19cfbd436027acba2697c \ - --hash=sha256:b974caec2c330c22bbe765705a5ac7d98ec3022811dec2042d561a3c65cb991b \ - --hash=sha256:d7ce75c498bff758548ec6e4424ab4271aa257e5887cc436a54bc947fd46199a \ - --hash=sha256:d8d75e4f879b908be66cce05ba6c05791a5dbb4a15e39abc01aa25c8a2492bd9 \ - --hash=sha256:e068ef844a327877bfefbef1bc6fb7284c727bb87af80095f08d95bcaf7b8bb2 \ - --hash=sha256:f8ea989965a4f636a309444bd696ab877bba373d5d67bf744785f9bd8c560865 \ - --hash=sha256:f93cae08e8ed20f2d5b777a8602a71f9418389c661d2c937e84d94863e7e7011 \ - --hash=sha256:ff3c89cecea62af8ca02aa33cab0f2edc0214c747eac7d3364ed6b2640cb55e4 +oracledb==4.0.1 \ + --hash=sha256:032ca4f558b05f03fa1bef1b04e59ec350ae0b22e6d85c47f4ac62ae98315823 \ + --hash=sha256:03afeda85bec3eca983ebf3ad9910d0f217d99300258366d287e015a041d6c13 \ + --hash=sha256:08e84a6af1b6e5921dba088dd9fc0738927206eafe5ce9763c34195f87556849 \ + --hash=sha256:0d3c6ed987df64b914ece0722692419fe494d07f15bb4d7715adeada4f914c3a \ + --hash=sha256:0ece951553c106a0896c8e1690bcdf69d472761fa65fec9b8152cbce13ab8b81 \ + --hash=sha256:10204432f0eea8707a79c75bdccb84071e43fd19c658cb3b34d1746b12c6e7fe \ + --hash=sha256:20a10f903c8da59e9689a98bd68012f78fa19bed950ad9f19cd8f5b8b97e73a0 \ + --hash=sha256:29ae0ff517a3241060eeee15a321b710c3f83a688cf2da7d5729adbe212e2b00 \ + --hash=sha256:34bbea44423ed8b24093aa859ca7ee9b6e76ea490f9acdc5f6ff01aa1083e343 \ + --hash=sha256:3b5ef1676a27b7e0a7ec55be27fd8f6d28d1601f5e8dfdae78705909f25b7c0a \ + --hash=sha256:416b324cd7715073cf5f3d577330387ffd59741463995c25bdc2d82b3e80b88e \ + --hash=sha256:443b2f03461e873ccd73dff3d8541fcf974c05e13e296a6687ffbb0c4a72c0a1 \ + --hash=sha256:4b42725337f80d433a3bd2928c08667e5b89da9ce05cf9ae3a4189c4fc4805ea \ + --hash=sha256:523b3356cde9d588ba250cefafdfc34869233d65c179f805ea6e4d3d6b209a7f \ + --hash=sha256:5332a4499d61c3cd659ed09bbd0d3c9a4c74a70bd51136d5c3de9127dc6d7434 \ + --hash=sha256:5646c126d4ab506ee2bda261e792f0036231ee929296057e79857ec678d86d4f \ + --hash=sha256:7156ef112a901967b3ee89b6c582bafc5a3082c47ca566de1a79e9ac3b48da32 \ + --hash=sha256:73ba32597fe1da72e0824aaa4b1900ec08a3b77268cb4eb45c733ae7e7043e70 \ + --hash=sha256:7bbe5611f9196f0ec15d4bf838ec728d89586a962a20d65cad898aec020e11c4 \ + --hash=sha256:7db5a43c29a23ed23923a29816c65c7a81fe00f2abfe6bf36d83ad952abd9b89 \ + --hash=sha256:8159c5bd8f25b0ca0ce30f21e7a732a2bdfb4adb81b9c8ea1ca75339d8ec8398 \ + --hash=sha256:828dd4c981b286f0467feab1c035fae8d3888cfdc707706841734821877ae1f3 \ + --hash=sha256:86a06d0afb3bb3a24bace0e72fb9abca2093efe0fa3457c65c13ba4eb5000b0b \ + --hash=sha256:86ac65cbc8d29626b1d9d203f9151566c26a78e55bdfc030c06169ae8017f458 \ + --hash=sha256:873fcca53306e2b3b445a7d657cddc19e415a7aa7e392c473dfd1a3ae3970989 \ + --hash=sha256:8e13ff1e6f28fdb863180d23fa94cb42c619c29d2981e24992431e51b97caa54 \ + --hash=sha256:8fcad6d9628923281bf21e48a391ac2f87ec6950dc63381d8fea470e3128aef0 \ + --hash=sha256:90586b3c7729b9cf3d40df902e81257f01e15e3408d8b6b9dbf91e939b64f72c \ + --hash=sha256:9f521b3f3f14fa9b8e748aeb79b064ae6767fcb0e8ff969a9aba7a852f059658 \ + --hash=sha256:a029dcee759bca56a8c95e952040c3d3f57e5ec05965355293b21930a66967fb \ + --hash=sha256:ae894ca2705929eb0ac228329336fd03388ad6e3b54002be6f5d4400a8feaf52 \ + --hash=sha256:b05bfadbfe462c39cc97258a973972f5bbbc9f8e2e9a4c2e0efcb1ec86b91088 \ + --hash=sha256:b09eec35681d72c9476e6d715b89bb775724a31e7363df6beba7470494ea8040 \ + --hash=sha256:b73820521eccd290506af94e1ffb9a8a5941b4018e3861df9b040652a7cef123 \ + --hash=sha256:c05a01d6ad610a88c2aa1a43b1dc0a8485f5fbd4374d2b36908859d4205de192 \ + --hash=sha256:c24b174aac8163065736072a726a50091791f6d30ac5c44965cf7044e86fbaf8 \ + --hash=sha256:c2d394453f669858bec942ff0da18b6ebade296ece823d582ad2b464ed5c6c90 \ + --hash=sha256:cb7727f93ff962ab826bc3d0bca4b0e5bf45ecb7c525551c70c9e094f0f27027 \ + --hash=sha256:ce3f25552fe58df5c266874f8b13f0a8ab7fcd09ab4b476bc15520a67527ca4b \ + --hash=sha256:ce6319ee01dcbb4d74f0e2a5794c6a566f339958ecac9830c67c7070521620e2 \ + --hash=sha256:cf61e42b9ef723dbdd0b23032b695e872009ed7341003df59d9a97cd960df977 \ + --hash=sha256:d132af7d95474d207632363575c7968b09e2d33dd24af3a36f539254433f4ae8 \ + --hash=sha256:d7cd278d59780e22e0a7451d208460756d779dc62b55bdbd95652f9640fbf8c3 \ + --hash=sha256:dbe8b44fea57385617838f2acfce8cc19f6c95cd9e65e7235e86b5932af1acd9 \ + --hash=sha256:e36581bb10e719d928dad12018c2d42606db2c34f49d6665b06f701f049255f0 \ + --hash=sha256:e3d54b624748cfe42248c4bc62c3f788632a2077058485a9acb3150312b1c396 \ + --hash=sha256:e4926e699a42c526137724960fa4303ecb0b542186b11d3705ac84414a896508 # via ibis-framework -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 # via - # feast (pyproject.toml) + # pymilvus # trino -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # accelerate # build @@ -3174,6 +3671,9 @@ packaging==26.0 \ # jupyterlab-server # lazy-loader # marshmallow + # matplotlib + # mlflow-skinny + # mlflow-tracing # nbconvert # openlineage-python # pandas-gbq @@ -3181,6 +3681,7 @@ packaging==26.0 \ # ray # safetensors # scikit-image + # skops # snowflake-connector-python # sphinx # transformers @@ -3252,6 +3753,7 @@ pandas==2.3.3 \ # google-cloud-bigquery # great-expectations # ibis-framework + # mlflow # pandas-gbq # pymilvus # ray @@ -3264,17 +3766,17 @@ pandocfilters==1.5.1 \ --hash=sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e \ --hash=sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc # via nbconvert -paramiko==4.0.0 \ - --hash=sha256:0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 \ - --hash=sha256:6a25f07b380cc9c9a88d2b920ad37167ac4667f8d9886ccebd8f90f654b5d69f +paramiko==5.0.0 \ + --hash=sha256:36763b5b95c2a0dcfdf1abc48e48156ee425b21efe2f0e787c2dd5a95c0e5e79 \ + --hash=sha256:b7044611c30140d9a75261653210e2002977b71a0497ff3ba0d98d7edbf62f7c # via openshift-client parsimonious==0.11.0 \ --hash=sha256:32e3818abf9f05b3b9f3b6d87d128645e30177e91f614d2277d88a0aea98fae2 \ --hash=sha256:e080377d98957beec053580d38ae54fcdf7c470fb78670ba4bf8b5f9d5cad2a9 # via singlestoredb -parso==0.8.6 \ - --hash=sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd \ - --hash=sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff +parso==0.8.7 \ + --hash=sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c \ + --hash=sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1 # via jedi parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -3407,12 +3909,13 @@ pillow==11.3.0 \ # docling-parse # easyocr # imageio + # matplotlib # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1.2 \ + --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ + --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3444,6 +3947,10 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) +prettytable==3.17.0 \ + --hash=sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0 \ + --hash=sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 + # via skops prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 @@ -3456,154 +3963,153 @@ prompt-toolkit==3.0.52 \ --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 # via ipython -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==4.25.8 \ - --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ - --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ - --hash=sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af \ - --hash=sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0 \ - --hash=sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd \ - --hash=sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0 \ - --hash=sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7 \ - --hash=sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9 \ - --hash=sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f \ - --hash=sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3 \ - --hash=sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24 +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) + # databricks-sdk # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable @@ -3615,6 +4121,8 @@ protobuf==4.25.8 \ # grpcio-status # grpcio-testing # grpcio-tools + # mlflow-skinny + # mlflow-tracing # mypy-protobuf # opentelemetry-proto # proto-plus @@ -3658,80 +4166,70 @@ psutil==5.9.0 \ # feast (pyproject.toml) # accelerate # ipykernel -psycopg[binary, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[binary, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-binary==3.2.5 \ - --hash=sha256:02fb96091e2fb3ea1470b113fef08953baaedbca1d39a3f72d82cb615177846c \ - --hash=sha256:11e3ed8b94c750d54fc3e4502dd930fb0fd041629845b6a7ce089873ac9756b0 \ - --hash=sha256:1494827c43265820d5dcdc6f8086521bc7dd04b9da8831310978a788cdcd2e62 \ - --hash=sha256:21b839f9bfd77ed074f7f71464a43f453400c57d038a0ba0716329a28e335897 \ - --hash=sha256:23a1dc61abb8f7cc702472ab29554167a9421842f976c201ceb3b722c0299769 \ - --hash=sha256:274e852f9e61252bc8e80a0a43d300ba352d40219e856733054023a3bb960eb4 \ - --hash=sha256:28bd5cb2324567e5e70f07fe1d646398d6b0e210e28b49be0e69593590a59980 \ - --hash=sha256:2b053eae21dd3a6828b516a1171e1274d1af5f7c07d2d9a8f597f2e19c732168 \ - --hash=sha256:2cbb8649cfdacbd14e17f5ab78edc52d33350013888518c73e90c5d17d7bea55 \ - --hash=sha256:2cc86657c05e09c701e97f87132cd58e0d55381dd568520081ac1fe7580a9bbb \ - --hash=sha256:2d10ce4c39eb9631381a0c3792727946a4391e843625a7ee9579ac6bb11495a5 \ - --hash=sha256:2d22a15e45f43d36ed35aed4d5261f8ef6ab7d9b84ee075576ca56ae03b9e0aa \ - --hash=sha256:2dbaf32c18c0d11c4480016b89c9c5cadb7b64c55de7f181d222b189bd13a558 \ - --hash=sha256:32b5673736f04c36ccbf8012800fe5bc01b46dac22c5d59e41b043bebaad9d3d \ - --hash=sha256:375149006e21d58ed8aba640e0295d8e636043064c433af94eb58057f9b96877 \ - --hash=sha256:393ab353196d364858b47317d27804ecc58ab56dbde32217bd67f0f2f2980662 \ - --hash=sha256:39e2cd10bf15442d95c3f48376b25dc33360418ea6c3c05884d8bf42407768c0 \ - --hash=sha256:3d2e57a1d06f3968e49e948ba374f21a7d8dcf44f37d582a4aeddeb7c85ce239 \ - --hash=sha256:3eb71cfc35116e4a8e336b7e785f1fe06ca23b4516a48ea91facd577d1a1fdf6 \ - --hash=sha256:3f893c0ed3d5c7b83b76b1f8f7d3ca5a03e38bcd3cab5d65b5c25a0d1064aca4 \ - --hash=sha256:473f6827cf1faf3924eb77146d1e85126a1b5e48a88053b8d8b78dd29e971d78 \ - --hash=sha256:48f97936145cb7de18b95d85670b2d3e2c257277263272be05815b74fb0ef195 \ - --hash=sha256:48fcb12a0a72fdfe4102bdb1252a7366e8d73a2c89fe6ce5923be890de367c2f \ - --hash=sha256:4914dc60f2fddf0884464985e31d775aa865b665471fa156ec2f56fa72a1a097 \ - --hash=sha256:51a96d9fe51f718912b4a0089784f1f32d800217499fd0f0095b888506aba4c5 \ - --hash=sha256:5244bebaa9734a236b7157fb57c065b6c0f2344281916187bd73f951df1899e0 \ - --hash=sha256:5b81342e139ddccfa417832089cd213bd4beacd7a1462ca4019cafe71682d177 \ - --hash=sha256:5d2253189aa4cca0a425e2ca896d1a29760cd3a2b10ab12194e4e827a566505c \ - --hash=sha256:5fd017d7ed71c58f19b0f614e7bfb8f01ec862bacb67ae584f494d090956102e \ - --hash=sha256:605f70e267222d567fc40de7813ee3fb29f8145a1a20aa6fd3dc62baba9312f1 \ - --hash=sha256:60d0f36a42a822e43c4c7472df8a0c980c0f32e5d74ed871333c423a4e942f11 \ - --hash=sha256:62965045cc0fe3dc5dd55d39779620b225ef75962825c7b1b533033cb91810bd \ - --hash=sha256:65162a9cc3f86d70b1d895dbda506e3c079f80d082eb41c54d3f6d33a00b3965 \ - --hash=sha256:659f2c675d478b1bc01b95a8d3ded74fa939b370e71ffbecd496f617b215eb05 \ - --hash=sha256:6b581da13126b8715c0c0585cd37ce934c9864d44b2a4019f5487c0b943275e6 \ - --hash=sha256:71d82dbc7c6c7f5746468e7992e5483aa45b12250d78d220a2431ab88795825c \ - --hash=sha256:7376b13504396da9678b646f5338462347da01286b2a688a0d8493ec764683a2 \ - --hash=sha256:7623659d44a6aa032be4a066c658ba45009d768c2481526fbef7c609702af116 \ - --hash=sha256:7a94020821723a6a210206ddb458001f3ed27e1e6a0555b9422bebf7ead8ff37 \ - --hash=sha256:7d5f1bfc848a94e0d63fe693adee4f88bd9e5c415ecb4c9c17d2d44eba6795a6 \ - --hash=sha256:7efe6c732fd2d7e22d72dc4f7cf9b644020adacfff61b0a8a151343da8e661c0 \ - --hash=sha256:8a602d9fdb567cca090ca19ac3ebf10219065be2a4f8cf9eb8356cffb5a7ab1d \ - --hash=sha256:8cd9ebf335262e864d740f9dad3f672f61162cc0d4825a5eb5cf50df334a688f \ - --hash=sha256:8e6f2bef5aed021fbdf46323d3cd8847bf960efb56394698644a8ee2306f8892 \ - --hash=sha256:93221d5a759bd39b1face1d7d887d2b9ede3e55aefaff8eacf1b663ccdcd204b \ - --hash=sha256:9639289b72f9339721982e156527c296693236d6192ccc31412ab36fccd1683c \ - --hash=sha256:98efaedf2bf79f4d563ca039a57a025b72847bd80568f54709cc39fc1404772c \ - --hash=sha256:9abe093a303e25ac58774a11241150e2fe2947358d1ca12521ad03c90b131060 \ - --hash=sha256:a4321ee8180982d70458d3e8378e31448901bf0ee40fe0d410a87413578f4098 \ - --hash=sha256:a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed \ - --hash=sha256:a91b0e096fdfeb52d86bb8f5ee25dc22483d6960af9b968e6b381a8ec5bfbf82 \ - --hash=sha256:b5e0acbc991472188c9df40eb56d8a97ad3ad00d4de560b8b74bdc2d94041a8f \ - --hash=sha256:b6b5a4542aca4095ab35e184517cb0d18895ba4b6661c92865b431fa7b7974d8 \ - --hash=sha256:ba4a610882171bdaae0779f14e0ff45f3ee271fd2dbf16cdadfc81bd67323232 \ - --hash=sha256:bc5bd9bf5f5894923b78a41c5becd52d6bced1e1e43744855bd85cb341376ca6 \ - --hash=sha256:c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 \ - --hash=sha256:c3c5fa3d4fa0a651cefab391b783f89bc5e331afa0a4e93c9b16141993fa05c8 \ - --hash=sha256:ca5e36a3e7480a5c09aed99ecdb8e6554b21485c3b064297fe77f7b1b5806106 \ - --hash=sha256:d4e0c1b1aa5283f6d9a384ffc7a8400d25386bb98fdb9bddae446e4ef4da7366 \ - --hash=sha256:dc8bc40d82d1ee8dec136e10707c7f3147a6322fd8014e174a0f3446fb793649 \ - --hash=sha256:de576c49d7deab2b78088feb24e1f6ae3e16a0020e8496cdd3b8543f5e350e87 \ - --hash=sha256:e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 \ - --hash=sha256:eb8293d66c6a4ddc72fceb7ad0e111cb196cc394954ae0f9b63c251d97f1b00e \ - --hash=sha256:ee6d8f489a9b116ea8dc797664a50671585a4ca20573359f067858e1231cc217 \ - --hash=sha256:efb878d08dd49d7d9d18512e791b418a1171d08f935475eec98305f0886b7c14 +psycopg-binary==3.3.4 \ + --hash=sha256:018fbed325936da502feb546642c982dcc4b9ffdea32dfef78dbf3b7f7ad4070 \ + --hash=sha256:0579252a1202cd73e4da137a1426e2dae993ae44e757605344282af3a082848c \ + --hash=sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc \ + --hash=sha256:13a7f380824c35896dcac7fe0f61440f7ca49d6dc73f3c13a9a4471e6a3b302e \ + --hash=sha256:17a21953a9e5ff3a16dab692625a3676e2f101db5e40072f39dbee2250194d68 \ + --hash=sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae \ + --hash=sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829 \ + --hash=sha256:22cdbf5f91ef7bb91fe0c5757e1962d3127a8010256eefd9c61fcaf441802097 \ + --hash=sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c \ + --hash=sha256:276904e3452d6a23d474ef9a21eee19f20eed3d53ddd2576af033827e0ba0992 \ + --hash=sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97 \ + --hash=sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6 \ + --hash=sha256:32a6fbf8481e3a370d0d72b860d35948a693cb01281da217f7b2f307636e591a \ + --hash=sha256:41f2ec0fea529832982bcb6c9415de3c86264ebe562b77a467c0fbcd7efbba8d \ + --hash=sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228 \ + --hash=sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e \ + --hash=sha256:494ca54901be8cf9eb7e02c25b731f2317c378efa44f43e8f9bd0e1184ae7be4 \ + --hash=sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41 \ + --hash=sha256:574ea21a9651958f1535c5a1c649c7409e9168bcbffa29a3f2f961f58b322949 \ + --hash=sha256:580ae30a5f95ccd90008ec697d3ed6a4a2047a516407ad904283fa42086936e9 \ + --hash=sha256:5ab28a2a7649df3b72e6b674b4c190e448e8e77cf496a65bd846472048de2089 \ + --hash=sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf \ + --hash=sha256:612a627d733f695b1de1f9b4bd511c15f999a5d8b915d444bbd7dd71cf3370da \ + --hash=sha256:6402a9d8146cf4b3974ded3fd28a971e83dc6a0333eb7822524a3aa20b546578 \ + --hash=sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014 \ + --hash=sha256:71e55ccbdfae79a2ed9c6369c3008a3025817ff9d7e27b32a2d84e2a4267e66e \ + --hash=sha256:7465bfe6087d2d5b42d4c53b9b11ca9f218e477317a4a162a10e3c19e984ba8e \ + --hash=sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31 \ + --hash=sha256:773d573e11f437ce0bdb95b7c18dc58390494f96d43f8b45b9760436114f7652 \ + --hash=sha256:77df19583501ea288eaf15ac0fe7ad01e6d8091a91d5c41df5c718f307d8e31b \ + --hash=sha256:7f7668f30b9dd5163197e5cbf4e0efd54e00f0a859cc566ce56cfc31f4054839 \ + --hash=sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277 \ + --hash=sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7 \ + --hash=sha256:ab8cca8ef8fb1ccf5b048ae5bd78ba55b9e4b5d472e3ce5ca39ff4d2a9c249e4 \ + --hash=sha256:ad3bc94054876155549fdaedf4a46d1ec69d39a5bcee377148afe498e84c4b8e \ + --hash=sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70 \ + --hash=sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf \ + --hash=sha256:b7bfff1ca23732b488cbca3076fc11bc98d520ee122514fdb17a8e20d3338f5a \ + --hash=sha256:bdef84570ebbce1d42b4e7ea952d21c414c5f118ad02fee00c5625f35e134429 \ + --hash=sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8 \ + --hash=sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3 \ + --hash=sha256:cf7f73a4a792bc5db58a4b385d8a1467e8d468f7548702fb0ed1e9b7501b1c13 \ + --hash=sha256:cffc3408d77a27973f33e5d909b624cce683db5fc25964b02fe0aae7886c1007 \ + --hash=sha256:d7b4d40c153fa352ab3cca530f3a0baedf7621b2ebcbd7f084009522c21788fc \ + --hash=sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38 \ + --hash=sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9 \ + --hash=sha256:e2631da29253a98bd496e6c4813b24e09a4fe3fb2a9e88513305d6f8747cce95 \ + --hash=sha256:e7510c37550f91a187e3660a8cc50d4b760f8c3b8b2f89ebc5698cd2c7f2c85d \ + --hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \ + --hash=sha256:eb4eed2079c01a4850bf467deacfab56d356d4225040170af03dc9958321242d \ + --hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \ + --hash=sha256:f80e3f2b5331dbbf0901bcb658056c03eeb2c1ef31d774afb0d61598b242e744 \ + --hash=sha256:f9b1c2533af01cd7648378599f82b0b8ae32f293296e6eec5753a625bc97ef28 \ + --hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \ + --hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg ptyprocess==0.7.0 \ --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ @@ -3751,71 +4249,71 @@ py-cpuinfo==9.0.0 \ --hash=sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690 \ --hash=sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5 # via pytest-benchmark -py-spy==0.4.1 \ - --hash=sha256:1fb8bf71ab8df95a95cc387deed6552934c50feef2cf6456bc06692a5508fd0c \ - --hash=sha256:4972c21890b6814017e39ac233c22572c4a61fd874524ebc5ccab0f2237aee0a \ - --hash=sha256:532d3525538254d1859b49de1fbe9744df6b8865657c9f0e444bf36ce3f19226 \ - --hash=sha256:6a80ec05eb8a6883863a367c6a4d4f2d57de68466f7956b6367d4edd5c61bb29 \ - --hash=sha256:809094208c6256c8f4ccadd31e9a513fe2429253f48e20066879239ba12cd8cc \ - --hash=sha256:d92e522bd40e9bf7d87c204033ce5bb5c828fca45fa28d970f58d71128069fdc \ - --hash=sha256:e53aa53daa2e47c2eef97dd2455b47bb3a7e7f962796a86cc3e7dbde8e6f4db4 \ - --hash=sha256:ee776b9d512a011d1ad3907ed53ae32ce2f3d9ff3e1782236554e22103b5c084 +py-spy==0.4.2 \ + --hash=sha256:142887e984a4e541071c99a4401ff8c3770f255d329dbd0f64e8c1dd51882cce \ + --hash=sha256:1ccf688393105111684435f035bc14ec3f22117dd2b85b2414612cf27a22755a \ + --hash=sha256:24720573f95230653b457671a1dcc3c5a381fcf4e92677761e328a430ad251b2 \ + --hash=sha256:7f1c6d9b0e2379ead5bf792df43f4cf36153aa79e6dda4fb8ac7740cf8017110 \ + --hash=sha256:8b06a353c177677e4e1701b288d8c58e2f8d4208ee81a8048d9f72ba800918f8 \ + --hash=sha256:90e600b27bb6bb40479637baca5a5b4bc2ba3395c93d889e672315d93042c4ae \ + --hash=sha256:a0e6f6810ccf0fc5e64e85e0182a5b626c4496eec01b14fb8755154b363a4831 \ + --hash=sha256:aeb0323409199c785f730645e9f4bb7a7b9ca2c481f2c331a55642b5d13fa52f # via ray py4j==0.10.9.9 \ --hash=sha256:c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 \ --hash=sha256:f694cad19efa5bd1dee4f3e5270eb406613c974394035e5bfc4ec1aba870b879 # via pyspark -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -3824,6 +4322,7 @@ pyarrow==23.0.1 \ # deltalake # google-cloud-bigquery # ibis-framework + # mlflow # pandas-gbq # ray # snowflake-connector-python @@ -3831,12 +4330,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -3930,9 +4427,9 @@ pycryptodome==3.23.0 \ --hash=sha256:e3f2d0aaf8080bda0587d58fc9fe4766e012441e2eed4269a77de6aea981c8be \ --hash=sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7 # via minio -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # codeflare-sdk @@ -3945,146 +4442,148 @@ pydantic==2.12.5 \ # fastapi-mcp # great-expectations # mcp + # mlflow-skinny + # mlflow-tracing # pydantic-settings # qdrant-client # ray -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # ipython @@ -4093,11 +4592,12 @@ pygments==2.19.2 \ # nbconvert # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) + # kube-authkit # mcp # msal # singlestoredb @@ -4105,9 +4605,82 @@ pyjwt[crypto]==2.11.0 \ pylatexenc==2.10 \ --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 # via docling -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 + # via feast (pyproject.toml) +pymongo==4.17.0 \ + --hash=sha256:0ff6bd2f735ab5356541e3e57d5b7dbfbc3f2ee1ccb10b6b0f82d58af69d1d8e \ + --hash=sha256:1175563375d682260f613a96fb7a53dce746ed752bfd924eab61de3bc5bfde34 \ + --hash=sha256:1195370a77baf003b59b10e91ecc4706297197f0dd9d29c840cc556dc08f7cee \ + --hash=sha256:12c4fded3a9f1d6a687e36ebd384ac6d00b9b00de1969aa74048e7051ec2a713 \ + --hash=sha256:15d3f3d732aecac1f8d481bde4029755615639bd3076f258a2147210aec8515a \ + --hash=sha256:20323b0b1c1d33770ad1fc68d429c757734ce9ad3594421c3d6618f10572b1b9 \ + --hash=sha256:2a0d5ac205728c86e0a02192f1aa5f865b0d7d51f8df6101c01a69a7fc620d72 \ + --hash=sha256:2db66aa8dd253a0fc1fad3b0d23d5b3993f7ebde02fbbd7727128debf2853675 \ + --hash=sha256:2e190827834fce70ecdf9d46796c6dbc0ce08ea87dc2ff5bc6f3f5579b605cb9 \ + --hash=sha256:320b34457b20bbcc79997801f95d25ce00472915ca5241167242b42c4359e027 \ + --hash=sha256:3689ea34f6b647c7d1e7bdc60fcfb214b2789ed1359a7fb96569c69f50e5f18f \ + --hash=sha256:37a8385c29881b43eab31f584100fa0eaddedd5607adf010147ba1810118be90 \ + --hash=sha256:3987e96e7c7be4083d42e8ac2cc6c0d5b78db9973c90fce42ae800b616ca6b20 \ + --hash=sha256:4141e6c6a339789b2974efa00ecd9409101672d77a0e3ee2cc3839eedf8ec4df \ + --hash=sha256:422fa50d7d7f5c22ea0953554396c9ef95684a2d775f860bd75a7b510538dfca \ + --hash=sha256:47b021363cd923ace5edc7a1d63c0ff8a6d9d43859b8a1ba23645f5afae63221 \ + --hash=sha256:485c8a8eaa4c739f00a331fc73757898ee7c092c214a79e63866ff76aaf282ff \ + --hash=sha256:48bbc576677b50af043df870d84ded67cc3a9b4aa7553201beef4da5dc050a0a \ + --hash=sha256:4ae22fafca69dd3c78261969e999782ac5fc23b76cf8cccfbc3707982a74cc3d \ + --hash=sha256:50e8f8e23c6df7c6d6929f5e734980b227706e73ee847517c9ba5af90f7fc466 \ + --hash=sha256:51e1915761f65f2aaabd0ba691a31d56551d3f19d1263c2d6bf261730603de5f \ + --hash=sha256:5376ad67bb30ae910d83affcf997f706d9dee37e8b5dad8b6fedb0626e262d85 \ + --hash=sha256:5960519b4d7168f1ecdd3ea10c81b2aedeb9423651aca953cfbc8e76705d3b38 \ + --hash=sha256:5a5de048e6da5c18e27cc2437e8c15b3b0cdc8385c15b41178b0caa3322a09c2 \ + --hash=sha256:5ab3b8ff79e0dfc49b68f3c925e8cc735ea95c60efaed84cfe75692dffcaac2a \ + --hash=sha256:64837adbbd72073301af51bb0fc80e3d7707fe5527cea1033ba0320f0b2f881b \ + --hash=sha256:6877214bff5f06f6884a9fc8d9016a4a7a5f51f537f5c51ac3a576f93e7dfb32 \ + --hash=sha256:68fca71e05ee5da23a8d73cee8379dfb3d26e609a377cae731d742771ed96946 \ + --hash=sha256:6c5f62862d0f87be481fa1fe8cb811994486773c94a2b61e509285e3f2890763 \ + --hash=sha256:6fe0de9d0f6791abce3471230b32b4817bf89d27b1182b6a550e1ec0fa72aa9a \ + --hash=sha256:70ffa08ba641468cc068cf46c06b34f01a8ce3489f6411309fcb5ceabe6b2fc0 \ + --hash=sha256:757f2a4c0c2c46cab87df0333681ce69e86c9d5b45bc5203ceba5410b3489e59 \ + --hash=sha256:75bc3aa5b94fdb7138d357ec6ca61cd97e0c79f4f7f0bd3efe9639b15cc50942 \ + --hash=sha256:77aa4bc164b4de60d5db193b322f0f5b6ead716e831031bfdef8e8bd92205556 \ + --hash=sha256:7db10678814cdf7ea39fd308c6f41395cfa7b29d904bcd7895288963d8f892ba \ + --hash=sha256:809ec74de3b9148ae43fa8df9faf53470f511c8d384f13b99d6f671f2a379f15 \ + --hash=sha256:8446ff4bfcb6ec2a2e50998c860986a1e992136f998b7f53e7a717fb8aa5a0b9 \ + --hash=sha256:8a1be016198a03fd7727cdd55998964bfa4e5a6fd9733c8e95830628cef34d29 \ + --hash=sha256:8e97e03fa13327c87e3fdc5656acd01e71817f0c1dc3221cd8f30de136bf4ec3 \ + --hash=sha256:93641192644fa1ee0f34030e774fd31022a27ad11ba22cb1716142231524f8bd \ + --hash=sha256:9543d8f84c2e5608565c08ac679774811e6730770d8a645439b073422a4276fb \ + --hash=sha256:9828485f72f63c7d802e0ec41f71906f633c2692621ab3af55ca990186b091b1 \ + --hash=sha256:9eb5d63a3c518cb0804ed678f5e2b875af032d89a7cf57a57360322cf6a4d222 \ + --hash=sha256:a431b737816bf4cddd4fa0fcef04e424ad36b7692734a64150f872fb8f3208be \ + --hash=sha256:a8f9c40a09bb7d4b9fc8b1da65ecf6efa79bda5cb2756f39d9b6940fac1d19ae \ + --hash=sha256:addd0498ebbdc6354227f6ed457ed9fce442d48a3bb30d5b5bad33e104996561 \ + --hash=sha256:b24598dc3c2feccbc83b43044be48145a0dc4f9bee49ef923e3d707d54a55d85 \ + --hash=sha256:b2dfcc795f5b9fedbe179a11fdf6051581479d196582a3fe819a92a00e9b9969 \ + --hash=sha256:b4384700cffc3f1dd98e088bc0072dedf6d7d68a230bb4b972665cf69c071c1e \ + --hash=sha256:b93b22eedc62598cf5ee9d8c8007a8e9121c50fd88137012d8985500e9dc3151 \ + --hash=sha256:ba2195d4f386f839a52a23ea1cfd60ffaaba78a3d7841db51b7e433001139918 \ + --hash=sha256:bb3ebc86782049f6928dcc583008287cb1c17d463501c94a620f035f5b4fd463 \ + --hash=sha256:bd835cdb37a1adec359dd072c24f8bb14809e2644fde86fab4ee2fc9719b9483 \ + --hash=sha256:c2292144505fb12156b981bd440f3dc994a883da06ac726c0c8692ccdbc1c510 \ + --hash=sha256:c4979e7e8887862bbb44d203f00cc8263a3f27237876fa691b6beba23e40e6d8 \ + --hash=sha256:c5c8e180cb2cabe37300e1e36c60aa4f2ff956cc579f0142135a5d2cba252243 \ + --hash=sha256:c797f8a80957134f6dd9690367a0f8f5906d672119af2c6aa55f0c527b656bed \ + --hash=sha256:c9786665926a09630c5d420c79762cfadbff35a9438bcbc4c81a9fb5ab9228b7 \ + --hash=sha256:cee36b3c0d0354f880fa7a7fdcdaf2bb5e542c2281e25c1bfadf8cfe21eba7d2 \ + --hash=sha256:d53ffa94b2340dbf6b055e09a0090618c60482c158ecfc9565642fc996bf0944 \ + --hash=sha256:df4a644af9ae132d4bfdb2e9516ea51a615fd881caddfbfbd071cf1354844479 \ + --hash=sha256:dff3de1294fbbc1db0ba6b511f77b8e540601d092538a31312e99c8a91a78b1e \ + --hash=sha256:e46767f28dea610e02edf6c5d956ce615c3c7790ea396660b9b1efd5c5ead2e0 \ + --hash=sha256:e4fab10f8403169ce92f3cea921609d9ee81107306caae06c08f592d4b8ad2b5 \ + --hash=sha256:e537e95514dae1aaa718f481ec03151a0f0394bcd05f1322896d8fc1330cb729 \ + --hash=sha256:e68c76b84e0c132d9dbf9307f12ff8185702328187a87b9aca8c941303873433 \ + --hash=sha256:e816db649ba5d7de0568cf3a9f287a9dc9aad21cf0ca667ab156a7ef47fca0b0 \ + --hash=sha256:f09645e0ce4e3825fa0baa8254064a716ed0be33f78feeedd4731016cb8aaa17 \ + --hash=sha256:f3ee3d241ed77a4fc99ce3cff3b289c3ebce37f61fdd7349d3592c23b82c8784 \ + --hash=sha256:faf03e4c2aafd6de626dbd30ba246d369ae33f47f10629d1bbe40f72115027a6 \ + --hash=sha256:ff5aa3f1c7e3f08eb0e7a016c91ba468b1850ccfd63d9b1f12f56350f4974cef # via feast (pyproject.toml) pymssql==2.3.2 \ --hash=sha256:06883bc9bdb297ae9132d9371b5b1a3a223c8f93dd6a87d1c112c6a688f26d53 \ @@ -4169,9 +4742,9 @@ pymssql==2.3.2 \ --hash=sha256:fb8a7b197aaf466a7577ca6690aa9d747081b653ab212d052d71f3cc10587c3b \ --hash=sha256:fdd774b26407babd0205ef85a098f90553e6b3da77a22322a1e7d2cb51f742c0 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) pynacl==1.6.2 \ --hash=sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c \ @@ -4268,14 +4841,16 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==25.1.0 \ - --hash=sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab \ - --hash=sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ --hash=sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc - # via great-expectations + # via + # great-expectations + # matplotlib pypdfium2==4.30.0 \ --hash=sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e \ --hash=sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29 \ @@ -4297,8 +4872,8 @@ pyproject-hooks==1.2.0 \ # via # build # pip-tools -pyspark==4.1.1 \ - --hash=sha256:77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec +pyspark==4.1.2 \ + --hash=sha256:fa5d6159f700d0990a07f4f62df1b7449401dccee9cd7d5d6df8957530841602 # via feast (pyproject.toml) pytest==7.4.4 \ --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ @@ -4322,9 +4897,9 @@ pytest-benchmark==3.4.1 \ --hash=sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809 \ --hash=sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47 # via feast (pyproject.toml) -pytest-cov==7.0.0 \ - --hash=sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1 \ - --hash=sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861 +pytest-cov==7.1.0 \ + --hash=sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2 \ + --hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 # via feast (pyproject.toml) pytest-env==1.1.3 \ --hash=sha256:aada77e6d09fcfb04540a6e462c58533c37df35fa853da78707b17ec04d17dfc \ @@ -4351,112 +4926,146 @@ pytest-xdist==3.8.0 \ --hash=sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 \ --hash=sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1 # via feast (pyproject.toml) -python-bidi==0.6.7 \ - --hash=sha256:01ff2fd676ef8351f32e820b2d3b61eac875a21702d2118263a2641b458e1996 \ - --hash=sha256:05fe5971110013610f0db40505d0b204edc756e92eafac1372a464f8b9162b11 \ - --hash=sha256:06650a164e63e94dc8a291cc9d415b4027cb1cce125bc9b02dac0f34d535ed47 \ - --hash=sha256:0cb75e8a410166fd677d55095e505bf6a4773c066f51efbda72d302ebc56e79b \ - --hash=sha256:0dbb4bbae212cca5bcf6e522fe8f572aff7d62544557734c2f810ded844d9eea \ - --hash=sha256:0f86e447e94ae78db7d56e7da2124c435eaee4425c87d3d92aea271317811112 \ - --hash=sha256:11c51579e01f768446a7e13a0059fea1530936a707abcbeaad9467a55cb16073 \ - --hash=sha256:1395e236c71f11267860b53293a33b19b991b06e0f4ac61045b892e6a99d96f2 \ - --hash=sha256:17572944e6d8fb616d111fc702c759da2bf7cedab85a3e4fa2af0c9eb95ed438 \ - --hash=sha256:19737d217088ef27014f98eac1827c5913e6fb1dea96332ed84ede61791070d9 \ - --hash=sha256:1ba28642928d1c8fdb18b0632fe931f156e888c646326a3ad8eb3e55ee904951 \ - --hash=sha256:1c061207212cd1db27bf6140b96dcd0536246f1e13e99bb5d03f4632f8e2ad7f \ - --hash=sha256:1c5fb99f774748de283fadf915106f130b74be1bade934b7f73a7a8488b95da1 \ - --hash=sha256:1dd0a5ec0d8710905cebb4c9e5018aa8464395a33cb32a3a6c2a951bf1984fe5 \ - --hash=sha256:24388c77cb00b8aa0f9c84beb7e3e523a3dac4f786ece64a1d8175a07b24da72 \ - --hash=sha256:24a4a268289bbe80ad7da3064d7325f1571173859e8ad75d2f99075d5278b02b \ - --hash=sha256:24afff65c581a5d6f658a9ec027d6719d19a1d8a4401000fdb22d2eeb677b8e3 \ - --hash=sha256:257d6dd0e07221f1dc8720fa61158471f5aae30d5f89837c38a026386151c250 \ - --hash=sha256:26a8fe0d532b966708fc5f8aea0602107fde4745a8a5ae961edd3cf02e807d07 \ - --hash=sha256:2a93b0394cc684d64356b0475858c116f1e335ffbaba388db93bf47307deadfa \ - --hash=sha256:2d28e2bdcadf5b6161bb4ee9313ce41eac746ba57e744168bf723a415a11af05 \ - --hash=sha256:349b89c3110bd25aa56d79418239ca4785d4bcc7a596e63bb996a9696fc6a907 \ - --hash=sha256:3a85275dfc24a96629da058c4c2fc93af6390aefe2f7cdde1500b6ac3fd40ca0 \ - --hash=sha256:3b63d19f3f56ff7f99bce5ca9ef8c811dbf0f509d8e84c1bc06105ed26a49528 \ - --hash=sha256:3b96744e4709f4445788a3645cea7ef8d7520ccd4fa8bbbfb3b650702e12c1e6 \ - --hash=sha256:414004fe9cba33d288ff4a04e1c9afe6a737f440595d01b5bbed00d750296bbd \ - --hash=sha256:4283f8b517411cc81b3c92d11998981fe54ac0d2300f4c58d803e0c071aba1ba \ - --hash=sha256:4636d572b357ab9f313c5340915c1cf51e3e54dd069351e02b6b76577fd1a854 \ - --hash=sha256:47deaada8949af3a790f2cd73b613f9bfa153b4c9450f91c44a60c3109a81f73 \ - --hash=sha256:49639743f1230648fd4fb47547f8a48ada9c5ca1426b17ac08e3be607c65394c \ - --hash=sha256:4c73cd980d45bb967799c7f0fc98ea93ae3d65b21ef2ba6abef6a057720bf483 \ - --hash=sha256:4d84e70923392f8c9611f0fb6b341577346ef6224f3809b05f0ae1fbf8f17578 \ - --hash=sha256:4ea928c31c7364098f853f122868f6f2155d6840661f7ea8b2ccfdf6084eb9f4 \ - --hash=sha256:5013ba963e9da606c4c03958cc737ebd5f8b9b8404bd71ab0d580048c746f875 \ - --hash=sha256:5debaab33562fdfc79ffdbd8d9c51cf07b8529de0e889d8cd145d78137aab21e \ - --hash=sha256:5ebc19f24e65a1f5c472e26d88e78b9d316e293bc6f205f32de4c4e99276336e \ - --hash=sha256:630cee960ba9e3016f95a8e6f725a621ddeff6fd287839f5693ccfab3f3a9b5c \ - --hash=sha256:6323e943c7672b271ad9575a2232508f17e87e81a78d7d10d6e93040e210eddf \ - --hash=sha256:6c051f2d28ca542092d01da8b5fe110fb6191ff58d298a54a93dc183bece63bf \ - --hash=sha256:6c19ab378fefb1f09623f583fcfa12ed42369a998ddfbd39c40908397243c56b \ - --hash=sha256:6df7be07af867ec1d121c92ea827efad4d77b25457c06eeab477b601e82b2340 \ - --hash=sha256:6f9fa1257e075eeeed67d21f95e411036b7ca2b5c78f757d4ac66485c191720a \ - --hash=sha256:7336a3c4ba4fc9e6741fbe60c6483266fe39e1f24830724dfce453471d11fa40 \ - --hash=sha256:73a88dc333efc42281bd800d5182c8625c6e11d109fc183fe3d7a11d48ab1150 \ - --hash=sha256:766d5f5a686eb99b53168a7bdfb338035931a609bdbbcb537cef9e050a86f359 \ - --hash=sha256:77bb4cbadf4121db395189065c58c9dd5d1950257cc1983004e6df4a3e2f97ad \ - --hash=sha256:77fea54c2379b93def4ed16db6390e1232e7b235679587295a23dd8b1925475f \ - --hash=sha256:8047c33b85f7790474a1f488bef95689f049976a4e1c6f213a8d075d180a93e4 \ - --hash=sha256:80e6fd06f6e4074d183cea73962c89cf76cb4f70c0ee403689f57a429ebde488 \ - --hash=sha256:849a57d39feaf897955d0b19bbf4796bea53d1bcdf83b82e0a7b059167eb2049 \ - --hash=sha256:8678c2272e7bd60a75f781409e900c9ddb9f01f55c625d83ae0d49dfc6a2674f \ - --hash=sha256:8814db38fa317bebec8eb74b826bae7d0cb978a7eca30dfe4ecf60e61f06ee0b \ - --hash=sha256:8860d67dc04dc530b8b4f588f38b7341a76f2ec44a45685a2d54e9dcffa5d15a \ - --hash=sha256:898db0ea3e4aaa95b7fecba02a7560dfbf368f9d85053f2875f6d610c4d4ec2c \ - --hash=sha256:8a17631e3e691eec4ae6a370f7b035cf0a5767f4457bd615d11728c23df72e43 \ - --hash=sha256:8a18c61817f3210ba74ad5792c8a5048d9550ba233233a0a8fe35800350988f4 \ - --hash=sha256:8d4e621caadfdbc73d36eabdb2f392da850d28c58b020738411d09dda6208509 \ - --hash=sha256:94dbfd6a6ec0ae64b5262290bf014d6063f9ac8688bda9ec668dc175378d2c80 \ - --hash=sha256:95867a07c5dee0ea2340fe1d0e4f6d9f5c5687d473193b6ee6f86fa44aac45d1 \ - --hash=sha256:95c9de7ebc55ffb777548f2ecaf4b96b0fa0c92f42bf4d897b9f4cd164ec7394 \ - --hash=sha256:9adeec7cab0f2c2c291bd7faf9fa3fa233365fd0bf1c1c27a6ddd6cc563d4b32 \ - --hash=sha256:9c463ae15e94b1c6a8a50bd671d6166b0b0d779fd1e56cbf46d8a4a84c9aa2d0 \ - --hash=sha256:9d9de35eb5987da27dd81e371c52142dd8e924bd61c1006003071ea05a735587 \ - --hash=sha256:a2eb8fca918c7381531035c3aae31c29a1c1300ab8a63cad1ec3a71331096c78 \ - --hash=sha256:a4319f478ab1b90bbbe9921606ecb7baa0ebf0b332e821d41c3abdf1a30f0c35 \ - --hash=sha256:a507fe6928a27a308e04ebf2065719b7850d1bf9ff1924f4e601ef77758812bd \ - --hash=sha256:a8892a7da0f617135fe9c92dc7070d13a0f96ab3081f9db7ff5b172a3905bd78 \ - --hash=sha256:a99d898ad1a399d9c8cab5561b3667fd24f4385820ac90c3340aa637aa5adfc9 \ - --hash=sha256:aa4136f8ccb9a8cd32befd1b3882c2597e6791e64e8b3cf3129c55549b5de62f \ - --hash=sha256:ab2a5177522b62426db897b655a02f574e27d9735bbeb6da41bc981b771df636 \ - --hash=sha256:ab806fd026bfd48bade5e21e06d0d799cbfad32f236989ff6f37db03a5fbe34f \ - --hash=sha256:ad5f0847da00687f52d2b81828e8d887bdea9eb8686a9841024ea7a0e153028e \ - --hash=sha256:b0bee27fb596a0f518369c275a965d0448c39a0730e53a030b311bb10562d4d5 \ - --hash=sha256:b31d66b62736b8514982a24a7dedcf8c062b27a8e9b51e52d7a5899045a45fe1 \ - --hash=sha256:b38ddfab41d10e780edb431edc30aec89bee4ce43d718e3896e99f33dae5c1d3 \ - --hash=sha256:be1bdbd52145dfe46880d8bb56eacc25aa75c3bb075fa103de7974295eb2811f \ - --hash=sha256:c10065081c0e137975de5d9ba2ff2306286dbf5e0c586d4d5aec87c856239b41 \ - --hash=sha256:c11c62a3cdb9d1426b1536de9e3446cb09c7d025bd4df125275cae221f214899 \ - --hash=sha256:c3777ae3e088e94df854fbcbd8d59f9239b74aac036cb6bbd19f8035c8e42478 \ - --hash=sha256:c3d93171dd65b36eca5367acf19eef82c79b4df557cb4bd0daf323b7a27f2d3b \ - --hash=sha256:c9a679b24f5c6f366a0dec75745e1abeae2f597f033d0d54c74cbe62e7e6ae28 \ - --hash=sha256:caa71c723f512f8d859fa239573086e16f38ffc426b5b2f7dab5d40fdb356c80 \ - --hash=sha256:ce86d9dfc6b409ad16556384244572bb3cbefa2ca0f0eab7fba0ff2112b2f068 \ - --hash=sha256:d4cd82e65b5aeb31bd73534e61ece1cab625f4bcbdc13bc4ddc5f8cbfb37c24a \ - --hash=sha256:d524a4ba765bae9b950706472a77a887a525ed21144fe4b41f6190f6e57caa2c \ - --hash=sha256:d7310312a68fdb1a8249cf114acb5435aa6b6a958b15810f053c1df5f98476e4 \ - --hash=sha256:d8274ff02d447cca026ba00f56070ba15f95e184b2d028ee0e4b6c9813d2aaf9 \ - --hash=sha256:d879be7fb5296409e18731c7ba666d56ecd45b816b2c9eb35138aa1d7777aeb5 \ - --hash=sha256:d87ed09e5c9b6d2648e8856a4e556147b9d3cd4d63905fa664dd6706bc414256 \ - --hash=sha256:dde1c3f3edb1f0095dcbf79cf8a0bb768f9539e809d0ad010d78200eea97d42a \ - --hash=sha256:df5e9db9539d70426f5d20c7ebb6f7b33da5fbd40620e11261fe3fba7e177145 \ - --hash=sha256:e7cad66317f12f0fd755fe41ee7c6b06531d2189a9048a8f37addb5109f7e3e3 \ - --hash=sha256:ec1694134961b71ac05241ac989b49ccf08e232b5834d5fc46f8a7c3bb1c13a9 \ - --hash=sha256:ec985386bc3cd54155f2ef0434fccbfd743617ed6fc1a84dae2ab1de6062e0c6 \ - --hash=sha256:ef9d103706560c15fecaf7d3cff939e0f68ce5763cf0e64d0e4e5d37f9bdd2d1 \ - --hash=sha256:f1350033431d75be749273236dcfc808e54404cd6ece6204cdb1bc4ccc163455 \ - --hash=sha256:f1fe71c203f66bc169a393964d5702f9251cfd4d70279cb6453fdd42bd2e675f \ - --hash=sha256:f24189dc3aea3a0a94391a047076e1014306b39ba17d7a38ebab510553cd1a97 \ - --hash=sha256:f57726b5a90d818625e6996f5116971b7a4ceb888832337d0e2cf43d1c362a90 \ - --hash=sha256:f7c055a50d068b3a924bd33a327646346839f55bcb762a26ec3fde8ea5d40564 \ - --hash=sha256:f7e5072269c34a1b719910ee4decf13b288159fb320f18aba3885f6b6aab7753 \ - --hash=sha256:f7e507e1e798ebca77ddc9774fd405107833315ad802cfdaa1ab07b6d9154fc8 \ - --hash=sha256:fbbffb948a32f9783d1a28bc0c53616f0a76736ed1e7c1d62e3e99a8dfaab869 \ - --hash=sha256:fd87d112eda1f0528074e1f7c0312881816cb75854133021124269a27c6c48dc \ - --hash=sha256:ff06e4aa781aa4f68fbfaf1e727fe221fa1c552fef8ae70b6d2a0178e1f229ad +python-bidi==0.6.10 \ + --hash=sha256:00e8f3504e63a7713bdc1367b3de46270ddc76551f1cf04510039d65a123fd53 \ + --hash=sha256:038d29ba39a638a5aa904e3f86547f6f883ca16b3ea1db98fbc861e9644762fe \ + --hash=sha256:0533a900b9b9fa94e1c906e8cdb15b579389ce3fa959af228a12e8527aaba8cc \ + --hash=sha256:0675bdaceac9e2bd8ea99729d064435d1d1502e1875b87ed72ad93a8da153ff0 \ + --hash=sha256:07de0d6b998184233e8f753cbff5e828e0204b38daa3deaa458af6cb53c0960d \ + --hash=sha256:099b82f05557c1588973cceab0ebd2535800990850b4cbf8eae57682ef746a16 \ + --hash=sha256:099c3c29d813e263e999205ec9d59658c519c3bc51256e8ab3761ff3dc46a1b3 \ + --hash=sha256:09c90aca4713ed86422acfbaf90d8c5c9f64cbae02e737e7f82f13cd2ff4f34c \ + --hash=sha256:09d70ad127cbcb9cc5e90c4f2f427d998450374870f305345a8c23338a0bca55 \ + --hash=sha256:0c63bf9de0646eb7cf8d520e258701e5086c010e18cbc32e8ab884e29d5ff12f \ + --hash=sha256:0e404d7e027bd47553e48d9e3f207f3ee255698cac1fa80380d4703d4397ffe5 \ + --hash=sha256:0ef816ef2a04ce92108cdcc61c7710860e0f2b11906d493e14c6e5b403b09a01 \ + --hash=sha256:0f1c310774819302fba49b0608126033ba4b2bd0fb01d23b2c232df6d31003a4 \ + --hash=sha256:0f6a5c7b00ce285a3389e261db3f0477c2c3e893b352e65889410d995ff5ee13 \ + --hash=sha256:15298befde960a80885729c3603a95058f611b7d71de645cfbdd875f98146e14 \ + --hash=sha256:153a2f75648ceb583a09e66b4da99ec54b82e3226e5c0992f79e05d2d00d5a6e \ + --hash=sha256:1552aad47e65e8458346307e8b3fe7ae8eb0fcf3ea4ce3aba5cf44c50117e30b \ + --hash=sha256:15f0deadc4e8bf4d5458d62c4c94f7716c1d29f106751f2d9f5a478698465df0 \ + --hash=sha256:19c06c20f47f4a3daad14b5e7c2b4e23e76f4277883ef43616ecd9a8eff73203 \ + --hash=sha256:1a156226a8723942b50ffa210d1840688da158c185e3d0840743345003249875 \ + --hash=sha256:1d7714b96ab30df31337f5d100bf71ebe637976e2464761c81ab05787c4bacff \ + --hash=sha256:22f51e0e5c64e18f5f9b6ac2d01fcbbecdfa6a2d571ae71323d3051d0635b9c6 \ + --hash=sha256:2371afc3f50da896212b2d1ea7f461134ef292e1737c87d7547dd0384c092388 \ + --hash=sha256:2598937e05401111ade68cd6e2212fa556fe8cc401b541d19dcd039496a0cfdd \ + --hash=sha256:27fc502f2e368ffcedb97b674956f8306573f43cd0204e2ed9fbe7f41d116a7b \ + --hash=sha256:29a476af5efbe7fedfb53c8d05d1447e4f4149da8d88fa0643716a374b6abf27 \ + --hash=sha256:2a2013623ea8713e4bc712922d37449a4a86a504275b42447e1d2f22eb565f9d \ + --hash=sha256:322bea01cd3f9c1cc153ea4ca3b8f82d27efe5ae8c4bd81cc981420e25490bd4 \ + --hash=sha256:327e570f10443995d3697e8096bc337970dfc32cd5339759fa4e87093cf5cdf9 \ + --hash=sha256:32c6075f2b44c1b3d01e7d0c8a5bb519bdbbc832bee2d4b01a06908117d3b050 \ + --hash=sha256:32eb932af02b2dec7d3043daed84a80e34a3f46327a7cacf6a813773369fceb8 \ + --hash=sha256:341d75c8b0e107bd5188e30a8a340ec5e1a26066f21de3c761b53fde54e6cd7d \ + --hash=sha256:3a2fcfc6be1917695cd6f7c9626481aa81ade7e3ef3f79c0f7a286edf68e4463 \ + --hash=sha256:3a485820e499c74332929eb9fe9246cec92fd4e6b8c2abde03e8d8f0fea00728 \ + --hash=sha256:3d0c48305c58a5ed0017500dbeedbfc62fc8b9cd552d582ea578a10f77eed1c1 \ + --hash=sha256:3ebbf3915c39ed8d0095e3672ed4f824dfe9544e950a273513956b147528a18b \ + --hash=sha256:3ff3bc2221d8c32427cf90999b60ee9bd5e31e2e0b7f54b63ad54a05912725b8 \ + --hash=sha256:441d931609adfb2d213892e2da0326a5c5048f05e36497d5e37087b97a3287dd \ + --hash=sha256:446f1cd15783b14a280fc6c8e8931afa3f4ec1edc0b341b82cfca1537886cf28 \ + --hash=sha256:44caa945d27b7634bb4fdfe8fbeaa27b33fb12b66418e326e5a491d235b5c61b \ + --hash=sha256:44e21c6dc51b88ede76aafe730a208ef5a23cf7275d30d7870ff46e3a6ad4314 \ + --hash=sha256:44e6566093397def4e72f85e47d246d442838c497e6be3b14be0bca7d9761a50 \ + --hash=sha256:452a7ff78909edef965d1f2dc87e8cf04e6d4234771eef9b876688fdd821ab1d \ + --hash=sha256:473e718a86e5a9290ee240cf0cf49093ec0ca841d709f0fef191b7f5ea4e8b3b \ + --hash=sha256:48af3fc3bee49c3be03bbd47b503dc794474c52db249c57d230a4616cf13cf52 \ + --hash=sha256:4ed6794f07fcb4374e74a1a973350c5997c2088ba6143a8fedb533010f379502 \ + --hash=sha256:5040b6595e6a9d1cbca5fc2298684994cc5f1036ff2015eaf30063f015f31540 \ + --hash=sha256:5899a244bc0b60d71ae80dcf0dfad16c72e742857c13c0d040d1c975bb758983 \ + --hash=sha256:5d11a3eb283fbde362c4b1faa32a4053413a83aa6abc2274827e1f03c89f53f4 \ + --hash=sha256:5e4752fc7228a2d70b69dc81fe4bbe602eca44a520b3d7ff46b50fb2b68d435e \ + --hash=sha256:5f3febf9b547b3b237429fb8c214ff8faa50972c6de0fc0fbaf060fc29e4696d \ + --hash=sha256:5fdea42e1356d428cdc1771e3468327cf776da51c44a8ced855b67b02809ea56 \ + --hash=sha256:6054e1b9920a917749fb4e7547b378e0647c25095c012a2a7c184493b9204ef1 \ + --hash=sha256:644d068e01071c7af565a70269f8c93f6434c031df2b1428625ed8f6040b94b4 \ + --hash=sha256:64d4adc41eb79de0561874bbbe74e8f7974b3bb947070d0edd73d388c98e1234 \ + --hash=sha256:6a75d9ab145003094475bc955120b4577d70f34ee02f0b69696d7f216b513479 \ + --hash=sha256:6c5be3141bf22d2908d6269e613c2bc3824db0f31560a61b95be75d224812c67 \ + --hash=sha256:6e2b535558cad96805b58695353a628471e455f4f30e346d1d0a10468c991d0e \ + --hash=sha256:704c76e64aa0f7c0d4b8dff04ce9e8fb38314bddd1426985856e2533e66d7d21 \ + --hash=sha256:732ad1ebff85d4669152ec8c0bbeebdf945a3460e26ae852a30d39d93765765c \ + --hash=sha256:73bc12f9599cf1dbc39e3792abaa8fc62656cff30340308c3341583631ea5fcc \ + --hash=sha256:78248580e38051ba799076bffa5d0498d2550a4fa6d2ec733c38e4ec5a2d8039 \ + --hash=sha256:7965b1c468b986a1bbb9fd3ba8641b51f4f93352cefc83eec851fdf15850019f \ + --hash=sha256:79ba6f914436c674cb0a25d4e1356e54b3b788ccd1498e1b130edd6ba1ad2f8e \ + --hash=sha256:7a3f20dca786d493c1383273992ca87ff78942456898b136e2973a682dad73ae \ + --hash=sha256:7a5452fda554628660eb4c1c4da6187986c5497f34fbeb07f920c867b6daa943 \ + --hash=sha256:7ae97eed360514e229b0c407095a4184d8a0e6383bc87962972ae27f6ecb96e6 \ + --hash=sha256:8012aed843d01a96fbd5c2fe4d8062696f8720d38990d68eaf871aa692652e98 \ + --hash=sha256:81b27ffd3e40e2d8f274e1acbf5967873e53d6f32bf677899e0d8421170703da \ + --hash=sha256:82897bacfd8fc2fb1157b1828a011af954c24b1dc25adb2aec33fdbcacd3935f \ + --hash=sha256:84f6975f51d2af2e9b474669f26673486899138ea985f9967db4f6ab9a431b95 \ + --hash=sha256:86dea78bc3953853afb701b7bf3531f062e7aa7d0a4bdb1a59f496200967bbf7 \ + --hash=sha256:8af0d7059829d43e5b9e4072103f09d3869d3da9fc6db66b51e93da0ed0b1161 \ + --hash=sha256:8f95878c574eb603942561ad76d09ed8b05e2ffd46917b32f15bb83878f7f40e \ + --hash=sha256:903b8e4ea0fed7d453e7e437d41ba0357be55572a108f8d6110ab74cbe3b2bb0 \ + --hash=sha256:916688bcee55ce613879751a27b25977f75403c681e6d110cdf301edb48027a1 \ + --hash=sha256:929c705687f506fed02aa1fbd6781fb310203d7a20420dd7f106cd87fe1d01c5 \ + --hash=sha256:9545c3cd8238a79ab7e0ff7b27326bef3439001207984ea47fa3be31551d364e \ + --hash=sha256:97692e9fb3271a637f18d728d5db4ff729c82ae25356e35d371fada2fe0ff006 \ + --hash=sha256:9c2ae7649b77a4354b6db6423c495bd57ac5727d62266dfe98254896eb573b25 \ + --hash=sha256:a06a6e54a95b5c5864e117af2479113bb367660b0d95295b4adf314b3dff77af \ + --hash=sha256:a0df4cb0fe94de7565c3fc875888431ef774d643f00b030bd041fdebbdcd189b \ + --hash=sha256:a2e1da56d841ae506c49df41e16893428b96d3c8c255f096b1aa83c512302c94 \ + --hash=sha256:a50b1ce6c5a2aaa4febbd72cf030ec7d9bd63a063977850e484fb4a7983f7eaf \ + --hash=sha256:a51922e22ab237431c3d5505b2511732748f936349ab65d0c1a4a13e224144fc \ + --hash=sha256:a5aac3c9648872dcf11543751e2a8970ab0e8e3192fdf83ed507838917f50d70 \ + --hash=sha256:a7853e894f723675489ac49aa4b52dc8eac87d7a67b5940631c8c9d2aab46f90 \ + --hash=sha256:a7871f1226a062c641c500f81f05c2c00274c23de26707d747ce16ede43a6fdb \ + --hash=sha256:a84f26e55770a9326cedf79c005c2e7f9c13da9e0cbb65bc36890382a793bda9 \ + --hash=sha256:a9b83026c2907ad207eff37d5d302ecdd20441ba87d89401a79fa4b9af11f24d \ + --hash=sha256:afd28c86da0968996595b3dcc1166b24367954d69242c186c0916721fe36274d \ + --hash=sha256:b048ba7ec56dfd0eb37bee34d395771d1ce444fd7a32c6e8ddd3bfc92090a1d8 \ + --hash=sha256:b0c77d935abdd7e3bee0f9b8a7d0ae8a7c230e5aca3a7b9948576b2e151c9985 \ + --hash=sha256:b223d1f5493530777475fc40e4a47b6854a5ac56ea3211196d7a91809fa565f3 \ + --hash=sha256:b35b3c7e2c91f67dbf49de4513adf80ee052b06f15dcb9e7e5c6cd6f37373114 \ + --hash=sha256:b35ff4e825c4ad912a30909f2922eddd684c84bffc48e713c8bf22a4f3d7794f \ + --hash=sha256:b45368872b3770b20d101a87364ffeec5c0cf02d8aaee1834c30167fe29ddaaa \ + --hash=sha256:b47233bf36749ab63561ece99b8b32684043558415f1e4ca6c540f1793fa12f3 \ + --hash=sha256:b497a46082c3b0e0f9a2571d573e745686ed1a6f7a9c631ebe2b9d6f55ecc87a \ + --hash=sha256:b528e71c3f4b867e207418ea4ed465a111306ac6c2838bf75ff1e465c74ea933 \ + --hash=sha256:b5c66316296044bcdda0fa37296322973c73b708eac737565d5bbc2f6fd51037 \ + --hash=sha256:b6bbca74b7d39d4f259c0eebb6d62fd970999c0beae553db7232319d151fa533 \ + --hash=sha256:b6ff61cd6e3a60ae9bd559aa5ab5a7018e8d26067e7f80ca0ac30e08c76bf983 \ + --hash=sha256:b97376c559d90d80976a2b3c2d1f7699b6e3ae69ffd2bfdefaacf1eb4bc45f8e \ + --hash=sha256:bca06cdbd6d90a939af253ddeed232e7e122a1e027942c2ebd431307e6471be6 \ + --hash=sha256:bd1247b5138e23824b62f96aa03f1d45084dee6c76c46019784546cc432a85ee \ + --hash=sha256:c1726465626bcad9518ff878be9edb6897b42d57c1bfb9e4a00ffd4000980c48 \ + --hash=sha256:c267e531392cbdd900e46796d410dda380c7b311434bf5090ee261bb05650bcc \ + --hash=sha256:c2960742693ee19663bc448328b6b7035f6ae4ad28f57379568d22180911c7d5 \ + --hash=sha256:c55787b0274b1e06530817fe6d375a5443a0e32d5ee55071244fe5af3483fcbc \ + --hash=sha256:c5fb03df1d641d19cec53ee9eb5b89f659d0087d03ae94f06e78e2663824d013 \ + --hash=sha256:c7aa354a62e727b592cfa181a5d435d9a946aba4dd2349bb18fc52c869d470f1 \ + --hash=sha256:c7b849fa2ed07cb59ed5e76d3cf0e3527b7d7bfa2e70d4fcb6df048a9c9177ee \ + --hash=sha256:cac7477518b8cfd53e78527a873be7de5a69183397124f7ebcae295cc39187c1 \ + --hash=sha256:cdc2933960f9b1b160551ff4a0cc543ec3866550ad13f35f1881c22f08b5ad82 \ + --hash=sha256:ce576c6e9a548e09c853e47cb88a95bb29363586c6ec7778ead517e61449b275 \ + --hash=sha256:d698d1354d7e30d3a3fbfb91b7b6c904e13875b4ed2dc40c726ca23d82b5089a \ + --hash=sha256:d6ec69bd053def14e4538b15dcd28bc9528c820b644687c0d38afc38e81fe8e8 \ + --hash=sha256:d717dc455632ab75284969106c4f40cc1533709f852c50d6db643b20e903b23d \ + --hash=sha256:d7d9b2602cccbb92fc6a8b8ab2b1f0f03c77c126e089f22f7747b19499cb3e1d \ + --hash=sha256:de06759a2b223599a98a200b01b9fdafec7e346b513ce6a31632f7089234eca3 \ + --hash=sha256:de7f4782b4381ae5b0dfa36ce1e4b0a925ccecd4f52330fcc50bcd73430b99fd \ + --hash=sha256:df0a3aa46c78e56ebed8c5be33da34c0408d4114c6b782103208fecbd3b6cac0 \ + --hash=sha256:e0fe5c41dac834dfbf1f93f29438393fef13ce250e699d67d2c066da6a0eb8af \ + --hash=sha256:e13dc08bcf7ef257d0635400e3377d3a776ec57ea25e985e903b00bf5ea06911 \ + --hash=sha256:e2e81871fa3353376a35260bf0313e631624eac6997d8fa4d60f38beee3f633f \ + --hash=sha256:e4871a8955ba6c4d80eaffc0f44af6ab724a99f4ec2ad6499243fe542027494f \ + --hash=sha256:e65f8b3029e64af05323cc630550b27649d8b1b612387c2e88411ae32c6a5b59 \ + --hash=sha256:e75704f210e8fbcfbe9546f33d4ef86ff9932830d74726108b45dad72d5c1b55 \ + --hash=sha256:e7f1fa876d3b7c09c1c6be627338502e78d3cc6e9b21ea94f8eeec6ad4157afa \ + --hash=sha256:edec736cfe6b5421e6c0fbf3e4fc70b5db30263d22e070526c7c540f5895f9fb \ + --hash=sha256:f3386c4370515f7acb3372ca49b4bd6652b65c381f50e772b5de96da7df2dbad \ + --hash=sha256:f53dbcc5b1ab75ee593f9ccdd474f9091e21b2051ade79db9930540188f3c9e3 \ + --hash=sha256:f6dad7fe7f004900a45b04ab2ef51dd11a46c7be4b182c2e533810435e197249 \ + --hash=sha256:f6e8fca537eb348409549b75f8721fe911cc001124cc7cbfa1a4722e641584c3 \ + --hash=sha256:f6fb6b3fef1b611841f50688c46d722ad5bd9bb5b9beec9d7c51885519f6026c \ + --hash=sha256:fc012f8738e21462b8b173278ef9278a822373a64f558ac1bfa36eceb56296df \ + --hash=sha256:fedf838627e262a5a3b9312a144582e7c81ff3be986a3b0ecd51b9d904747c0b \ + --hash=sha256:ff693056db843b5e4de6d8e50b4847c116481406492d10517dfe4d7c573c8f82 # via easyocr python-dateutil==2.9.0 \ --hash=sha256:78e73e19c63f5b20ffa567001531680d939dc042bf7850431877645523c66709 \ @@ -4468,10 +5077,12 @@ python-dateutil==2.9.0 \ # botocore # elasticsearch # google-cloud-bigquery + # graphene # great-expectations # ibis-framework # jupyter-client # kubernetes + # matplotlib # moto # openlineage-python # pandas @@ -4484,31 +5095,31 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via + # mlflow-skinny # pydantic-settings # pymilvus # testcontainers # uvicorn -python-json-logger==4.0.0 \ - --hash=sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2 \ - --hash=sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f +python-json-logger==4.1.0 \ + --hash=sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2 \ + --hash=sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195 # via jupyter-events python-keycloak==4.2.2 \ --hash=sha256:1d43a1accd4a038ed39317fcb3eb78211df6c75bbcbc4c482c99ee76327136f2 \ --hash=sha256:5137fd87c69031a372a578df96bae96b9aead2c9dad976613bc978e9e0246a1e # via feast (pyproject.toml) -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ --hash=sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095 # via docling -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via - # clickhouse-connect # great-expectations # pandas # snowflake-connector-python @@ -4597,6 +5208,7 @@ pyyaml==6.0.3 \ # huggingface-hub # jupyter-events # kubernetes + # mlflow-skinny # openlineage-python # openshift-client # pre-commit @@ -4702,30 +5314,30 @@ pyzmq==27.1.0 \ # ipykernel # jupyter-client # jupyter-server -qdrant-client==1.17.0 \ - --hash=sha256:47eb033edb9be33a4babb4d87b0d8d5eaf03d52112dca0218db7f2030bf41ba9 \ - --hash=sha256:f5b452c68c42b3580d3d266446fb00d3c6e3aae89c916e16585b3c704e108438 +qdrant-client==1.18.0 \ + --hash=sha256:093aa8cf8a420ee3ad2a68b007e1378d7992b2600e0b53c193fc172674f659cd \ + --hash=sha256:52e8ece1a7d40519801bf0b70713bfa0f6b7ae28c7275bbe0b0286fbed7f6db4 # via feast (pyproject.toml) -ray[data, default]==2.52.1 \ - --hash=sha256:08eb8f5fd55292ba6bee363a32491136a5e54af54e007f81e0603986fbea41a4 \ - --hash=sha256:24694e60cdc7770b90f123cc578cabb9d1a231c1fe673b5da0027b118de45846 \ - --hash=sha256:2b57ef272a2a0a0dbae6d18d70aa541eab620b4fe3b44d50466d3a533c16f9d9 \ - --hash=sha256:4e8478544fef69a17d865431c0bebdcfeff7c0f76a306f29b73c3bc3cbb0bdb9 \ - --hash=sha256:65bf461fdfe4ffa667c46f9455f8740b2ad6c1fa471b461d5f5cf6b7baf177b5 \ - --hash=sha256:6831592fedf0a122016f5dab4b67d85fa3d4db3b21f588d18834b5c031396d1c \ - --hash=sha256:8045172ad3fcff62b9dab9a4cd2e0991ad0e27fc814fe625a8d3a120306651d6 \ - --hash=sha256:843c0108ad72bb7fc6c23a22e29e6099546a5eaad3ad675c78a146d9080f6ec6 \ - --hash=sha256:993194a8be70540e0f819862031bbf19a64401fbe6c31b42065fd313ba466d34 \ - --hash=sha256:a5a3c268d45060c50cd029979ecc5f1eaaec040b19fa88dd4fe9e927d19ff13e \ - --hash=sha256:b3f9e61b799fb3cc8fd7077a3d2eb676ddfef7db644f6b6a2b657c5c3214cf19 \ - --hash=sha256:b5bc29548abb0a0a7ae9e6ff3b0ccca2824edaf011a4336e15a32793d574fbfd \ - --hash=sha256:bbe492c780a39a64bd3d0766cad10d54cf12222df88d287ec2d8f2d52de37c79 \ - --hash=sha256:e3826aeb4e4399de0c6885bd8be7ce2f629fa0010f0013f1183e0726b3d25e40 \ - --hash=sha256:f59e3b2d1a1466ac0778f2c6fac9ccb5f30107d77e3dddd1d60167248d268474 +ray[data, default]==2.54.1 \ + --hash=sha256:054985194bd32f4464c93f9318d247fac61e1f32ac221565ecfdc81ab8c75d0b \ + --hash=sha256:0c3ae2943176e7b239c78b825a5b2bf4135d90280083a0e19c0a75a5db4d836f \ + --hash=sha256:2766f0230806480c38a9a94502087f1d4aea919f38521a28781690613b0290a4 \ + --hash=sha256:2ea650e648acc6e76edd98c694657fd1fcb1cd97700d944a7d20da90269e9810 \ + --hash=sha256:4c6f7e23dda62a32f94083141c3f97e9c4246e3ae4ae2bc488bcd8fd0311f54a \ + --hash=sha256:512587412e2f5e1753adabfdfa4dd9cff1dc509601e36fd5fab671e448ae4dac \ + --hash=sha256:6425f15cfe6a298366b53c8658350f94ced2c548802ca3b69f94b87db16e97c5 \ + --hash=sha256:645ebfb73cfd32bd510a05ed9f2738a18d6db69929cae9701d749f2740dbfd9a \ + --hash=sha256:673a895c0c4a716ed772552baa3f5b8d7d1f7a4b34e04787fdfe6fe3049ed0d8 \ + --hash=sha256:86c51eafd3e84dad59c1ef4cf97b3ac8c088af0705782ee915e31bca5880597a \ + --hash=sha256:c0240496af274af7cd3b1b1d015f23b88e5fdafe59bfdc040e5f229e0aff5dff \ + --hash=sha256:cd452b61ae2e0daf9271f5a554614397429cc2731681bae10fe72316dadc2749 \ + --hash=sha256:d05f477d1518a00fd5880644e889a7a3eaf64ae5d1f8f239a682d052ad2a383d \ + --hash=sha256:e095dfe9c521a04e5930520b4a82ea82d61903d4cd2f3270fbc5dfbdb41b9c72 \ + --hash=sha256:ea90bed0110e0ce3ff6571e7a0c800920a3c6d299d29b8eac020dac362667169 # via codeflare-sdk -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4734,131 +5346,132 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.2.28 \ - --hash=sha256:00945d007fd74a9084d2ab79b695b595c6b7ba3698972fadd43e23230c6979c1 \ - --hash=sha256:00f2b8d9615aa165fdff0a13f1a92049bfad555ee91e20d246a51aa0b556c60a \ - --hash=sha256:01d65fd24206c8e1e97e2e31b286c59009636c022eb5d003f52760b0f42155d4 \ - --hash=sha256:02473c954af35dd2defeb07e44182f5705b30ea3f351a7cbffa9177beb14da5d \ - --hash=sha256:03a83cc26aa2acda6b8b9dfe748cf9e84cbd390c424a1de34fdcef58961a297a \ - --hash=sha256:09500be324f49b470d907b3ef8af9afe857f5cca486f853853f7945ddbf75911 \ - --hash=sha256:0b1d2b07614d95fa2bf8a63fd1e98bd8fa2b4848dc91b1efbc8ba219fdd73952 \ - --hash=sha256:0d25a10811de831c2baa6aef3c0be91622f44dd8d31dd12e69f6398efb15e48b \ - --hash=sha256:0d5bef2031cbf38757a0b0bc4298bb4824b6332d28edc16b39247228fbdbad97 \ - --hash=sha256:10d28e19bd4888e4abf43bd3925f3c134c52fdf7259219003588a42e24c2aa25 \ - --hash=sha256:180e08a435a0319e6a4821c3468da18dc7001987e1c17ae1335488dfe7518dd8 \ - --hash=sha256:195237dc327858a7721bf8b0bbbef797554bc13563c3591e91cd0767bacbe359 \ - --hash=sha256:19a9c9e0a8f24f39d575a6a854d516b48ffe4cbdcb9de55cb0570a032556ecff \ - --hash=sha256:1c2c95e1a2b0f89d01e821ff4de1be4b5d73d1f4b0bf679fa27c1ad8d2327f1a \ - --hash=sha256:1d367257cd86c1cbb97ea94e77b373a0bbc2224976e247f173d19e8f18b4afa7 \ - --hash=sha256:1e496956106fd59ba6322a8ea17141a27c5040e5ee8f9433ae92d4e5204462a0 \ - --hash=sha256:1f8b17be5c27a684ea6759983c13506bd77bfc7c0347dff41b18ce5ddd2ee09a \ - --hash=sha256:2234059cfe33d9813a3677ef7667999caea9eeaa83fef98eb6ce15c6cf9e0215 \ - --hash=sha256:25b6eb660c5cf4b8c3407a1ed462abba26a926cc9965e164268a3267bcc06a43 \ - --hash=sha256:2954379dd20752e82d22accf3ff465311cbb2bac6c1f92c4afd400e1757f7451 \ - --hash=sha256:2afa673660928d0b63d84353c6c08a8a476ddfc4a47e11742949d182e6863ce8 \ - --hash=sha256:2b2b23587b26496ff5fd40df4278becdf386813ec00dc3533fa43a4cf0e2ad3c \ - --hash=sha256:2fb950ac1d88e6b6a9414381f403797b236f9fa17e1eee07683af72b1634207b \ - --hash=sha256:3935174fa4d9f70525a4367aaff3cb8bc0548129d114260c29d9dfa4a5b41692 \ - --hash=sha256:39bb5727650b9a0275c6a6690f9bb3fe693a7e6cc5c3155b1240aedf8926423e \ - --hash=sha256:3b24bd7e9d85dc7c6a8bd2aa14ecd234274a0248335a02adeb25448aecdd420d \ - --hash=sha256:4390c365fd2d45278f45afd4673cb90f7285f5701607e3ad4274df08e36140ae \ - --hash=sha256:481df4623fa4969c8b11f3433ed7d5e3dc9cec0f008356c3212b3933fb77e3d8 \ - --hash=sha256:4f5c0b182ad4269e7381b7c27fdb0408399881f7a92a4624fd5487f2971dfc11 \ - --hash=sha256:50c2fc924749543e0eacc93ada6aeeb3ea5f6715825624baa0dccaec771668ae \ - --hash=sha256:511f7419f7afab475fd4d639d4aedfc54205bcb0800066753ef68a59f0f330b5 \ - --hash=sha256:516604edd17b1c2c3e579cf4e9b25a53bf8fa6e7cedddf1127804d3e0140ca64 \ - --hash=sha256:52b017b35ac2214d0db5f4f90e303634dc44e4aba4bd6235a27f97ecbe5b0472 \ - --hash=sha256:5a932ea8ad5d0430351ff9c76c8db34db0d9f53c1d78f06022a21f4e290c5c18 \ - --hash=sha256:5cdcc17d935c8f9d3f4db5c2ebe2640c332e3822ad5d23c2f8e0228e6947943a \ - --hash=sha256:5d10303dd18cedfd4d095543998404df656088240bcfd3cd20a8f95b861f74bd \ - --hash=sha256:5e68192bb3a1d6fb2836da24aa494e413ea65853a21505e142e5b1064a595f3d \ - --hash=sha256:64e7c6ad614573e0640f271e811a408d79a9e1fe62a46adb602f598df42a818d \ - --hash=sha256:6591f281cb44dc13de9585b552cec6fc6cf47fb2fe7a48892295ee9bc4a612f9 \ - --hash=sha256:69fc560ccbf08a09dc9b52ab69cacfae51e0ed80dc5693078bdc97db2f91ae96 \ - --hash=sha256:6d63a07e5ec8ce7184452cb00c41c37b49e67dc4f73b2955b5b8e782ea970784 \ - --hash=sha256:6db7bfae0f8a2793ff1f7021468ea55e2699d0790eb58ee6ab36ae43aa00bc5b \ - --hash=sha256:71a911098be38c859ceb3f9a9ce43f4ed9f4c6720ad8684a066ea246b76ad9ff \ - --hash=sha256:73cdcdbba8028167ea81490c7f45280113e41db2c7afb65a276f4711fa3bcbff \ - --hash=sha256:78454178c7df31372ea737996fb7f36b3c2c92cccc641d251e072478afb4babc \ - --hash=sha256:7900157786428a79615a8264dac1f12c9b02957c473c8110c6b1f972dcecaddf \ - --hash=sha256:7ab218076eb0944549e7fe74cf0e2b83a82edb27e81cc87411f76240865e04d5 \ - --hash=sha256:7c1b34dfa72f826f535b20712afa9bb3ba580020e834f3c69866c5bddbf10098 \ - --hash=sha256:851fa70df44325e1e4cdb79c5e676e91a78147b1b543db2aec8734d2add30ec2 \ - --hash=sha256:864cdd1a2ef5716b0ab468af40139e62ede1b3a53386b375ec0786bb6783fc05 \ - --hash=sha256:8710d61737b0c0ce6836b1da7109f20d495e49b3809f30e27e9560be67a257bf \ - --hash=sha256:9036b400b20e4858d56d117108d7813ed07bb7803e3eed766675862131135ca6 \ - --hash=sha256:9185cc63359862a6e80fe97f696e04b0ad9a11c4ac0a4a927f979f611bfe3768 \ - --hash=sha256:948c12ef30ecedb128903c2c2678b339746eb7c689c5c21957c4a23950c96d15 \ - --hash=sha256:94d63db12e45a9b9f064bfe4800cefefc7e5f182052e4c1b774d46a40ab1d9bb \ - --hash=sha256:96f6269a2882fbb0ee76967116b83679dc628e68eaea44e90884b8d53d833881 \ - --hash=sha256:97054c55db06ab020342cc0d35d6f62a465fa7662871190175f1ad6c655c028f \ - --hash=sha256:98adf340100cbe6fbaf8e6dc75e28f2c191b1be50ffefe292fb0e6f6eefdb0d8 \ - --hash=sha256:99985a2c277dcb9ccb63f937451af5d65177af1efdeb8173ac55b61095a0a05c \ - --hash=sha256:9b65d33a17101569f86d9c5966a8b1d7fbf8afdda5a8aa219301b0a80f58cf7d \ - --hash=sha256:9dd450db6458387167e033cfa80887a34c99c81d26da1bf8b0b41bf8c9cac88e \ - --hash=sha256:a25c7701e4f7a70021db9aaf4a4a0a67033c6318752146e03d1b94d32006217e \ - --hash=sha256:a448af01e3d8031c89c5d902040b124a5e921a25c4e5e07a861ca591ce429341 \ - --hash=sha256:a5dac14d0872eeb35260a8e30bac07ddf22adc1e3a0635b52b02e180d17c9c7e \ - --hash=sha256:a729e47d418ea11d03469f321aaf67cdee8954cde3ff2cf8403ab87951ad10f2 \ - --hash=sha256:aaffaecffcd2479ce87aa1e74076c221700b7c804e48e98e62500ee748f0f550 \ - --hash=sha256:b059e71ec363968671693a78c5053bd9cb2fe410f9b8e4657e88377ebd603a2e \ - --hash=sha256:b387a0d092dac157fb026d737dde35ff3e49ef27f285343e7c6401851239df27 \ - --hash=sha256:b389c61aa28a79c2e0527ac36da579869c2e235a5b208a12c5b5318cda2501d8 \ - --hash=sha256:b42f7466e32bf15a961cf09f35fa6323cc72e64d3d2c990b10de1274a5da0a59 \ - --hash=sha256:b49eb78048c6354f49e91e4b77da21257fecb92256b6d599ae44403cab30b05b \ - --hash=sha256:b5acd4b6a95f37c3c3828e5d053a7d4edaedb85de551db0153754924cb7c83e3 \ - --hash=sha256:b8b3f1be1738feadc69f62daa250c933e85c6f34fa378f54a7ff43807c1b9117 \ - --hash=sha256:b8cf76f1a29f0e99dcfd7aef1551a9827588aae5a737fe31442021165f1920dc \ - --hash=sha256:ba55c50f408fb5c346a3a02d2ce0ebc839784e24f7c9684fde328ff063c3cdea \ - --hash=sha256:bba2b18d70eeb7b79950f12f633beeecd923f7c9ad6f6bae28e59b4cb3ab046b \ - --hash=sha256:bbb882061f742eb5d46f2f1bd5304055be0a66b783576de3d7eef1bed4778a6e \ - --hash=sha256:bcb399ed84eabf4282587ba151f2732ad8168e66f1d3f85b1d038868fe547703 \ - --hash=sha256:bd477d5f79920338107f04aa645f094032d9e3030cc55be581df3d1ef61aa318 \ - --hash=sha256:bec23c11cbbf09a4df32fe50d57cbdd777bc442269b6e39a1775654f1c95dee2 \ - --hash=sha256:c0b5ccbb8ffb433939d248707d4a8b31993cb76ab1a0187ca886bf50e96df952 \ - --hash=sha256:c15af43c72a7fb0c97cbc66fa36a43546eddc5c06a662b64a0cbf30d6ac40944 \ - --hash=sha256:c7815afb0ca45456613fdaf60ea9c993715511c8d53a83bc468305cbc0ee23c7 \ - --hash=sha256:cb3b1db8ff6c7b8bf838ab05583ea15230cb2f678e569ab0e3a24d1e8320940b \ - --hash=sha256:d0b02e8b7e5874b48ae0f077ecca61c1a6a9f9895e9c6dfb191b55b242862033 \ - --hash=sha256:d6b08a06976ff4fb0d83077022fde3eca06c55432bb997d8c0495b9a4e9872f4 \ - --hash=sha256:d6cfe798d8da41bb1862ed6e0cba14003d387c3c0c4a5d45591076ae9f0ce2f8 \ - --hash=sha256:d8511a01d0e4ee1992eb3ba19e09bc1866fe03f05129c3aec3fdc4cbc77aad3f \ - --hash=sha256:dc8ed8c3f41c27acb83f7b6a9eb727a73fc6663441890c5cb3426a5f6a91ce7d \ - --hash=sha256:dd8847c4978bc3c7e6c826fb745f5570e518b8459ac2892151ce6627c7bc00d5 \ - --hash=sha256:de0cf053139f96219ccfabb4a8dd2d217c8c82cb206c91d9f109f3f552d6b43d \ - --hash=sha256:dee50f1be42222f89767b64b283283ef963189da0dda4a515aa54a5563c62dec \ - --hash=sha256:e1e7b24cb3ae9953a560c563045d1ba56ee4749fbd05cf21ba571069bd7be81b \ - --hash=sha256:e59bc8f30414d283ae8ee1617b13d8112e7135cb92830f0ec3688cb29152585a \ - --hash=sha256:e61eea47230eba62a31f3e8a0e3164d0f37ef9f40529fb2c79361bc6b53d2a92 \ - --hash=sha256:e621fb7c8dc147419b28e1702f58a0177ff8308a76fa295c71f3e7827849f5d9 \ - --hash=sha256:e71dcecaa113eebcc96622c17692672c2d104b1d71ddf7adeda90da7ddeb26fc \ - --hash=sha256:e7ce83654d1ab701cb619285a18a8e5a889c1216d746ddc710c914ca5fd71022 \ - --hash=sha256:e8c8cb2deba42f5ec1ede46374e990f8adc5e6456a57ac1a261b19be6f28e4e6 \ - --hash=sha256:ec0c608b7a7465ffadb344ed7c987ff2f11ee03f6a130b569aa74d8a70e8333c \ - --hash=sha256:ec6f5674c5dc836994f50f1186dd1fafde4be0666aae201ae2fcc3d29d8adf27 \ - --hash=sha256:edb1b1b3a5576c56f08ac46f108c40333f222ebfd5cf63afdfa3aab0791ebe5b \ - --hash=sha256:ef77bdde9c9eba3f7fa5b58084b29bbcc74bcf55fdbeaa67c102a35b5bd7e7cc \ - --hash=sha256:f2791948f7c70bb9335a9102df45e93d428f4b8128020d85920223925d73b9e1 \ - --hash=sha256:f467cb602f03fbd1ab1908f68b53c649ce393fde056628dc8c7e634dab6bfc07 \ - --hash=sha256:f8ed9a5d4612df9d4de15878f0bc6aa7a268afbe5af21a3fdd97fa19516e978c \ - --hash=sha256:fa539be029844c0ce1114762d2952ab6cfdd7c7c9bd72e0db26b94c3c36dcc5a \ - --hash=sha256:fb1c4ff62277d87a7335f2c1ea4e0387b8f2b3ad88a64efd9943906aafad4f33 \ - --hash=sha256:fb4db2f17e6484904f986c5a657cec85574c76b5c5e61c7aae9ffa1bc6224f95 \ - --hash=sha256:fb66e5245db9652abd7196ace599b04d9c0e4aa7c8f0e2803938377835780081 \ - --hash=sha256:fc48c500838be6882b32748f60a15229d2dea96e59ef341eaa96ec83538f498d \ - --hash=sha256:fcf26c3c6d0da98fada8ae4ef0aa1c3405a431c0a77eb17306d38a89b02adcd7 \ - --hash=sha256:fd0ce43e71d825b7c0661f9c54d4d74bd97c56c3fd102a8985bcfea48236bacb \ - --hash=sha256:fd63453f10d29097cc3dc62d070746523973fb5aa1c66d25f8558bebd47fed61 +regex==2026.5.9 \ + --hash=sha256:002205cafd2a9e78c6290c7d1df277bf3277b3b7a30e0b4bb0dac2e2e3f7cb2d \ + --hash=sha256:01f0f5f55f4b64dacec85dc116d3c05fd23ad3ff037bbc73a2085775953c2611 \ + --hash=sha256:01f28d868834624c934b8d2e0aa1c8341337e37831f4a012f18a5afcba4cbaf3 \ + --hash=sha256:075160bf16658e16d35233300b8453aac25de4cbea808d22348b6979668e924d \ + --hash=sha256:0de5cf193997384ed2ca6f1cd4f78055b255d93d82d5a8cd6ba0d11c10b167e4 \ + --hash=sha256:0e1b1b4e496afbb24f4a62aba855ee4f88f25578927697b340702e48c9ee6bc2 \ + --hash=sha256:0f03aa6898aaaac4592479821df16e68e8d0e29e903e65d8f2dfb2f19028a989 \ + --hash=sha256:0f9eede6a5cbdc02d4978090186390936e1776a7d1359b21e41014c609880bcf \ + --hash=sha256:1268eddd8486dc561d08eee1156e40aa3a8fe10f4bdec8fa653b455fcbffd12c \ + --hash=sha256:15ee42209947f4ca045412eae98416317238163618ace2a8e54f99586a466733 \ + --hash=sha256:164eba9b755ea6f244b0d881196fbc1fac09714e9782c9e2732b813142033c8e \ + --hash=sha256:19c16ceb4a267a8789e25733e583983eeab9f0f8664e66b0bd1c5d21f14c2d4b \ + --hash=sha256:1bd7587a2948b4085195d5a3374eaf4a425dc3e55784c038175355ecf3bbbf8a \ + --hash=sha256:1e6da47d679b7010ef27556b6e0f99771b744936db1792a10ceac6547ae1503e \ + --hash=sha256:205109e96b3cf5adf8f4cd62bedde9487feb282b9497a3535451e5a24cd706a0 \ + --hash=sha256:2099f7e7ff7b6aa3192312650a56e91cc091e49d50b04e4f6f8b6e28b3b27f1c \ + --hash=sha256:246de9d60aa3f8538b519834dd95cbf276ea263d6a7bd5a3666dc3fa0230505b \ + --hash=sha256:24b2355ef5cc9aa5b8f07d17704face1c166fdcc2290fa7bd6e6c925655a8346 \ + --hash=sha256:2a661a7d270a61f7cf460caee8b9fa2d5ef9e5c681234bcb9e0fe14f488e7dfc \ + --hash=sha256:2acfb48634f64996b57f90f39afa692ff362162722581921fe92239a59960f3c \ + --hash=sha256:2efa205e6d98b24d1f3ab395c11aa15cdf10935bca283d0285e0499c284fba21 \ + --hash=sha256:31037c82eccb44b7ea2e9e221d7c01429430e989a1f4b91ea5a855f6017b509a \ + --hash=sha256:3527bb4942d2c14552155406cdedd906567456821848aed1cb4933a391bf5eca \ + --hash=sha256:39617fb0cde9c0e6306dc70e3bfc096f3da793219879f7ae7aa341a69fbdcf6d \ + --hash=sha256:398c521292f4c7fb807001dcd54694d3a1fcafc179a36ad9cc56f98df85930b6 \ + --hash=sha256:3b1e39888c5e0c7d92cea4fc777396c4a90363b05de75d02eb459a4752200808 \ + --hash=sha256:3dd4a3ff360dfb836fecdb93a4598f9d6e2ac81e3e397125145c6221bf58cf4c \ + --hash=sha256:3ddd90103f9e5c471c49c7852ecc1fe27c7e45eb99e977aefe7caa4e779f4f58 \ + --hash=sha256:446ddd671e43ab535810c4b21cff7104945c701d4a14d1e6d1cd6f4e445a8bea \ + --hash=sha256:45375819235558a4ff1c4971dc32881f022613abdb180128f5cb4768c1765a1c \ + --hash=sha256:46f1326ca6e65b0879d23ca302c0f2415aad42ff0309b9c818e7949fe19a41d8 \ + --hash=sha256:48036f6374aaa79eb3b754ec29c61d1c6b1606749d705a13f8854fa2539671f6 \ + --hash=sha256:4ebe8f0b5ec5a5024dc4a4c59f444c4e9afc5f2abdbb8962065b75d27fb971f9 \ + --hash=sha256:4eeb011098fcb77af513dcef521a3dbecbf8849b1e38940759d293b7a93f5026 \ + --hash=sha256:508f56a89ba9cb26e4168cbc37dbd60a28d82430a9e18ad1d25fe0883c314ca2 \ + --hash=sha256:5604dfd046dc37eca90250fc3be938b076c8059fa772ac0ed6f499b0f0fb0415 \ + --hash=sha256:56a33f191f17d8c417f99945ebdc1e691d3af9605d86ec68c7e54a57e3e17af6 \ + --hash=sha256:57e8915c7986aa33d25e4d3629cef711cd2863f2961b10409f0c04cb8b7d9020 \ + --hash=sha256:57eeeb05db7979413dec5438f2db21d7ecbba787cde7a711df1a6f6df672aa06 \ + --hash=sha256:5b73ab8afcf66c622db143d1c6fda4e58e4d537ee4f125229ad47b1ab80f34c0 \ + --hash=sha256:5e41809d2683fcde7d5a8c87a6567ba1fb1ce0de9f31bff578de00a4b2d76daa \ + --hash=sha256:6351571c8a42b505eb555c0dc47d740d0fb66977dc142919eea6f4325b7c56a0 \ + --hash=sha256:6441cc660d76107934a09c22167200839a0e89604a6297f78a974e66e931d2c0 \ + --hash=sha256:65c8c8c37377794bd5b2f3ebe51919042bf17aec802e23c833d89782ed0c78af \ + --hash=sha256:6ba42b2e7e7f46cf68cc6a5ca36fa07959f9bbd9c6bdcc47b6ee76549a590248 \ + --hash=sha256:71b61c5bfe1c806332defc42ad6c780b3c55f661986d7f40283a3a88274b4c00 \ + --hash=sha256:728d8bfd28a8845c8b6bc5dc7ce010453d206396786c0765c2740cb65f37791e \ + --hash=sha256:7b92817338591505f282cf3864c145244b1edcf5381d237038df955001091538 \ + --hash=sha256:7e30b874d341fac767d7df5a0870540541c2c054b80cfaac116e8d367a8a7ff2 \ + --hash=sha256:7e87577720152d2caae19fe2baaf1f8d5ca12091e9e229f03915c37d1e4b9178 \ + --hash=sha256:83d0ee4a57d1c87cb549e195ec300b8f0ec3a82eba66d835e4e2ed8634fe4499 \ + --hash=sha256:8676474c07469d6f33dd1085ca2cd45f65785f32518f2b20e36d9953ca07f994 \ + --hash=sha256:86f40a5d6444db30a125c9c9177e6b25dad981cbc37451fd838f145e6edac92e \ + --hash=sha256:872acc074bd29ffc9913ecdfedf6ea77502312ca44a4aa0d3779089c6069d8de \ + --hash=sha256:8abd33fef90b2a9efac5557d6033ca82d1195ed3a15fea5af15ba7b463c6a63b \ + --hash=sha256:8c6e4218fbdfbcd4f6c19efca40930d24a621bf4b48cb76bc6640543bd28ef20 \ + --hash=sha256:8e76e8161ad00694cfce6767d5dea860c6391ac5b83e5c3a39661e696f11fc7e \ + --hash=sha256:8f3af7a4903c5c04a11a196a5aa75cdd7dd3f8508132f9fb3259d9f5908e3b88 \ + --hash=sha256:91328f1c23d47595ca3ef0a7557fa129c5a23404b775c770697d2f35b33e0107 \ + --hash=sha256:916714069da19329ef7de197dcbc77bb3104145c7c2c864dbfbe318f46b88b14 \ + --hash=sha256:93a7860539414dddaefba2b40f8771765ae17949d4c7182b876ce429e11a8309 \ + --hash=sha256:954cc214c04663ee6d266fc61739cad83054683048de65c5bd1d640ad28098ac \ + --hash=sha256:96f5f58b54a063d7ea9dca08e1cf57bfe10499c4d579ee672da284f57f5f0070 \ + --hash=sha256:97cf3bc1b7d7d2306772ec07366c80d9df00ff79e79cea32898883a646d2fae2 \ + --hash=sha256:98bd73080e8756255137e1bd3f3f00295bbc5aa383c0e0f973920e9134d7c4ad \ + --hash=sha256:992604d02e6d9c6d786c24a706a71ecffe1020fc1ef264044474cd81fa2c3919 \ + --hash=sha256:a24852d3c29ad9e47593593d8a247c44ccc3d0548ef12c822d6ed0810affe676 \ + --hash=sha256:a6a563446a41adc451393dc6b8e6ad87979efaee3c8738690a8d1b08ebead1b4 \ + --hash=sha256:a8234aa23ec39894bfe4a3f1b85616a7032481964a13ac6fc9f10de4f6fca270 \ + --hash=sha256:a8820737949116ffff55fe18f9fc644530063ba6ebfcb8314239416e78f1347c \ + --hash=sha256:a9e1328e17c84c1a5d22ec9f785ecef4a967fab9a42b6a8dc3bcbebd0a0c9e44 \ + --hash=sha256:aa0fbdbac82cb3e4450d0ccde7d7a35607f4cb2dd9fba4b8b69bfaf8c9fa6aed \ + --hash=sha256:b310768746dd314ea6e2ff4cc89ef215426813396ff4e94ee8e6f7096c8b6e03 \ + --hash=sha256:b46b0f094dc1d3b90356c85a0bd2c9bafc4a6a190b9d6f8ddd5a033b6e088ed4 \ + --hash=sha256:b4bb445ff3f725f59df8f6014edb547ee928ec7023a774f6a39a3f953038cbb2 \ + --hash=sha256:b6d189041f15691cfa2b6c4290448ec221244d225b3f5fe9e7771b34ffcdf6e2 \ + --hash=sha256:b96350aa424e79d4fd6b567b344dcbe2b2d6bfc48dfe7717587e1fa6d43da6ff \ + --hash=sha256:be3372b9df6ddecff6486d37e19095a7b4973137caf5512407a89f4455361f41 \ + --hash=sha256:bfe1ce50cbfb569d74e1e4337da6468961f31dbea55fd85aa5de59c0947a805a \ + --hash=sha256:c010eb8caca74bdb40c07498d7ece26b4428fd3f04aa8a72c9ac6f79e8faaac6 \ + --hash=sha256:c8b9b9d294cfea3cd19c718ade7cc93492b2c4991abd9a68d0b3477ae6d8e100 \ + --hash=sha256:c9411dd64ca95477225734a93dfc8583b51916b8d5942f99d6cac21e09965451 \ + --hash=sha256:ca518ed29c46eecba6010b15f1b9a479314d2de409536e71b6a13aa04e3b8a77 \ + --hash=sha256:ccf5249114cc3e772ecdd88a98a86eca0fd74c61ce32a94743758c083fc05d48 \ + --hash=sha256:cd2846168eb9ee3c513902bc8225409cb1caab31d04728b145171fa1625d9621 \ + --hash=sha256:d29eebfc9525db68cad3c97eedd7f754fa265aa5cd0cf4f863b2421e1b48fc9f \ + --hash=sha256:d3d7eb5c9a7f6df82ed3cfac9beb93882a5cbcb5b8b157b56cb2b3b276574ac1 \ + --hash=sha256:d626b84406444b165fc0ba981604edea39f0588ff1f92baa23fe50799ea9afdb \ + --hash=sha256:d641a8c9a61618047796d572a39a79b26167b0411d2c3031937b2fe2d081e2cf \ + --hash=sha256:d659eee77986549c9ea45b861c7567e44d6287c3dc9a4565478853f7b9fe2ff6 \ + --hash=sha256:d6b8a143aca6c39b446ea8092cde25cc8fe9304d4f5fecfbc1a9dbb0282703c2 \ + --hash=sha256:d726ca3f0d76969bf1e8e477d160d3d666bbf999f6860bd314889e5345782046 \ + --hash=sha256:d7bdc0ab8f3dd7e1b4f9ab88634e13374669db86bb3c72e8292f07ae313f539f \ + --hash=sha256:daff2bdbaf1d23e52fdff7c0b7bc2048b68f978df6a4d107ac981f94caef2e66 \ + --hash=sha256:dd2810d22146b6d838acc5ec15602cb6b47920aa4e33015df3868eedfd20bab8 \ + --hash=sha256:ddda5340e6c01a293027dd46232fa79eaff1b48058ce7a98f572b6445b088041 \ + --hash=sha256:dea2e88e1cce4522496cce630e11e67b98b7076620bc4336c3f674bc21a375f4 \ + --hash=sha256:debb893095e944091c16e641a6e33c1b0f4cb61ab945ec5afbf53ce7068834d8 \ + --hash=sha256:dfbe4579b9f08036aa7d101d1835437a20783574ac66327e6b29b4018a138081 \ + --hash=sha256:e1d93bf647916292e8edcec150c07ddf3dc50179ccaf770c04a7f9e452155372 \ + --hash=sha256:e82db382b44d0111b22601c509c89f64434816c9e0eef9d1989cda8cc6ff1c04 \ + --hash=sha256:ea9c8ecfa1b73c73b626534d6626e5340d429630943672b8480724f44e84b962 \ + --hash=sha256:ead4b163ac30a29574510cd4b3e2e985ac5290c05fc7095557d6a5f403fc31b5 \ + --hash=sha256:ecd353045824e4477562a2ac718c25799cdaaa41f7aa925a806a8a3e6848a5b9 \ + --hash=sha256:ed2c9e8068b614c574d8d30e543d617cf5379b0535d46f97ef00e904745a08b5 \ + --hash=sha256:ed457d8e98ae812ed7732bef7bf78de78e834eae0372a74e23ca90ef21d910f9 \ + --hash=sha256:ef31cbfe458e21c6122ba8150ff060e0c7789ed0d26eb423f25472584920b555 \ + --hash=sha256:f079e50a0d3cc3cd5091fa9ff45869a2e6b2cd35895731edafb0327901a8d86d \ + --hash=sha256:f3844f134e834076677dd369976e9f5068679fcb8e50102fdf6b7ac96a3ec127 \ + --hash=sha256:f7a7c26137296beba7784de6eba69c6a93a63ccebc385e4962fe67e267a91225 \ + --hash=sha256:fa411799ca8da32a8d38d020a88faa5b6f91657d284761352940ecf9f7c3bbdd \ + --hash=sha256:fd03c4f0e33280d15cae17159b899245d6b7c53d21def19b263b39655061f5ce \ + --hash=sha256:fd190e88a895a8901325fad284a3f74ea52b1da8525b76cc811fa9b1edf0ce2b \ + --hash=sha256:ff8d372ac2acdc048d1c19916f27ee61bc5722728458ba6ca5052f2c72d51763 # via # feast (pyproject.toml) # parsimonious # transformers -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # azure-core + # databricks-sdk # datasets # docker # docling @@ -4869,10 +5482,13 @@ requests==2.32.5 \ # great-expectations # huggingface-hub # jupyterlab-server + # kube-authkit # kubernetes + # mlflow-skinny # moto # msal # openlineage-python + # pymilvus # python-keycloak # ray # requests-oauthlib @@ -4893,9 +5509,9 @@ requests-toolbelt==1.0.0 \ --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \ --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 # via python-keycloak -responses==0.26.0 \ - --hash=sha256:03ec4409088cd5c66b71ecbbbd27fe2c58ddfad801c66203457b3e6a04868c37 \ - --hash=sha256:c7f6923e6343ef3682816ba421c006626777893cb0d5e1434f674b649bac9eb4 +responses==0.26.1 \ + --hash=sha256:2eb3218553cc8f79b57d257bac23af5e1bf381f5b9390b1767816f0843e01dc2 \ + --hash=sha256:8aacc4586eb08fb2208ef64a9eb4258d9b0c6e6f4260845f2f018ab847495345 # via moto rfc3339-validator==0.1.4 \ --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ @@ -4913,137 +5529,148 @@ rfc3987-syntax==1.1.0 \ --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d # via jsonschema -rich==13.9.4 \ - --hash=sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098 \ - --hash=sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90 +rich==14.3.4 \ + --hash=sha256:07e7adb4690f68864777b1450859253bed81a99a31ac321ac1817b2313558952 \ + --hash=sha256:817e02727f2b25b40ef56f5aa2217f400c8489f79ca8f46ea2b70dd5e14558a9 # via # codeflare-sdk # fastapi-mcp # ibis-framework # typer -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth rtree==1.4.1 \ --hash=sha256:12de4578f1b3381a93a655846900be4e3d5f4cd5e306b8b00aa77c1121dc7e8c \ --hash=sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0 \ @@ -5061,29 +5688,29 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.5 \ - --hash=sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752 \ - --hash=sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681 \ - --hash=sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204 \ - --hash=sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c \ - --hash=sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd \ - --hash=sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080 \ - --hash=sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74 \ - --hash=sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2 \ - --hash=sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe \ - --hash=sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010 \ - --hash=sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8 \ - --hash=sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca \ - --hash=sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2 \ - --hash=sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b \ - --hash=sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65 \ - --hash=sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a \ - --hash=sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d \ - --hash=sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440 +ruff==0.15.16 \ + --hash=sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a \ + --hash=sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3 \ + --hash=sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071 \ + --hash=sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec \ + --hash=sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628 \ + --hash=sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8 \ + --hash=sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e \ + --hash=sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2 \ + --hash=sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb \ + --hash=sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123 \ + --hash=sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121 \ + --hash=sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951 \ + --hash=sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf \ + --hash=sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb \ + --hash=sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d \ + --hash=sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78 \ + --hash=sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a \ + --hash=sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4 # via feast (pyproject.toml) -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 safetensors[torch]==0.7.0 \ --hash=sha256:0071bffba4150c2f46cae1432d31995d77acfd9f8db598b5d1a2ce67e8440ad2 \ @@ -5165,45 +5792,43 @@ scikit-image==0.26.0 \ --hash=sha256:f775f0e420faac9c2aa6757135f4eb468fb7b70e0b67fa77a5e79be3c30ee331 \ --hash=sha256:fac96a1f9b06cd771cbbb3cd96c5332f36d4efd839b1d8b053f79e5887acde62 # via easyocr -scikit-learn==1.8.0 \ - --hash=sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2 \ - --hash=sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a \ - --hash=sha256:146b4d36f800c013d267b29168813f7a03a43ecd2895d04861f1240b564421da \ - --hash=sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9 \ - --hash=sha256:2838551e011a64e3053ad7618dda9310175f7515f1742fa2d756f7c874c05961 \ - --hash=sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6 \ - --hash=sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271 \ - --hash=sha256:35c007dedb2ffe38fe3ee7d201ebac4a2deccd2408e8621d53067733e3c74809 \ - --hash=sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242 \ - --hash=sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4 \ - --hash=sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7 \ - --hash=sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76 \ - --hash=sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6 \ - --hash=sha256:5e30adb87f0cc81c7690a84f7932dd66be5bac57cfe16b91cb9151683a4a2d3b \ - --hash=sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e \ - --hash=sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7 \ - --hash=sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e \ - --hash=sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57 \ - --hash=sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735 \ - --hash=sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb \ - --hash=sha256:8c497fff237d7b4e07e9ef1a640887fa4fb765647f86fbe00f969ff6280ce2bb \ - --hash=sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e \ - --hash=sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd \ - --hash=sha256:a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a \ - --hash=sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9 \ - --hash=sha256:ada8121bcb4dac28d930febc791a69f7cb1673c8495e5eee274190b73a4559c1 \ - --hash=sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde \ - --hash=sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3 \ - --hash=sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f \ - --hash=sha256:c57b1b610bd1f40ba43970e11ce62821c2e6569e4d74023db19c6b26f246cb3b \ - --hash=sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3 \ - --hash=sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e \ - --hash=sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702 \ - --hash=sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c \ - --hash=sha256:f984ca4b14914e6b4094c5d52a32ea16b49832c03bd17a110f004db3c223e8e1 \ - --hash=sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4 \ - --hash=sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd - # via feast (pyproject.toml) +scikit-learn==1.9.0 \ + --hash=sha256:051075bda8b7aab87b1906ab3d4740a1e1224a19d7b3781a576736edc94e76aa \ + --hash=sha256:056c92bb67ad4c28463c2f2653d9701449201e7e7a9e94e321be0f71c4fef2b8 \ + --hash=sha256:147e9329ef0e39f75d4cffa02b2aa48d827832684926cd5210d9a2cb5c57246b \ + --hash=sha256:1b944b6db288f6b926e3650026ddafb988929de95d11fc2cc5fa117773c9ba42 \ + --hash=sha256:1fea2cc5677ab49d6f5bade978c866da44957b712d92e9635e8b4f723013c3cb \ + --hash=sha256:24360002ae845e7866522b0a5bbf690802e7bc388cac8663502e78aa98598aa2 \ + --hash=sha256:26e22435f63bcdcf396b574273f29f13dd531f5ea035801f5be10ba1540a4e60 \ + --hash=sha256:2bd41b0d201bc81575531b96b713d3eb5e5f50fb0b82101ff0f92294fdc236ac \ + --hash=sha256:366652351f092b219c248f1e72821e841960a63d8f358f1dcfd54dc1cbdbbc28 \ + --hash=sha256:38c3dcb9a1ffb85505ec53d54c7b4aea0cff70050425a7760c2af661ac85df05 \ + --hash=sha256:4306775fad04cc4b472a1b15af1ae9cede1540fbfcc17fbce3767cd8dc7ae283 \ + --hash=sha256:4ccacf04ca5f4b492158a5f28afe0ace43f81b2571e4b9a66d34848b46128949 \ + --hash=sha256:5162ad10a418c8a282dde04c9aa06965de3e9a65f33c1440c0ae69bb1a09d913 \ + --hash=sha256:5808d98f15c6bf6d9d96d2348c1997392a5888ce7097e664105f930c4bca1277 \ + --hash=sha256:5b934c45c252844a91d69fda3a34cff5e7307e1db10d77cb10a3980312c74713 \ + --hash=sha256:5bad8f8b9950321b54c965fdcbac6c6c55e79e16646b49977bcf3668d3870a1a \ + --hash=sha256:5be45aa4a42a68a533913a6ed736cf309de2226411c79ef8d609a5456f1939b1 \ + --hash=sha256:5dc1818c77575d149e25fce9ef82dd7b7263ae372f03494158668ad632a69759 \ + --hash=sha256:5e50ed4da51974e86e940690e9a3d82e729b62b5a49f7c9bac534d515d39d86f \ + --hash=sha256:64fa347efc1c839c487433e40c5144d38c336e8a2b59c81aa8660373945c2673 \ + --hash=sha256:78fc56eafd4edb9575d2d8950d1dd152061abb573341a1cb7e099fc40f6c6666 \ + --hash=sha256:80746d63bd4b6eaca54d36fe5feaf4d28bb38dc6f9470f81c7cad7c40155f119 \ + --hash=sha256:8833266989d3a5110178a9fae30783675460724d0e1efb13b14901d2c660c557 \ + --hash=sha256:9656acd4e93f74e0b66c8a36c88830a99252dfa900044d36bc2212ae89a47162 \ + --hash=sha256:9db6f4d34e68c8899e4cab27fdf8eafe6ed21f2ba52ceb25ea250cd237f8e47b \ + --hash=sha256:d77f54c017633791bc0225a43e2f8d03745fdcfe4880268fcc4df15f505dec2e \ + --hash=sha256:da76d09304a4706db7cc1e3ebaa3b6b98a67365cc11d2996c4f1e58ba47df714 \ + --hash=sha256:ee1a8db2c18c08e34c7412d4b10be1cac214cd4ea7dc9715a6a327eb49a37c96 \ + --hash=sha256:f401448645a3e7bc115aa3c094097865155b34bff1cba8101857d9104e99074c \ + --hash=sha256:f7e254636164090da847715a27f8e5478feb98c40a9e0ee90cbd277de9e5ceb8 \ + --hash=sha256:fd3a8ef0c758555a3b23c03adaa858af32f7736785ded50ad5991f59c4ed03fa + # via + # feast (pyproject.toml) + # mlflow + # sentence-transformers + # skops scipy==1.17.1 \ --hash=sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0 \ --hash=sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458 \ @@ -5270,8 +5895,11 @@ scipy==1.17.1 \ # docling # easyocr # great-expectations + # mlflow # scikit-image # scikit-learn + # sentence-transformers + # skops semchunk==3.2.5 \ --hash=sha256:ee15e9a06a69a411937dd8fcf0a25d7ef389c5195863140436872a02c95b0218 \ --hash=sha256:fd09cc5f380bd010b8ca773bd81893f7eaf11d37dd8362a83d46cedaf5dae076 @@ -5280,6 +5908,10 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server +sentence-transformers==5.5.1 \ + --hash=sha256:02b7740dfc60bdbbcb6061625f5d97a5c1a4e2d3baac5f9391b912bb5eae2290 \ + --hash=sha256:4fe11d433badc5282d32f7fc08bc714216b7a5aca426f9df77a45a554756deb7 + # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ --hash=sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173 @@ -5291,7 +5923,6 @@ setuptools==80.10.2 \ # pbr # pip-tools # pydata-google-auth - # pymilvus # singlestoredb # torch shapely==2.1.2 \ @@ -5378,10 +6009,18 @@ six==1.17.0 \ # python-dateutil # rfc3339-validator # thriftpy2 -smart-open==7.5.1 \ - --hash=sha256:3e07cbbd9c8a908bcb8e25d48becf1a5cbb4886fa975e9f34c672ed171df2318 \ - --hash=sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7 +skops==0.14.0 \ + --hash=sha256:60a5db78a9db46ccee2139a0ba13ab5afb1c96f4749b382e75a371291bbe3e36 \ + --hash=sha256:6c8c0e047f691a3a582c3258943eecafcbfd79c8c7eef66260f3703e363254f0 + # via mlflow +smart-open==7.6.1 \ + --hash=sha256:4347996e7ba21db7cd1e059632e0b30395407e4f6c660d2ddffc8f2a9ae5f990 \ + --hash=sha256:b4de6aebef023aca91cc9fb372052e1343ba3f152de215bd22391a663e3ddd21 # via ray +smmap==5.0.3 \ + --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ + --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f + # via gitdb sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc @@ -5389,45 +6028,45 @@ sniffio==1.3.1 \ # elastic-transport # elasticsearch # httpx -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.0.0 \ - --hash=sha256:0c0204f639fddc58452b0362ba8821cd5153bd7aaa89434d59104bc39f4fa176 \ - --hash=sha256:1ca2503f705627f7e045da6254d97c37210a3b0a18b43d0f1b29616d0c7aaa01 \ - --hash=sha256:1fea301e3d1e8022b9f2ff87dc3be139d5ed7be5e85fab8a6c59d400a02e6d58 \ - --hash=sha256:2c3e0f6d103fe67c975550ed424f579d3e7ae503d56467e5549f3a1a1e0e8f24 \ - --hash=sha256:4106a66e770e564b3037457b7b01b15ca28aee61afb88560b664aa8af439b533 \ - --hash=sha256:4b10a865c4a5e1fa60c365c7fe41e0433605e6e5edc824e8730a9038f330b3a6 \ - --hash=sha256:4e8c3d2ea4055dd4aecc93514030341e300f557f2e86ca21eb47568c461a6f56 \ - --hash=sha256:54e648bbd506a0f2f8076f9eafe231b2d4284b1a884528c3a0690391ab2bb54e \ - --hash=sha256:5ad5d0f1ebcb2c6b7a7859ee3d4e02203087e40faae539a336bbcb45a3660777 \ - --hash=sha256:65e4e36dd1b0c7235d84cddef8a3c97c5ea0dc8fea85e31e45fc485000b77a83 \ - --hash=sha256:7789df78f7c7abfb351f2709258d05a94652cfe3c2c617fb15f15a11fc1b7b25 \ - --hash=sha256:79b4e7a58e600419f083a63f99e5da89d438faddae1d344e9f9b003754fa231b \ - --hash=sha256:835161dd46ef8f5fc9d2f135ca654c2f3fbdf57b035d3e1980506aa8eac671dc \ - --hash=sha256:985cd2f8b6b2e663ef30dc59f1ba8c1becff7683ebc51bd7f14b962407a9fa88 \ - --hash=sha256:a790f06808e4481c23cfed1396d2c9a786060ddd62408b1fda1a63e1e6bc4b07 \ - --hash=sha256:af89a9e1355ea4dac7927d2f9bc15b2c81e381ad8bcdf8954ba3dd457a4d51d6 \ - --hash=sha256:b95b29589293ad14d0367428518141995524cfc7dc47d8f3d0c47010f5d974da \ - --hash=sha256:bfd3b8523d7adc830f99c5c4c635689ceca61700a05368d5bbb34c6811f2ec54 \ - --hash=sha256:cd23bff2abc74e34c6123a181c004ead9e6cc8ef2661250892afd64bad24533c \ - --hash=sha256:e376bad497c7932448cc29058e75737f02b3f0e25569de9e4ff0616944b4ceba \ - --hash=sha256:e6132986d6965e4005b0167270612fbc7fa4bc4ef42726a40b85a8f57475a78d \ - --hash=sha256:e8d5b66f283967c700fff2303ac5e52d1a3cf41990a634f121ac8b1f1cd9af10 \ - --hash=sha256:eb1bb9729fd3bfaae22364491cec4816dda380376ac3be4559a6f6949c6d2833 \ - --hash=sha256:ebbdeec0d65c2e3f648c8b05839001c062984959417902717f7fc6eed983211d \ - --hash=sha256:f67d844241a6fed764a8f04d32c0273aedf9159d5162b764748526277c7f8831 \ - --hash=sha256:fd0d2d2c5cfd15f041e8522f5f8bdad0be4de7d805dd1646377fccd6bd404fa8 +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -soupsieve==2.8.3 \ - --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ - --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 +soupsieve==2.8.4 \ + --hash=sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e \ + --hash=sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65 # via beautifulsoup4 sphinx==6.2.1 \ --hash=sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b \ @@ -5457,77 +6096,98 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb - # via feast (pyproject.toml) -sqlglot[rs]==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb + # via + # feast (pyproject.toml) + # alembic + # mlflow +sqlglot[rs]==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via # feast (pyproject.toml) # ibis-framework +sqlglotc==30.9.0 \ + --hash=sha256:197f30830a4c40d39655e9d97c91b179dcd1c88635d34d5281a15536cb04030e \ + --hash=sha256:3f132418f0facde6319611dbaf4d47b6f8a7ca37527cda5337f7253ddbd0f62d \ + --hash=sha256:45e65c77a2a3887934d16421db019a1081403ddc4d2ec359d61971d0ace8f48a \ + --hash=sha256:46f004fda92af8676577171e2172892aced1ec7baa1388b26b25be37e980164f \ + --hash=sha256:54788de9eac748135afc322e0385a040296fb6e35fabd213f3387e09821eab50 \ + --hash=sha256:65a84bc3cca32acef23f3b7366cd85eece18536eac41bd364a87d64fcee97470 \ + --hash=sha256:7848eb58afdf74e056cf3fbbc8ea4c70b94e6a106d967c7abc628ed8f2acefc8 \ + --hash=sha256:8060a9446768b810d4f89e1263b04ffdacc67a2c1711aa4af9e7d22be4ac59ed \ + --hash=sha256:88c98db55e0f673f4bd80f2662a07bc234e9a37d321a1044ca6ff2f3598d42db \ + --hash=sha256:955c58c5fe0b555304fed58c5bf960a27211cfba2fb0ff0ead6a8253a35b6e17 \ + --hash=sha256:ab1763090f60581bdabf304c86ef465d3b019244c0b7610db15562bb52688d70 \ + --hash=sha256:b7d8aff3f33f2930dbdc6b7de875d3c22414528755631f3183d1e982fd7ae255 \ + --hash=sha256:c4879678e5bca435245951669ce8790651e9806760fbbbe48772440c9f392b43 \ + --hash=sha256:d57133358daec2003a86f533ca5c38306680cdc60d71e3d25174b182da667b45 \ + --hash=sha256:d98f26796bc4ab5f0fc2c9ac5eae9dc6ca2d8793abcdffab0a3f8937f9d27ff0 \ + --hash=sha256:e1829f6d77b1de1c7481ea289ee1615c1ca9e37149cbd20663742bd42f1cfe2a \ + --hash=sha256:e1c79d46e1733a53c97a78fea76cad6e45e922058afa948e60b796b3546182a3 \ + --hash=sha256:ee104e4781b4ee656c7461056e8a1ca34dcd0256ade5db5bb8d5eaf4b470ac12 \ + --hash=sha256:f932992dea9fbdf797cc40da1752e2df423867d0e5de98663f0136822224293e \ + --hash=sha256:faa3ec4c15894d70341390db2a0b890c92f57c79a0398f7f954f345aea59060a \ + --hash=sha256:fcea2b7d0dca702f2c0f0af41da8552c39a749f2e63d66757c947f97344ab11f + # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ --hash=sha256:ad1ad158234af0f8ba5054ca51bd17a7c1e3f81b4798c7970ebf7953fe08ddcb @@ -5543,20 +6203,26 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sqlparse==0.5.5 \ + --hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \ + --hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e + # via mlflow-skinny +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 # via ipython -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp + # mlflow-skinny # sse-starlette sympy==1.14.0 \ --hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \ @@ -5579,9 +6245,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc3 \ + --hash=sha256:2a9dad9a10ef1aff91c3df43b7387768ed16616d83bc591b92cefd54d3426faf \ + --hash=sha256:9e8a1ca7b15d3cbd907dec45d5823f512a01b67cc22d9db6af86fa41b47e561b # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -5596,14 +6262,18 @@ thriftpy2==0.6.0 \ --hash=sha256:1245c36b82f34aa26f049e6529f40ad34d9be8d12bd0131559847c8476b98ce0 \ --hash=sha256:151d299e8e3694a6cc0f2f2cda01d5744080742649de958c5cdcbebb4306205f \ --hash=sha256:16eecfd34bd541b75172ba0d69ea90b874611a7361d18906fb6d95955089cc30 \ + --hash=sha256:182f54a7248c8ecf1320cf26d1fc9115765df6b1f2589c1d2d0df7049a5b27d4 \ --hash=sha256:210345281d41b3a76d263b555d3e3cc482103738441bdb92a73033a4e9a042e1 \ --hash=sha256:265588b8cdb3fe1097db43bf35fb208edc69d9350a2bec3a737d6357d0a5650d \ --hash=sha256:28fd55960a6d42207060536109928a4615fbbd6874c0ddd8a705b47075f1d2d0 \ --hash=sha256:29ff125e40c8016b4d3bf48e6d727bd93d2892451b47bfe57ba896944ecbdb0c \ --hash=sha256:2ae866adf9b112c7ab30c1a90d878a5d6f2d40244fbc46ec8477425d802f4ac5 \ --hash=sha256:2bf891c2d441b1edddfc62f16ab3031ac7506cba5b77680654179dbe93d8b7ec \ + --hash=sha256:2c88b0d356ea18ce026a52aa7c2110693db77fd52d5ac7553616635a7f165bbd \ --hash=sha256:3090d9cabc2c31c92ae943f36d539a20adfd82697f50e996ce94f0b279e9e1e4 \ + --hash=sha256:3359a7c4eb4c281bf54bd760dcc03c43299f0d529dd2a5018be2f1fbebf0cbbd \ --hash=sha256:375cca06f36f54339838c7f8251b64a777d5ff1277f8b91999487fad1a8e2d73 \ + --hash=sha256:386d8c4a5677fd94fd16c1af2adf39f59698af1e4ef0c3c026083f278540e352 \ --hash=sha256:44365bb5098d0a91c44382e7df0ad44d5b9a588d29d9071aca4a2867f704aaf1 \ --hash=sha256:443e502b428d325c57aec0947991857e8dc0589d0464181f35bd48f870cd5d18 \ --hash=sha256:4550cbb6629c9f6186ab22cb497f262408e1a90ae10b8653599f2717f518f0df \ @@ -5620,6 +6290,7 @@ thriftpy2==0.6.0 \ --hash=sha256:851981ded8bb42da66213cf95d1dd5eaf06c5d6b3a95725a18eddd58ec992b6b \ --hash=sha256:852e538b4866ed776126349161d9fdc37387b1e15ab46805f98dcdee25fee4b5 \ --hash=sha256:8b19d19661fc9a71f19b7c432c413ab65025e5dd11fbd192bd9169afb13b9ce0 \ + --hash=sha256:8e62d9c36bcfe6b85bec7b754accb97e2fa7b6a7c9a0c37f824d85eba699e7b8 \ --hash=sha256:8eb0566b4501c27ea51f2e593531122703946969564fe526a5ff1b18be0ad49a \ --hash=sha256:8f393607d54091e8976e297f8fd7399606d12cd8c2b8852353f07ad5ddac4224 \ --hash=sha256:91df1fa70a99ac08dc449d6fda24a14992a1836d571928f217c40c66fd63fcc8 \ @@ -5634,29 +6305,32 @@ thriftpy2==0.6.0 \ --hash=sha256:b361152c24fd5c791220de9966b00696578c9884a2bb67e4759d4dfe05fd7049 \ --hash=sha256:b51b5259dc344482ab21b768dfc7f54d51d9133665e72890831725068f69f24a \ --hash=sha256:b57f367d7b0e1bc9e5c9b0ff34febdb3fe440f1fe8d75903ae71301bc06072c0 \ + --hash=sha256:b8dc65d2e7951b7e81c17b92857db7c19d6b3dd442d2d8600b5bd5040aa43ce6 \ --hash=sha256:bc320e960347e5f9d27e8b4a9fc7044b2b26bfe4522bb4957e741fc1d1ebd2f0 \ --hash=sha256:bdf77ba7a8987a239eb57cf840d62669741f8b92b61a617e63898caed31da898 \ --hash=sha256:bf96b64400da2f411b43c4c81c2e20b09e3300d86766a52f42393696c8962f11 \ --hash=sha256:c37f5dbfe95579549485c33167854784358f559feda703ccc058719ca0efd8aa \ --hash=sha256:c41312c6edad5e875613719236f1ca6bba9310df40b1adc9308248e1bdb7a1ea \ + --hash=sha256:cafa1d43bcc69129a4855fd3973ab7983bb2274c407e5ff572af5dc196e00313 \ --hash=sha256:cb98556e919be3e6ba9bca629dbddccfaa33b95a0fe7503052849b124e4f88cd \ --hash=sha256:cd2e2c4dcc30c373e317d39b044afa6d9a090bec11d186f25841f70bc520bbb5 \ --hash=sha256:e6c4fb1e7f51f8858f348ed9c31bb408b61274942d18b549ec163bb480c987a0 \ + --hash=sha256:eccab0281667caab0c055882b3bbb8e346bb0181e55f37477e3e5e3f5b7a96dd \ --hash=sha256:f59f74c3779aa47223ba0a9e23ef10d2af5a873ed3624c78303f62a679d1b63e \ --hash=sha256:f6b86112cca7bd04151ce248d781763ea5f74cc18d148476c6d16cee32db81ac \ --hash=sha256:f837ab85ae93b118766b8b28a1cec47a1daddee303e1f986a595c56379062a5c # via happybase -tifffile==2026.3.3 \ - --hash=sha256:d9a1266bed6f2ee1dd0abde2018a38b4f8b2935cb843df381d70ac4eac5458b7 \ - --hash=sha256:e8be15c94273113d31ecb7aa3a39822189dd11c4967e3cc88c178f1ad2fd1170 +tifffile==2026.6.1 \ + --hash=sha256:0d7382d2769b855b81ce358528e2b40c16d48aa39031746efa81215205332a8d \ + --hash=sha256:626c892c0e899d959b9438e7c0e1491dc154a7fead1f1f37a991724a50eceba9 # via scikit-image -timm==1.0.25 \ - --hash=sha256:47f59fc2754725735cc81bb83bcbfce5bec4ebd5d4bb9e69da57daa92fcfa768 \ - --hash=sha256:bef7f61dd717cb2dbbb7e326f143e13d660a47ecbd84116e6fe33732bed5c484 +timm==1.0.27 \ + --hash=sha256:315dfe63186ca9fb7ff941268941231fd5be259f2b4bb4afa28560ae1015cb9a \ + --hash=sha256:5ff07c9ddf53cbada88eab1c93ff175c64cab683b5a2fddf863bcee985926f89 # via feast (pyproject.toml) -tinycss2==1.4.0 \ - --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ - --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 +tinycss2==1.5.1 \ + --hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \ + --hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957 # via bleach tokenizers==0.22.2 \ --hash=sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113 \ @@ -5688,58 +6362,58 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -5749,94 +6423,89 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -torch==2.10.0 \ - --hash=sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574 \ - --hash=sha256:233aed0659a2503b831d8a67e9da66a62c996204c0bba4f4c442ccc0c68a3f60 \ - --hash=sha256:29b7009dba4b7a1c960260fc8ac85022c784250af43af9fb0ebafc9883782ebd \ - --hash=sha256:2b980edd8d7c0a68c4e951ee1856334a43193f98730d97408fbd148c1a933313 \ - --hash=sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547 \ - --hash=sha256:3202429f58309b9fa96a614885eace4b7995729f44beb54d3e4a47773649d382 \ - --hash=sha256:3282d9febd1e4e476630a099692b44fdc214ee9bf8ee5377732d9d9dfe5712e4 \ - --hash=sha256:35e407430795c8d3edb07a1d711c41cc1f9eaddc8b2f1cc0a165a6767a8fb73d \ - --hash=sha256:418997cb02d0a0f1497cf6a09f63166f9f5df9f3e16c8a716ab76a72127c714f \ - --hash=sha256:5276fa790a666ee8becaffff8acb711922252521b28fbce5db7db5cf9cb2026d \ - --hash=sha256:5c4d217b14741e40776dd7074d9006fd28b8a97ef5654db959d8635b2fe5f29b \ - --hash=sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf \ - --hash=sha256:6021db85958db2f07ec94e1bc77212721ba4920c12a18dc552d2ae36a3eb163f \ - --hash=sha256:6528f13d2a8593a1a412ea07a99812495bec07e9224c28b2a25c0a30c7da025c \ - --hash=sha256:682497e16bdfa6efeec8cde66531bc8d1fbbbb4d8788ec6173c089ed3cc2bfe5 \ - --hash=sha256:6b71486353fce0f9714ca0c9ef1c850a2ae766b409808acd58e9678a3edb7738 \ - --hash=sha256:6d3707a61863d1c4d6ebba7be4ca320f42b869ee657e9b2c21c736bf17000294 \ - --hash=sha256:71283a373f0ee2c89e0f0d5f446039bdabe8dbc3c9ccf35f0f784908b0acd185 \ - --hash=sha256:716b01a176c2a5659c98f6b01bf868244abdd896526f1c692712ab36dbaf9b63 \ - --hash=sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb \ - --hash=sha256:a2f9edd8dbc99f62bc4dfb78af7bf89499bca3d753423ac1b4e06592e467b763 \ - --hash=sha256:a4be6a2a190b32ff5c8002a0977a25ea60e64f7ba46b1be37093c141d9c49aeb \ - --hash=sha256:aae1b29cd68e50a9397f5ee897b9c24742e9e306f88a807a27d617f07adb3bd8 \ - --hash=sha256:aaf663927bcd490ae971469a624c322202a2a1e68936eb952535ca4cd3b90444 \ - --hash=sha256:b7bd80f3477b830dd166c707c5b0b82a898e7b16f59a7d9d42778dd058272e8b \ - --hash=sha256:bf0d9ff448b0218e0433aeb198805192346c4fd659c852370d5cc245f602a06a \ - --hash=sha256:c2ee399c644dc92ef7bc0d4f7e74b5360c37cdbe7c5ba11318dda49ffac2bc57 \ - --hash=sha256:cdf2a523d699b70d613243211ecaac14fe9c5df8a0b0a9c02add60fb2a413e0f \ - --hash=sha256:d8f5912ba938233f86361e891789595ff35ca4b4e2ac8fe3670895e5976731d6 \ - --hash=sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e \ - --hash=sha256:f5ab4ba32383061be0fb74bda772d470140a12c1c3b58a0cfbf3dae94d164c28 \ - --hash=sha256:ff43db38af76fda183156153983c9a096fc4c78d0cd1e07b14a2314c7f01c2c8 +torch==2.12.0 \ + --hash=sha256:10802fd383bbfed646212e765a72c37d2185205d4f26eb197a254e8ac7ddcb25 \ + --hash=sha256:10ee1448a9f304d3b987eb4656f664ba6e4d7b410ca7a5a7c642199777a2cf88 \ + --hash=sha256:1834bd984f8a2f4f16bdfbeecca9146184b220aa46276bf5756735b5dae12812 \ + --hash=sha256:2140e373e9a51a3e22ef62e8d14366d0b470d18f0adf19fdc757368077133a34 \ + --hash=sha256:3fee918902090ade827643e758e98363278815de583c75d111fdd665ebffde9f \ + --hash=sha256:415c1b8d0412f67551c8e89a2daca0fb3e56694af0281ba155eaa9da481f58b4 \ + --hash=sha256:4b4f64c2c2b11f7510d93dd6412b87025ff6eddd6bb61c3b5a3d892ea20c4756 \ + --hash=sha256:5d6b560dfa7d56291c07d615c3bb73e8d9943d9b6d87f76cd0d9d570c4797fa6 \ + --hash=sha256:5f96b63f8287f66a005dd1b5a6abba2920f11156c5e5c4d815f3e2050fd1aa16 \ + --hash=sha256:6a7512adfdd7f6732e40de1c620831e3c75b39b98cef60b11d0c5f0a76473ec5 \ + --hash=sha256:864392c73b7654f4d2b3ae712f607937d0dbb1101c4555fbb41848106b297f39 \ + --hash=sha256:891c769072637c74e9a5a77a3bc782894696d8ffec83b938df8536dee7f0ba78 \ + --hash=sha256:8b958caff4a14d3a3b0b2dfc6a378f64dda9728a9dad28c08a0db9ce4dafb549 \ + --hash=sha256:8fbef9f108a863e7722a73740998967e3b074742a834fc5be3a535a2befa7057 \ + --hash=sha256:90dd587a5f61bfe1307148b581e2084fc5bc4a06e2b90a20e9a36b81087ff16b \ + --hash=sha256:a43ac605a5e13116c72b64c359644cce0229f213dde48d2ae0ae5eb5becf7feb \ + --hash=sha256:a6a2eebb237d3b1d9ad3b378e86d9b9e0782afdea8b1e0eba6a13646b9b49c07 \ + --hash=sha256:af68dbf403439cae9ceaeaaf92f8352b460787dcd27b92aa05c40dd4a19c0f1e \ + --hash=sha256:b41339df93d491435e790ff8bcbae1c0ce777175889bfd1281d119862793e6a2 \ + --hash=sha256:b4556715c8572758625d62b6e0ae3b1f76c440221913a6fb5e100f321fb4fb02 \ + --hash=sha256:c12592630aef72feaf18bd3f197ef587bbfa21131b31c38b23ab2e55fce92e36 \ + --hash=sha256:c66696857e987efb8bc1777a37357ec4f60ab5e8af6250b83d6034437fa2d8f3 \ + --hash=sha256:cf9839790285dd472e7a16aafcb4a4e6bf58ec1b494045044b0eefb0eb4bd1f2 \ + --hash=sha256:d47e7dee68ac4cd7a068b26bcd6b989935427709fae1c8f7bd0019978f829e15 \ + --hash=sha256:d4d029801cb7b6df858804a2a21b00cc2aa0bf0ee5d2ab18d343c9e9e5681f35 \ + --hash=sha256:dd37188ea325042cb1f6cafa56822b11ada2520c04791a52629b0af25bdfbfd9 \ + --hash=sha256:e2ad3eb85d39c3cab62dfa93ed5a73516e6a53c6713cb97d004004fe089f0f1f \ + --hash=sha256:f7dfae4a519197dfa050e98d8e36378a0fb5899625a875c2b54445005a2e404e # via # feast (pyproject.toml) # accelerate # docling-ibm-models # easyocr # safetensors + # sentence-transformers # timm # torchvision -torchvision==0.25.0 \ - --hash=sha256:0b5e7f50002a8145a98c5694a018e738c50e2972608310c7e88e1bd4c058f6ce \ - --hash=sha256:0d9a3f925a081dd2ebb0b791249b687c2ef2c2717d027946654607494b9b64b6 \ - --hash=sha256:146d02c9876858420adf41f3189fe90e3d6a409cbfa65454c09f25fb33bf7266 \ - --hash=sha256:153c0d2cbc34b7cf2da19d73450f24ba36d2b75ec9211b9962b5022fb9e4ecee \ - --hash=sha256:24e11199e4d84ba9c5ee7825ebdf1cd37ce8deec225117f10243cae984ced3ec \ - --hash=sha256:40a122c3cf4d14b651f095e0f672b688dde78632783fc5cd3d4d5e4f6a828563 \ - --hash=sha256:5e6b449e9fa7d642142c0e27c41e5a43b508d57ed8e79b7c0a0c28652da8678c \ - --hash=sha256:5f271136d2d2c0b7a24c5671795c6e4fd8da4e0ea98aeb1041f62bc04c4370ef \ - --hash=sha256:620a236288d594dcec7634c754484542dc0a5c1b0e0b83a34bda5e91e9b7c3a1 \ - --hash=sha256:632db02300e83793812eee4f61ae6a2686dab10b4cfd628b620dc47747aa9d03 \ - --hash=sha256:846890161b825b38aa85fc37fb3ba5eea74e7091ff28bab378287111483b6443 \ - --hash=sha256:855c0dc6d37f462482da7531c6788518baedca1e0847f3df42a911713acdfe52 \ - --hash=sha256:a8f8061284395ce31bcd460f2169013382ccf411148ceb2ee38e718e9860f5a7 \ - --hash=sha256:a95c47abb817d4e90ea1a8e57bd0d728e3e6b533b3495ae77d84d883c4d11f56 \ - --hash=sha256:acc339aba4a858192998c2b91f635827e40d9c469d9cf1455bafdda6e4c28ea4 \ - --hash=sha256:ad9a8a5877782944d99186e4502a614770fe906626d76e9cd32446a0ac3075f2 \ - --hash=sha256:b57430fbe9e9b697418a395041bb615124d9c007710a2712fda6e35fb310f264 \ - --hash=sha256:b75deafa2dfea3e2c2a525559b04783515e3463f6e830cb71de0fb7ea36fe233 \ - --hash=sha256:c2abe430c90b1d5e552680037d68da4eb80a5852ebb1c811b2b89d299b10573b \ - --hash=sha256:c4d395cb2c4a2712f6eb93a34476cdf7aae74bb6ea2ea1917f858e96344b00aa \ - --hash=sha256:cef0196be31be421f6f462d1e9da1101be7332d91984caa6f8022e6c78a5877f \ - --hash=sha256:d1abd5ed030c708f5dbf4812ad5f6fbe9384b63c40d6bd79f8df41a4a759a917 \ - --hash=sha256:db74a551946b75d19f9996c419a799ffdf6a223ecf17c656f90da011f1d75b20 \ - --hash=sha256:ea580ffd6094cc01914ad32f8c8118174f18974629af905cea08cb6d5d48c7b7 \ - --hash=sha256:f07f01d27375ad89d72aa2b3f2180f07da95dd9d2e4c758e015c0acb2da72977 \ - --hash=sha256:f25aa9e380865b11ea6e9d99d84df86b9cc959f1a007cd966fc6f1ab2ed0e248 \ - --hash=sha256:f49964f96644dbac2506dffe1a0a7ec0f2bf8cf7a588c3319fed26e6329ffdf3 \ - --hash=sha256:f9c55ae8d673ab493325d1267cbd285bb94d56f99626c00ac4644de32a59ede3 +torchvision==0.27.0 \ + --hash=sha256:0822b58d2c5d325cd0c7152b744acbd15f898c07572e2cfb70b075a865a4f6f9 \ + --hash=sha256:1a6dd742a150645126df9e0b2e449874c1d635897c773b322c2e067e98382dfe \ + --hash=sha256:1c01f0d1091ae22b9dfc082b0a0fe5faaf053686a29b4fb082ba7691375c73cf \ + --hash=sha256:1c2db4bde82bc48ebff73436a6adf34d4f809448268a70d9a1285f5c8f92313d \ + --hash=sha256:2664d06acd64d328aa7689b0d0c81ee31e240e9977d8768816b4be7c66c03211 \ + --hash=sha256:2c037709072ca9b19750c0cbe9e8bb6f91c9a1be1befa26df33e281deccbd8c7 \ + --hash=sha256:2c4099a15150143b9b034730b404a56d572efe0b79489b4c765d929cb4eac7f3 \ + --hash=sha256:419c98a9275b27660cdce6d09080fd5974d1ec1d4a225f71439ebacb3b0c4e64 \ + --hash=sha256:41d6dae73e1af09fa82ded597ae57f2a2314285acde54b25890a8f8e51b999d7 \ + --hash=sha256:5bb82fc3c55daf1788621e504310b0a286f1069627a8742f692aebb075ef25a7 \ + --hash=sha256:65772ff3ec4f4f5d680e30019835555dd239e7fefee4b0a846375fe1cb1592ef \ + --hash=sha256:70f071c6f74b60d5fe8851636d8d4cd5f4fa29d57fd9348a87a6f17b990b95ba \ + --hash=sha256:72bf547e58ddb948689734eed6f4b6a2031f979dba4fb08e3690688b392e929f \ + --hash=sha256:7a9966a088d06b4cf6c610e03be62de469efa6f2cd2e7c7eed8e925ed6af59ac \ + --hash=sha256:91f61b9865423037c327eb56afa207cc72de874e458c361840db9dcf5ce0c0eb \ + --hash=sha256:9bb9251f64b854124efed95d02953a89f7e2726c3ca662d7ea0151129157297f \ + --hash=sha256:a49e55055a39a8506fe7e59850522cab004efb2c3839f6057658889c1d69c815 \ + --hash=sha256:aaafa6962c9d91f42503de1957d6fa349907d028c06f335bd95da7a5bc57147d \ + --hash=sha256:aee384a2782c89517c4ab9061d2720ba59fd2ffe5ef89d0a149cc2d43abdf521 \ + --hash=sha256:b4aacff70ea4b7377f996f9048989c850d221fef33658ddbcae42aa5bd4ca11a \ + --hash=sha256:b4c6bb0a670dcba017b3643e21902c9b8a1cc1c127d602f1488fa29ec3c6e865 \ + --hash=sha256:c1fac0fc2a7adf29481fc1938a0e7845c57ba1147a986784109c4d98f434ea8c \ + --hash=sha256:c5121f1b9ab09a7f73e837871deb8321551f7eaeb19d87aa00de9191968eae44 \ + --hash=sha256:c9f44e35e6ec01caedacce9e941a5bf21fe424403321efac2507a201273653c5 \ + --hash=sha256:cbf89764fc76f3f17fbf80c12d5a89c691e91cb9d82c38412aaf0568655ffb19 \ + --hash=sha256:dadea3c5ecfd05bbb2a3312ab0374f213c58bf6459cb059122e2f4dfe13d10ed \ + --hash=sha256:df0c166b6bdf7c47f88e81e8b43bc085451d5c50d0c5d1691bc474c1227d6fed \ + --hash=sha256:f44453f107c296d5446a79f7ac59733ad8bf5ddfa04c53805dfbae298a42a798 # via # feast (pyproject.toml) # docling-ibm-models # easyocr # timm -tornado==6.5.4 \ - --hash=sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1 \ - --hash=sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1 \ - --hash=sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 \ - --hash=sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335 \ - --hash=sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8 \ - --hash=sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f \ - --hash=sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84 \ - --hash=sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7 \ - --hash=sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17 \ - --hash=sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 \ - --hash=sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f \ - --hash=sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc +tornado==6.5.6 \ + --hash=sha256:1c34cfab7ad6d104f052f55de06d39bbafc5885cfeb4da688803308dbcfa90b7 \ + --hash=sha256:2543597b24a695d72338a9a77818362d72387c03ae173f1f169eadc5c91466ac \ + --hash=sha256:385f35e4e22fb52551dfcda4cdc8c30c61c2c001aef5ddad99cdfe116952efd3 \ + --hash=sha256:38bc01b4acacded2de63ae78023548e41ebe6fbed3ec05a796d7ae3ad893887e \ + --hash=sha256:65fcfaafb079435c2c19dc9e07c0f1cf0fa9051759ed0a7d0a3ba7ea7f64919c \ + --hash=sha256:6739bf1e8eb09230f1280ddbd3236f0309db70f2c551a8dbc40f62babdf82f79 \ + --hash=sha256:8666946e70171b8c3f1fc9b7876fac492e84822c4c7f3746f4e8f8bc9ac92a79 \ + --hash=sha256:9a365179fe8ff6b8766f602c0f67c185d778193e9bdd828b19f0b6ed7764177d \ + --hash=sha256:b942e6a137fda31ff54bf8e6e2c8d1c37f1f50583f3ed53fb840b53b9601d104 \ + --hash=sha256:db475f1b67b2809b10bb16264829087724ca8d24fe4ed47f7b8675cae453ef86 # via # ipykernel # jupyter-client @@ -5844,9 +6513,9 @@ tornado==6.5.4 \ # jupyterlab # notebook # terminado -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # datasets @@ -5857,10 +6526,11 @@ tqdm==4.67.3 \ # milvus-lite # mpire # semchunk + # sentence-transformers # transformers -traitlets==5.14.3 \ - --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ - --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f +traitlets==5.15.1 \ + --hash=sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92 \ + --hash=sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722 # via # ipykernel # ipython @@ -5881,6 +6551,7 @@ transformers==4.57.6 \ # feast (pyproject.toml) # docling-core # docling-ibm-models + # sentence-transformers tree-sitter==0.25.2 \ --hash=sha256:0628671f0de69bb279558ef6b640bcfc97864fe0026d840f872728a86cd6b6cd \ --hash=sha256:0c8b6682cac77e37cfe5cf7ec388844957f48b7bd8d6321d0ca2d852994e10d5 \ @@ -5919,15 +6590,16 @@ tree-sitter==0.25.2 \ --hash=sha256:fbb1706407c0e451c4f8cc016fec27d72d4b211fdd3173320b1ada7a6c74c3ac \ --hash=sha256:fe43c158555da46723b28b52e058ad444195afd1db3ca7720c59a254544e9c20 # via docling-core -tree-sitter-c==0.24.1 \ - --hash=sha256:290bff0f9c79c966496ebae45042f77543e6e4aea725f40587a8611d566231a8 \ - --hash=sha256:789781afcb710df34144f7e2a20cd80e325114b9119e3956c6bd1dd2d365df98 \ - --hash=sha256:7d2d0cda0b8dda428c81440c1e94367f9f13548eedca3f49768bde66b1422ad6 \ - --hash=sha256:942bcd7cbecd810dcf7ca6f8f834391ebf0771a89479646d891ba4ca2fdfdc88 \ - --hash=sha256:9a74cfd7a11ca5a961fafd4d751892ee65acae667d2818968a6f079397d8d28c \ - --hash=sha256:9c06ac26a1efdcc8b26a8a6970fbc6997c4071857359e5837d4c42892d45fe1e \ - --hash=sha256:a6a807705a3978911dc7ee26a7ad36dcfacb6adfc13c190d496660ec9bd66707 \ - --hash=sha256:d46bbda06f838c2dcb91daf767813671fd366b49ad84ff37db702129267b46e1 +tree-sitter-c==0.24.2 \ + --hash=sha256:1628584df0299b5a340aa63f8e67b6c97c91517f52fa7e7a4c557e40adb330a9 \ + --hash=sha256:4a2f4371cd816cc3153458f69062135ebb2ea5f275ddd90494e5c823d778204a \ + --hash=sha256:4d4579a8b54f0a442f903d88d3304cab77cd5c2031d4015baa4f2f8e15d6dcb7 \ + --hash=sha256:5041ef67eb68ce6bc8bb0b1f8ef3a5585ce523dae0c7eec109ab0627dd75aede \ + --hash=sha256:82842c5a5f2acd93f4de10038c33ac179c8979defc39376f990348d6289e933b \ + --hash=sha256:97bc80a224d48215d4e6e6376bf30d114f4c317b8145ff1b02afe785d4ba7bdd \ + --hash=sha256:abb549225091f7b25df2dd3a0143ece6e208f7055d8bcb4700b41ee79b9ef1e1 \ + --hash=sha256:c098bedcd5ac86ff93fa734d51d1dd86aed40fd5ed7d634c7af11380a0469969 \ + --hash=sha256:e2b42e8e22202c251f8629306f9321233542e07a6e01611b5fe83489272143eb # via docling-core tree-sitter-javascript==0.25.0 \ --hash=sha256:199d09985190852e0912da2b8d26c932159be314bc04952cf917ed0e4c633e6b \ @@ -5965,9 +6637,9 @@ trino==0.337.0 \ --hash=sha256:3a0bd03a09b7ea5dccd41ca6e58abfb127c6303f3a48a258ff794d411dd83a3c \ --hash=sha256:868f2b8137d4d1baa84c9bc341f2cdf29039462aa69d7c089a0b821b5a91f29c # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typer==0.12.5 \ --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ @@ -5976,9 +6648,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==1.17.0.20260307 \ - --hash=sha256:1a4f1168d43ed8cd2b0ed40a3eb870cda685a154d98478b0a65862084f190a02 \ - --hash=sha256:89b5b2c798d32fc6e3304903ed99af93fd608b741483ce7d57fa69eda40430e5 +types-cffi==2.0.0.20260518 \ + --hash=sha256:5b68a215a95d0eac4203b58e766ff7fe40c2e091b1fa1a9e54111f04cc560084 \ + --hash=sha256:f9707e66c13454789a58f8843d1ded4a66f1e9c8b10bd24d5eb5e0f25c0c5472 # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -5986,25 +6658,25 @@ types-protobuf==3.19.22 \ # via # feast (pyproject.toml) # mypy-protobuf -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) types-pyopenssl==24.1.0.20240722 \ --hash=sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39 \ --hash=sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54 # via types-redis -types-python-dateutil==2.9.0.20260305 \ - --hash=sha256:389717c9f64d8f769f36d55a01873915b37e97e52ce21928198d210fbd393c8b \ - --hash=sha256:a3be9ca444d38cadabd756cfbb29780d8b338ae2a3020e73c266a83cc3025dd7 +types-python-dateutil==2.9.0.20260518 \ + --hash=sha256:51f02dc03b61c7f6a07df45797d4dfe8a1aa47f0b7db9ad89f6fd3a1a70e1b51 \ + --hash=sha256:d6a9c5bd0de61460c8fdef8ab2b400f956a1a1075cce08d4e2b4434e478c50b8 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260304 \ - --hash=sha256:0c3542d8e9b0160b424233440c52b83d6f58cae4b85333d54e4f961cf013e117 \ - --hash=sha256:175332c1cf7bd6b1cc56b877f70bf02def1a3f75e5adcc05385ce2c3c70e6500 +types-pytz==2026.2.0.20260518 \ + --hash=sha256:3a12eaa38f476bd650902a9c9bb442f03f3c7dee2be5c5848bce61bd708d205a \ + --hash=sha256:e5d254329e9c4e91f0781b22c43a4bb2d10bb044d97b24c4b05d45567b0eae16 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260518 \ + --hash=sha256:d2150f75a231c9fe9c7463bd29487d93e60bac90400287351384bc2284eba7cd \ + --hash=sha256:d917f83fb38462550338c1297faedd860b3ec83912b96b1e3d73255f7473e466 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -6014,15 +6686,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260508 \ + --hash=sha256:8e51f159e8b24976849706ae2ed1dc9adba8ebbd080b17e494ebb66a8cc92c74 \ + --hash=sha256:b1e1a2d0456fbd655a71690b09a7aaeffdf2978d32049184ea436492aa51d20a # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -6032,7 +6704,9 @@ typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal + # alembic # anyio # azure-core # azure-identity @@ -6041,12 +6715,16 @@ typing-extensions==4.15.0 \ # docling-core # elasticsearch # fastapi + # graphene # great-expectations + # grpcio # huggingface-hub # ibis-framework + # jupyter-client # jwcrypto # mcp # minio + # mlflow-skinny # mypy # opentelemetry-api # opentelemetry-sdk @@ -6060,6 +6738,7 @@ typing-extensions==4.15.0 \ # python-docx # python-pptx # referencing + # sentence-transformers # snowflake-connector-python # sqlalchemy # starlette @@ -6076,9 +6755,9 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # arrow # ibis-framework @@ -6089,99 +6768,13 @@ tzlocal==5.3.1 \ # via # great-expectations # trino -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus uri-template==1.3.0 \ --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # via jsonschema -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # feast (pyproject.toml) # botocore @@ -6189,6 +6782,7 @@ urllib3==2.6.3 \ # docker # elastic-transport # great-expectations + # kube-authkit # kubernetes # minio # qdrant-client @@ -6202,6 +6796,7 @@ uvicorn[standard]==0.34.0 \ # feast (pyproject.toml) # fastapi-mcp # mcp + # mlflow-skinny # uvicorn-worker uvicorn-worker==0.3.0 \ --hash=sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b \ @@ -6265,121 +6860,121 @@ virtualenv==20.23.0 \ # feast (pyproject.toml) # pre-commit # ray -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn -wcwidth==0.6.0 \ - --hash=sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad \ - --hash=sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159 - # via prompt-toolkit +wcwidth==0.7.0 \ + --hash=sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2 \ + --hash=sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0 + # via + # prettytable + # prompt-toolkit webcolors==25.10.0 \ --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf @@ -6459,13 +7054,16 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -werkzeug==3.1.6 \ - --hash=sha256:210c6bede5a420a913956b4791a7f4d6843a43b6fcee4dfa08a65e93007d0d25 \ - --hash=sha256:7ddf3357bb9564e407607f988f683d72038551200c704012bb9a4c523d42f131 - # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +werkzeug==3.1.8 \ + --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ + --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 + # via + # flask + # flask-cors + # moto +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6473,90 +7071,100 @@ widgetsnbextension==4.0.15 \ --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 # via ipywidgets -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via # aiobotocore + # deprecated # smart-open # testcontainers xlsxwriter==3.2.9 \ @@ -6567,281 +7175,304 @@ xmltodict==1.0.4 \ --hash=sha256:6d94c9f834dd9e44514162799d344d815a3a4faec913717a9ecbfa5be1bb8e61 \ --hash=sha256:a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a # via moto -xxhash==3.6.0 \ - --hash=sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad \ - --hash=sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c \ - --hash=sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3 \ - --hash=sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004 \ - --hash=sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b \ - --hash=sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796 \ - --hash=sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f \ - --hash=sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c \ - --hash=sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1 \ - --hash=sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1 \ - --hash=sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0 \ - --hash=sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec \ - --hash=sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d \ - --hash=sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919 \ - --hash=sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67 \ - --hash=sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360 \ - --hash=sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799 \ - --hash=sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679 \ - --hash=sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef \ - --hash=sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d \ - --hash=sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7 \ - --hash=sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8 \ - --hash=sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa \ - --hash=sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e \ - --hash=sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa \ - --hash=sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec \ - --hash=sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4 \ - --hash=sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad \ - --hash=sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7 \ - --hash=sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5 \ - --hash=sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11 \ - --hash=sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae \ - --hash=sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d \ - --hash=sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4 \ - --hash=sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6 \ - --hash=sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df \ - --hash=sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058 \ - --hash=sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850 \ - --hash=sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2 \ - --hash=sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d \ - --hash=sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89 \ - --hash=sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e \ - --hash=sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa \ - --hash=sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6 \ - --hash=sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb \ - --hash=sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3 \ - --hash=sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b \ - --hash=sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4 \ - --hash=sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db \ - --hash=sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119 \ - --hash=sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec \ - --hash=sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518 \ - --hash=sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296 \ - --hash=sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033 \ - --hash=sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729 \ - --hash=sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca \ - --hash=sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063 \ - --hash=sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5 \ - --hash=sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d \ - --hash=sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f \ - --hash=sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8 \ - --hash=sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42 \ - --hash=sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e \ - --hash=sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392 \ - --hash=sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222 \ - --hash=sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f \ - --hash=sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd \ - --hash=sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77 \ - --hash=sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802 \ - --hash=sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d \ - --hash=sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1 \ - --hash=sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41 \ - --hash=sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374 \ - --hash=sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263 \ - --hash=sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71 \ - --hash=sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13 \ - --hash=sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8 \ - --hash=sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc \ - --hash=sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62 \ - --hash=sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11 \ - --hash=sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65 \ - --hash=sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0 \ - --hash=sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b \ - --hash=sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2 \ - --hash=sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788 \ - --hash=sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6 \ - --hash=sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f \ - --hash=sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc \ - --hash=sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e \ - --hash=sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702 \ - --hash=sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 \ - --hash=sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f \ - --hash=sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6 \ - --hash=sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87 \ - --hash=sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3 \ - --hash=sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a \ - --hash=sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b \ - --hash=sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b \ - --hash=sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b \ - --hash=sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8 \ - --hash=sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db \ - --hash=sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99 \ - --hash=sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a \ - --hash=sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2 \ - --hash=sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204 \ - --hash=sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b \ - --hash=sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546 \ - --hash=sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95 \ - --hash=sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9 \ - --hash=sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54 \ - --hash=sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06 \ - --hash=sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c \ - --hash=sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152 \ - --hash=sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86 \ - --hash=sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4 \ - --hash=sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93 \ - --hash=sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd \ - --hash=sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd \ - --hash=sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a \ - --hash=sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2 \ - --hash=sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248 \ - --hash=sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd \ - --hash=sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6 \ - --hash=sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf \ - --hash=sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7 \ - --hash=sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490 \ - --hash=sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0 \ - --hash=sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536 \ - --hash=sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb \ - --hash=sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829 \ - --hash=sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746 \ - --hash=sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07 \ - --hash=sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292 \ - --hash=sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6 \ - --hash=sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd \ - --hash=sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7 \ - --hash=sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d \ - --hash=sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0 \ - --hash=sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee \ - --hash=sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6 +xxhash==3.7.0 \ + --hash=sha256:01cf5c5333aed26cc8d5eea33b8d6398e085e365a704b7372fabdf7ab06441a9 \ + --hash=sha256:030c0fd688fce3569fbb49a2feefd4110cbb0b650186fb4610759ecfac677548 \ + --hash=sha256:03f8ff4474ee61c845758ce00711d7087a770d77efb36f7e74a6e867301000b8 \ + --hash=sha256:040ea63668f9185b92bc74942df09c7e65703deed71431333678fc6e739a9955 \ + --hash=sha256:05ece0fe4d9c9c2728912d1981ae1566cfc83a011571b24732cbf76e1fb70dca \ + --hash=sha256:05fd1254268c59b5cb2a029dfc204275e9fc52de2913f1e53aa8d01442c96b4d \ + --hash=sha256:073c23900a9fbf3d26616c17c830db28af9803677cd5b33aea3224d824111514 \ + --hash=sha256:082c87bfdd2b9f457606c7a4a53457f4c4b48b0cdc48de0277f4349d79bb3d7a \ + --hash=sha256:0c36f89ba026ccc6fde8f48479a2fd9fc450a736cc7c0d5650acfcff8636282e \ + --hash=sha256:0c72fe9c7e3d6dfd7f1e21e224a877917fa09c465694ba4e06464b9511b65544 \ + --hash=sha256:0d23fd49fdc5c8af61fb7104f1ad247954499140f6cb6045b3aa5c99dadbbf28 \ + --hash=sha256:0ff71596bd79816975b3de7130ab1ff4541410285a3c084584eeb1c8239996fd \ + --hash=sha256:1061bc6cec00adf75347b064ee62b220d66d9bc506acaad1418c79eec45a318c \ + --hash=sha256:11dd69b1a34b7b9af29012f390825b0cdb0617c0966560e227ca74daa7478ba9 \ + --hash=sha256:1295325c5a98d552333fa53dc2b026b0ef0ec9c8e73ca3a952990b4c7d65d459 \ + --hash=sha256:12c249621af6d50a05d9f10af894b404157b15819878e18f75fcbb0213a77d07 \ + --hash=sha256:12eca820a5d558633d423bf8bb78ce72a55394823f64089247f788a7e0ae691e \ + --hash=sha256:13805f0461cba0a857924e70ff91ae6d52d2598f79a884e788db80532614a4a1 \ + --hash=sha256:14bf7a54e43825ec131ee7fe3c60e142e7c2c1e676ad0f93fc893432d15414af \ + --hash=sha256:151d7520838d4465461a0b7f4ae488b3b00de16183dd3214c1a6b14bf89d7fb6 \ + --hash=sha256:153c3a4f73563101d4c8102cbff6a5b46f7aa9dbe374eedf1cd3b15fda750566 \ + --hash=sha256:157c49475b34ecea8809e51123d9769a534e139d1247942f7a4bc67710bb2533 \ + --hash=sha256:178959906cb1716a1ce08e0d69c82886c70a15a6f2790fc084fdd146ca30cd49 \ + --hash=sha256:17f8ae90c8e00f225be4899c3023704f23ee6d5638a00c54d6cbe9980068e6f9 \ + --hash=sha256:1910df4756a5ab58cfad8744fc2d0f23926e3efcc346ee76e87b974abab922f4 \ + --hash=sha256:1ad86695c19b1d46fe106925db3c7a37f16be37669dcf58dcc70a9dd6e324676 \ + --hash=sha256:1cc07c639e3a77ef1d32987464d3e408565b8a3be57b545d3542b191054d9923 \ + --hash=sha256:1d398f372496152f1c6933a33566373f8d1b37b98b8c9d608fa6edc0976f23b2 \ + --hash=sha256:2220af08163baf5fa36c2b8af079dc2cbe6e66ae061385267f9472362dfd53c6 \ + --hash=sha256:24cc22070880cc57b830a65cde4e65fa884c6d9b28ae4803b5ee05911e7bafba \ + --hash=sha256:2524a1e20d4c231d13b50f7cf39e44265b055669a64a7a4b9a2a44faa03f19b6 \ + --hash=sha256:2a61e2a3fb23c892496d587b470dee7fa1b58b248a187719c65ea8e94ec13257 \ + --hash=sha256:2d415f18becf6f153046ab6adc97da77e3643a0ee205dae61c4012604113a020 \ + --hash=sha256:31ab1461c77a11461d703c88eb949e132a1c6515933cf675d97ec680f4bd18de \ + --hash=sha256:31e3516a0f829d06ded4a2c0f3c7c5561993256bfa1c493975fb9dc7bfa828a1 \ + --hash=sha256:322b2f0622230f526aeb1738149948a7ae357a9e2ceb1383c6fd1fdaecdafa16 \ + --hash=sha256:3281ba1d1e60ee7a382a7b958513ba03c2c0d5fcbd9a6f7517c0a81251a23422 \ + --hash=sha256:3409b50ddbc76377d938f40a7a4662cd449f743f2c6178fd6162b875bf9b0d4f \ + --hash=sha256:347a93f2b4ce67ce61959665e32a7447c380f8347e55e100daa23766baacf0e5 \ + --hash=sha256:3573a651d146912da9daa9e29e5fbc45994420daaa9ef1e2fa5823e1dc485513 \ + --hash=sha256:363c139bf15e1ac5f136b981d3c077eb551299b1effede7f12faa010b8590a60 \ + --hash=sha256:37d994d0ffe81ef087bb330d392caa809bb5853c77e22ea3f71db024a0543dba \ + --hash=sha256:3afec3a336a2286601a437cb07562ab0227685e6fbb9ec17e8c18457ff348ecf \ + --hash=sha256:3b6b3d28228af044ebcded71c4a3dd86e1dbd7e2f4645bf40f7b5da65bb5fb5a \ + --hash=sha256:3bb5fd680c038fd5229e44e9c493782f90df9bef632fd0499d442374688ff70b \ + --hash=sha256:3beb1de3b1e9694fcdd853e570ee64c631c7062435d2f8c69c1adf809bc086f0 \ + --hash=sha256:3e1860f1e43d40e9d904cf22d93e587ea42e010ebce4160877e46bcab4bc232a \ + --hash=sha256:418a463c3e6a590c0cdc890f8be19adb44a8c8acd175ca5b2a6de77e61d0b386 \ + --hash=sha256:421da671f43a0189b57a4b8be694576308395f92f55ed3badcde67ab95acef81 \ + --hash=sha256:43475925a766d01ca8cd9a857fd87f3d50406983c8506a4c07c4df12adcc867f \ + --hash=sha256:44909f79fb7a4950ec7d96059398f46f634534cd95be9330a3827210af5aaebe \ + --hash=sha256:44fba4a5f1d179b7ddc7b3dc40f56f9209046421679b57025d4d8821b376fd8d \ + --hash=sha256:468f0fc114faaa4b36699f8e328bbc3bb11dc418ba94ac52c26dd736d4b6c637 \ + --hash=sha256:48b542c347c2089f43dc5a6db31d2a6f3cdb04ee33505ec6e9f653834dbb0bde \ + --hash=sha256:496736f86a9bedaf64b0dc70e3539d0766df01c71ea22032698e88f3f04a1ce9 \ + --hash=sha256:49a88183a3e5ab0b69d9bbfc0180cbdb247e8bada19fd9403c538b3aa3c24176 \ + --hash=sha256:49e556558eee5c8c9b2d5da03fd36cfa6c99cae95b3c3887ec64ee1a49ed517a \ + --hash=sha256:4b6d6b33f141158692bd4eafbb96edbc5aa0dabdb593a962db01a91983d4f8fa \ + --hash=sha256:4c2454448ce847c72635827bb75c15c5a3434b03ee1afd28cb6dc6fb2597d830 \ + --hash=sha256:4e15cc9e2817f6481160f930c62842b3ff419e20e13072bcbab12230943092bc \ + --hash=sha256:503722d52a615f2604f5e7611de7d43878df010dc0053094ef91cb9a9ac3d987 \ + --hash=sha256:506a0b488f190f0a06769575e30caf71615c898ed93ab18b0dbcb6dec5c3713c \ + --hash=sha256:50846b9b01f461ee0250d7a701a3d881e9c52ebce335d6e38e0224adc3369f50 \ + --hash=sha256:50e879ebbac351c81565ca108db766d7832f5b8b6a5b14b8c0151f7190028e3d \ + --hash=sha256:54876a4e45101cec2bf8f31a973cda073a23e2e108538dad224ba07f85f22487 \ + --hash=sha256:54a675cb300dda83d71daae2a599389d22db8021a0f8db0dd659e14626eb3ecc \ + --hash=sha256:565df64437a9390f84465dcca33e7377114c7ede8d05cd2cf20081f831ea788e \ + --hash=sha256:5886ad85e9e347911783760a1d16cb6b393e8f9e3b52c982568226cb56927bdc \ + --hash=sha256:5a6ddec83325685e729ca119d1f5c518ec39294212ecd770e60693cdc5f7eb79 \ + --hash=sha256:5b1bde10324f4c31812ae0d0502e92d916ae8917cad7209353f122b8b8f610c3 \ + --hash=sha256:5bf2f1940499839b39fef1561b5ecb6ede9ac34ef4457474e1337fc7ef07c2f3 \ + --hash=sha256:5de686e73690cdaf72b96d4fa083c230ec9020bcc2627ce6316138e2cf2fe2d1 \ + --hash=sha256:5e7ce913b61f35b0c1c839a49ac9c8e75dd8d860150688aed353b0ce1bf409d8 \ + --hash=sha256:5ec1e080a3d02d94ea9335bfab0e3374b877e25411422c18f51a943fa4b46381 \ + --hash=sha256:6318d8b6f6c6c21058928c23289686fc74f37d794170f14b35fecceb515d5e37 \ + --hash=sha256:646a69b56d8145d85f7fd2289d14fba07880c8a5bda406aa256b407481a61f35 \ + --hash=sha256:646b8aa66cf0cec9295dfc4e3ac823ee52e338bada9547f5cf2d674212d04b58 \ + --hash=sha256:6741564a923f082f3c2941c8bb920462ed5b25eaebdd1e161f162233c9a10bc5 \ + --hash=sha256:693d02c6dc7d1aa0a45921d54cd8c1ff629e09dfdc2238471507af1f7a1c6f04 \ + --hash=sha256:6be4d70d9ab76c9f324ead9c01af6ff52c324745ea0c3731682a0cf99720f1fe \ + --hash=sha256:6cc4eefbb542a5d6ffd6d70ea9c502957c925e800f998c5630ecc809d6702bae \ + --hash=sha256:6e83179bbb208fb72774c06ba227d6e410fa3797de33d0d4c00e3935f81da7d2 \ + --hash=sha256:6e934bbae1e0ec74e27d5f0d7f37ef547ce5ff9f0a7e63fb39e559fc99526734 \ + --hash=sha256:6f31143e18e6db136455b16f0e4e6eba943e1889127dd7c649b46a50d54dd836 \ + --hash=sha256:7426ff0dfa76eb47efc2cc59d4a717bfa9dc9938bff5e49e748bca749f6aa616 \ + --hash=sha256:74bbd92f8c7fcc397ba0a11bfdc106bc72ad7f11e3a60277753f87e7532b4d81 \ + --hash=sha256:7553816512c0abb75329c163a1eee77b0802c3757054b910d6e547bd0dbd16b7 \ + --hash=sha256:79f9efdbc828b02c681a7cefc6d4108d63811b20a8fb8518a40cb2c13ed15452 \ + --hash=sha256:7ab9a49c410d8c6c786ab99e79c529938d894c01433130353dd0fe999111077a \ + --hash=sha256:7bd7bc82dd4f185f28f35193c2e968ef46131628e3cac62f639dadf321cba4d1 \ + --hash=sha256:7c4d596b7676f811172687ec567cbafb9e4dea2f9be1bbb4f622410cb7f40f40 \ + --hash=sha256:7c76f18d1268d3dc1c8b8facef5b48a9c6172d4a49113afa2d91745f555c75ff \ + --hash=sha256:7d7148180ec99ba36585b42c8c5de25e9b40191613bc4be68909b4d25a77a852 \ + --hash=sha256:7fbec49f5341bbdea0c471f7d1e2fb41ae8925af9b6f28025c28defd8eb94274 \ + --hash=sha256:84415265192072d8638a3afc3c1bc5995e310570cd9acb54dc46d3939e364fe0 \ + --hash=sha256:845d347df254d6c619f616afa921331bada8614b8d373d58725c663ba97c3605 \ + --hash=sha256:84710b4e449596a6565ab67293858d2d93a54eeec55722d55c8f0a08b6e6de24 \ + --hash=sha256:85f5c0e26d945b5bb475e0a3d95193117498130baa7619357bdc7869c2391b5a \ + --hash=sha256:8653dd7c2eda020545bb2c71c7f7039b53fe7434d0fc1a0a9deb79ab3f1a4fc1 \ + --hash=sha256:875811ba23c543b1a1c3143c926e43996eb27ebb8f52d3500744aa608c275aed \ + --hash=sha256:8c5fcfd806c335bfa2adf1cd0b3110a44fc7b6995c3a648c27489bae85801465 \ + --hash=sha256:8d09dfd2ab135b985daf868b594315ebe11ad86cd9fea46e6c69f19b28f7d25a \ + --hash=sha256:8d4dea659b57443989ef32f4295104fd6912c73d0bf26d1d148bb88a9f159b02 \ + --hash=sha256:8e7edb98dd4721a2694542a35a0bdb989b42892086fd0216f7c48762dfe20844 \ + --hash=sha256:8f4608a06e4d61b7a3425665a46d00e0579122e1a2fae97a0c52953a3aad9aa3 \ + --hash=sha256:8ff00fcc3eb436617ed8556cf15daf76c2b501248361a065625a588af78a0a02 \ + --hash=sha256:90b9d1a8bd37d768ffc92a1f651ec69afc532a96fa1ac2ea7abbed5d630b3237 \ + --hash=sha256:9122ad6f867c4a0f5e655f5c3bdf89103852009dbb442a3d23e688b9e699e800 \ + --hash=sha256:91c3b07cf3362086d8f126c6aecd8e5e9396ad8b2f2219ea7e49a8250c318acd \ + --hash=sha256:921c14e93817842dd0dd9f372890a0f0c72e534650b6ab13c5be5cd0db11d47e \ + --hash=sha256:970f9f8c50961d639cbd0d988c96f80ddf66006de93641719282c4fe7a87c5e6 \ + --hash=sha256:9e6c0d843f1daf85ea23aeb053579135552bde575b7b98af20bfc667b6e4548d \ + --hash=sha256:9f1563fdc8abfc389748e6932c7e4e99c89a53e4ec37d4563c24fc06f5e5644b \ + --hash=sha256:9fd17f14ac0faa12126c2f9ca774a8cf342957265ec3c8669c144e5e6cdb478c \ + --hash=sha256:a04a6cab47e2166435aaf5b9e5ee41d1532cc8300efdef87f2a4d0acb7db19ed \ + --hash=sha256:a169a036bed0995e090d1493b283cc2cc8a6f5046821086b843abefff80643bc \ + --hash=sha256:a2eae53197c6276d5b317f75a1be226bbf440c20b58bf525f36b5d0e1f657ca6 \ + --hash=sha256:a3b19a42111c4057c1547a4a1396a53961dca576a0f6b82bfa88a2d1561764b2 \ + --hash=sha256:a6545e6b409e3d5cbafc850fb84c55a1ca26ed15a6b11e3bf07a0e0cd84517c8 \ + --hash=sha256:a6d73a830b17ef49bc04e00182bd839164c1b3c59c127cd7c54fcb10c7ed8ee8 \ + --hash=sha256:a778b25874cb0f862eaab5986bff4ca49ffb0def7c0a34c237b948b3c6c775b2 \ + --hash=sha256:a7f25baec4c5d851d40718d6fae52285b31683093d4ff5207e63ab306ccf14a5 \ + --hash=sha256:a845a59664d5c531525a467470220f8edc37959e0a6f8e734ffb6654da5c4bee \ + --hash=sha256:a999771ff97bec27d18341be4f3a36b163bb1ac41ec17bef6d2dabd84acd33c7 \ + --hash=sha256:ab9dd2c83c4bbd63e422181a76f13502d049d3ddcac9a1bdc29196263d692bb8 \ + --hash=sha256:abb65b4e947e958f7b3b0d71db3ce447d1bc5f37f5eab871ce7223bda8768a04 \ + --hash=sha256:acbb48679ddf3852c45280c10ff10d52ca2cd1da2e552fb81db1ff786c75d0e4 \ + --hash=sha256:ad37c7792479e49cf96c1ab25517d7003fe0d93687a772ba19a097d235bbe41e \ + --hash=sha256:ad3aa71e12ee634f22b39a0ff439357583706e50765f17f05550f92dbf128a23 \ + --hash=sha256:ae3a39a4d96bdb6f8d154fd7f490c4ad06f0532fcd2bb656052a9a7762cf5d31 \ + --hash=sha256:b081119a6115d2db49e24ab6316b7dcd74651271e9630c7b979999bd0c11973d \ + --hash=sha256:b4e6fe5c6f4e6ad67c1374a7c85c944ca1a8d9672f0a1628201ea5c58e0d4596 \ + --hash=sha256:b59ee2ac81de57771a09ecad09191e840a1d2fae1ef684208320591055768f83 \ + --hash=sha256:b5cd29840505631c6f7dbb8a5d34b742b5e6bbda38fe0b9f54e825f3ea6b61dc \ + --hash=sha256:b7ffeaada9f8699be63d639536b0b60dff73b7d3325b7475c5bc8fdbf4eed47f \ + --hash=sha256:bb16aa13ed175bc9be5c2491ba031b85a9b51c4ed90e0b3d4ebe63cf3fb54f8e \ + --hash=sha256:bfe6f92e3522dcbe8c4281efd74fa7542a336cb00b0e3272c4ec0edabeaeaf67 \ + --hash=sha256:c21625d710f971dd58ae92c5b0c2ca109d2ceba939becc937c5cff9268cd451b \ + --hash=sha256:c3c0059e642b2e7e15c77341a8946f670a403fcd57feecc9e47d68555b9b1c08 \ + --hash=sha256:c40a8ad7d42fe779ac429fe245ed44c54f30e2549173559d70b7167922431701 \ + --hash=sha256:c4fd8acc6e32596350619896feb372033c0920975992d29837c32853bb1feacd \ + --hash=sha256:c50269d0055ac1faecfd559886d2cbe4b730de236585aba0e873f9d9dadbe585 \ + --hash=sha256:c72500a3b6d6c30ebfc135035bcace9eb5884f2dc220804efcaaba43e9f611dd \ + --hash=sha256:c7741c7524961d8c0cb4d4c21b28957ff731a3fd5b5cd8b856dc80a40e9e5acc \ + --hash=sha256:c9b31ab1f28b078a6a1ac1a54eb35e7d5390deddd56870d0be3a0a733d1c321c \ + --hash=sha256:ca12a6d683957a651e3203c1458ff8ab4119aae7363e202e2e820cbfe02df244 \ + --hash=sha256:cb5a888a968b2434abf9ecda357b5d43f10d7b5a6da6fdbbe036208473aff0e2 \ + --hash=sha256:cce1e2782efaf0f595c17fe331cf295882a268c04d5887956e2fc0d262b0fb3a \ + --hash=sha256:cd8ab85c916a58d5c8656ea15e3ce9df836fe2f120a74c296e01d69fab2614b4 \ + --hash=sha256:cee88dfaa6b1b2bfadd3c031fa5f05584870e62fb05dc500942e9900c44fcfda \ + --hash=sha256:cf7424a11a81f59b6f0abdccfbe27c87d552f059ef761471f98245b46b71b5c9 \ + --hash=sha256:d006faf3b491957efcb433489be3c149efe4787b7063d5cddb8ddaefdc60e0c1 \ + --hash=sha256:d1442628c84afa453a9a06a10d74d890d3c1b1e4da313b48b16e1001895fdac4 \ + --hash=sha256:d33fcd60f5546e4b7538a8ae2b2027b51e9905b9a264c32df56de32202997155 \ + --hash=sha256:d41fcda2fa8ca682ebca134a2f2dc02575ba549267585597e73061565795f475 \ + --hash=sha256:d610aa62cdb7d4d497740741772a24a794903bf3e79eaa51d2e800082abe11e5 \ + --hash=sha256:d798c1e291bffb8e37b5bbe0dda77fc767cd19e89cadaf66e6ed5d0ff88c9fe6 \ + --hash=sha256:d7d9110d0c3fb02679972837a033251fd186c529aa62f19c132fc909c74052b8 \ + --hash=sha256:da5b373b1dfce210b8620bdb5d9dae668fe549de67948465dcc39e833d4bbe28 \ + --hash=sha256:dbcd969178d417c2bbd60076f8e407a0e2baf90976eed21c1b818ff8292b902f \ + --hash=sha256:dc026e3b89d98e30a8288c95cb696e77d150b3f0fb7a51f73dcd49ee6b5577fa \ + --hash=sha256:dea2fd4ae84b14aa883ac713faffbb5c26764ec623e00ed34737895be523d1fa \ + --hash=sha256:e64a7c9d7dfca3e0fafcbc5e455519090706a3e36e95d655cec3e04e79f95aaa \ + --hash=sha256:e8ff6ec73110f610425caef3ea875afbfc34caa542f01df3a80f45aadeb9f906 \ + --hash=sha256:ea6daa712f4e094a30830cf01e9b47d03b24d05cc9dab8609f0d9a9db8454712 \ + --hash=sha256:ea85a647fd33d5cf2840027c2e0b7da8868b220d3f05e3866efdda78c440d499 \ + --hash=sha256:ec101643395d7f21405b640f728f6f627e6986557027d740f2f9b220955edafe \ + --hash=sha256:ec68dbba21532c0173a9872298e65c89749f7c9d21538c3a78b5bb6105871568 \ + --hash=sha256:ed4a6efe2dee1655adb73e7ad40c6aa955a6892422b1e3b95de6a34de56e3cbb \ + --hash=sha256:f13319fb8e6ef636f71db3c254d01cbf1543786e10a945a3ff180144618e25b6 \ + --hash=sha256:f14bb8b22a4a91325813e3d553b8963c10cf8c756cff65ee50c194431296c655 \ + --hash=sha256:f1598916cb197681e03e601901e4ab96a9a963de398c59d0964f8a6f44a2b361 \ + --hash=sha256:f1e65d52c2d526734abecb98372c256b7eacce8fdc42e0df8570417fb39e2772 \ + --hash=sha256:f262b8f7599516567e070abf607b9af649052b2c4bd6f9be02b0cb41b7024805 \ + --hash=sha256:f3e7b689c3bce16699efcf736066f5c6cc4472c3840fe4b22bd8279daf4abdac \ + --hash=sha256:f420ad3d41e38194353a498bbc9561fd5a9973a27b536ce46d8583479cf44335 \ + --hash=sha256:f749e52b539e2934171a3718cbf061dc12d74719eddde2d0f025c99637ddbe01 \ + --hash=sha256:f99a15867cbf9fcf753ea72b82a1d6fe6552e6feea3b4842c86a951525685bbb \ + --hash=sha256:f9fd595f1e5941b3d7863e4774e4b30caa6731fc34b9277da032295aa5656ee5 \ + --hash=sha256:fa77e7ec1450d415d20129961814787c9abd9a07f98872f070b1fe96c5084611 \ + --hash=sha256:fc84bf7aa7592f31ec63a3e7b11d624f468a3f19f5238cec7282a42e838ab1d7 \ + --hash=sha256:fd880353cf1ffaf321bc18dd663e111976dbd0d3bbd8a66d58d2b470dfa7f396 \ + --hash=sha256:fdc7d06929ae28dda98297a18eef7b0fd38991a3b405d8d7b55c9ef24c296958 \ + --hash=sha256:fddbbb69a6fff4f421e7a0d1fa28f894b20112e9e3fab306af451e2dfd0e459b \ + --hash=sha256:fe14c356f8b23ad811dc026077a6d4abccdaa7bce5ca98579605550657b6fcfb \ + --hash=sha256:fe32736295ea38e43e7d9424053c8c47c9f64fecfc7c895fb3da9b30b131c9ee \ + --hash=sha256:fe820f104473d1516ecd628993690bc1f79b0e699f32711d42a5a70b3d0f8170 # via datasets -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==4.1.0 \ + --hash=sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f \ + --hash=sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602 # via importlib-metadata zstandard==0.25.0 \ --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ diff --git a/sdk/python/requirements/py3.12-minimal-requirements.txt b/sdk/python/requirements/py3.12-minimal-requirements.txt index 0bda0810dae..1ce930421d2 100644 --- a/sdk/python/requirements/py3.12-minimal-requirements.txt +++ b/sdk/python/requirements/py3.12-minimal-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.12 --no-strip-extras pyproject.toml --extra minimal --generate-hashes --output-file sdk/python/requirements/py3.12-minimal-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -148,9 +149,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -161,38 +162,77 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -287,130 +327,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -420,68 +475,68 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt # pyopenssl # snowflake-connector-python -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -489,50 +544,50 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -540,9 +595,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -678,15 +733,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -696,9 +751,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -710,37 +765,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -784,84 +839,82 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -869,21 +922,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -893,150 +946,175 @@ h11==0.16.0 \ # via # httpcore # uvicorn -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1052,9 +1130,9 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1082,109 +1160,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1277,9 +1355,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1290,9 +1368,7 @@ milvus-lite==2.4.12 \ --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 - # via - # feast (pyproject.toml) - # pymilvus + # via feast (pyproject.toml) mmh3==5.2.1 \ --hash=sha256:022aa1a528604e6c83d0a7705fdef0b5355d897a9e0fa3a8d26709ceaa06965d \ --hash=sha256:0634581290e6714c068f4aa24020acf7880927d1f0084fa753d9799ae9610082 \ @@ -1553,123 +1629,129 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask @@ -1681,85 +1763,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1833,9 +1915,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1845,163 +1927,162 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2040,68 +2121,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2114,12 +2195,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2128,141 +2207,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2270,30 +2348,30 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2312,13 +2390,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2401,9 +2479,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2411,9 +2489,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2421,6 +2499,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python requests-oauthlib==2.0.0 \ @@ -2429,139 +2508,150 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework # typer -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -2570,7 +2660,6 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de @@ -2581,115 +2670,111 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via snowflake-connector-python -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2705,58 +2790,58 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -2765,31 +2850,33 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal # anyio # fastapi + # grpcio # ibis-framework # mcp # mypy @@ -2812,101 +2899,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -2974,116 +2975,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3152,216 +3151,201 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp diff --git a/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt b/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt index 2dca34d757e..0769b0cac0d 100644 --- a/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt @@ -4,6 +4,41 @@ # # pybuild-deps compile --generate-hashes --output-file=sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt sdk/python/requirements/py3.12-minimal-sdist-requirements.txt # +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 @@ -165,52 +200,116 @@ cython==3.0.12 \ # pyyaml # snowflake-connector-python # sqlalchemy -cython==3.2.4 \ - --hash=sha256:02cb0cc0f23b9874ad262d7d2b9560aed9c7e2df07b49b920bda6f2cc9cb505e \ - --hash=sha256:03893c88299a2c868bb741ba6513357acd104e7c42265809fd58dce1456a36fc \ - --hash=sha256:14dae483ca2838b287085ff98bc206abd7a597b7bb16939a092f8e84d9062842 \ - --hash=sha256:1a64a112a34ec719b47c01395647e54fb4cf088a511613f9a3a5196694e8e382 \ - --hash=sha256:28b1e363b024c4b8dcf52ff68125e635cb9cb4b0ba997d628f25e32543a71103 \ - --hash=sha256:28e8075087a59756f2d059273184b8b639fe0f16cf17470bd91c39921bc154e0 \ - --hash=sha256:2b1f12c0e4798293d2754e73cd6f35fa5bbdf072bdc14bc6fc442c059ef2d290 \ - --hash=sha256:31a90b4a2c47bb6d56baeb926948348ec968e932c1ae2c53239164e3e8880ccf \ - --hash=sha256:35ab0632186057406ec729374c737c37051d2eacad9d515d94e5a3b3e58a9b02 \ - --hash=sha256:36bf3f5eb56d5281aafabecbaa6ed288bc11db87547bba4e1e52943ae6961ccf \ - --hash=sha256:3b6e58f73a69230218d5381817850ce6d0da5bb7e87eb7d528c7027cbba40b06 \ - --hash=sha256:3b8e62049afef9da931d55de82d8f46c9a147313b69d5ff6af6e9121d545ce7a \ - --hash=sha256:55b6c44cd30821f0b25220ceba6fe636ede48981d2a41b9bbfe3c7902ce44ea7 \ - --hash=sha256:55eb425c0baf1c8a46aa4424bc35b709db22f3c8a1de33adb3ecb8a3d54ea42a \ - --hash=sha256:64d7f71be3dd6d6d4a4c575bb3a4674ea06d1e1e5e4cd1b9882a2bc40ed3c4c9 \ - --hash=sha256:67922c9de058a0bfb72d2e75222c52d09395614108c68a76d9800f150296ddb3 \ - --hash=sha256:6d5267f22b6451eb1e2e1b88f6f78a2c9c8733a6ddefd4520d3968d26b824581 \ - --hash=sha256:72e6c0bbd978e2678b45351395f6825b9b8466095402eae293f4f7a73e9a3e85 \ - --hash=sha256:732fc93bc33ae4b14f6afaca663b916c2fdd5dcbfad7114e17fb2434eeaea45c \ - --hash=sha256:767b143704bdd08a563153448955935844e53b852e54afdc552b43902ed1e235 \ - --hash=sha256:83266c356c13c68ffe658b4905279c993d8a5337bb0160fa90c8a3e297ea9a2e \ - --hash=sha256:84226ecd313b233da27dc2eb3601b4f222b8209c3a7216d8733b031da1dc64e6 \ - --hash=sha256:869487ea41d004f8b92171f42271fbfadb1ec03bede3158705d16cd570d6b891 \ - --hash=sha256:90f43be4eaa6afd58ce20d970bb1657a3627c44e1760630b82aa256ba74b4acb \ - --hash=sha256:983f9d2bb8a896e16fa68f2b37866ded35fa980195eefe62f764ddc5f9f5ef8e \ - --hash=sha256:b362819d155fff1482575e804e43e3a8825332d32baa15245f4642022664a3f4 \ - --hash=sha256:b84d4e3c875915545f77c88dba65ad3741afd2431e5cdee6c9a20cefe6905647 \ - --hash=sha256:ca2399dc75796b785f74fb85c938254fa10c80272004d573c455f9123eceed86 \ - --hash=sha256:ca578c9cb872c7ecffbe14815dc4590a003bc13339e90b2633540c7e1a252839 \ - --hash=sha256:d4b4fd5332ab093131fa6172e8362f16adef3eac3179fd24bbdc392531cb82fa \ - --hash=sha256:e3b5ac54e95f034bc7fb07313996d27cbf71abc17b229b186c1540942d2dc28e \ - --hash=sha256:e65e4773021f8dc8532010b4fbebe782c77f9a0817e93886e518c93bd6a44e9d \ - --hash=sha256:e71efb20048358a6b8ec604a0532961c50c067b5e63e345e2e359fff72feaee8 \ - --hash=sha256:f136f379a4a54246facd0eb6f1ee15c3837cb314ce87b677582ec014db4c6845 \ - --hash=sha256:f583cad7a7eed109f0babb5035e92d0c1260598f53add626a8568b57246b62c3 \ - --hash=sha256:f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 \ - --hash=sha256:f8d685a70bce39acc1d62ec3916d9b724b5ef665b0ce25ae55e1c85ee09747fc \ - --hash=sha256:fdfdd753ad7e18e5092b413e9f542e8d28b8a08203126090e1c15f7783b7fe57 \ - --hash=sha256:ff9af2134c05e3734064808db95b4dd7341a39af06e8945d05ea358e1741aaed +cython==3.1.1 \ + --hash=sha256:011cdcbf7725f0cfc1abc55ec83d326e788050711272131daf3cc24a19c34bb2 \ + --hash=sha256:020089f9c9f10269181f17660a2cada7d4577bd8eea24b7d2b14e6b64b6996be \ + --hash=sha256:07621e044f332d18139df2ccfcc930151fd323c2f61a58c82f304cffc9eb5280 \ + --hash=sha256:0de7adff5b42d2556d073e9f321c2faa639a17fb195ec1de130327f60ec209d8 \ + --hash=sha256:0e3ccec55e2a534a712db14c6617b66f65ad149c014fad518fc3920f6edde770 \ + --hash=sha256:0f7954b0b4b3302655d3caa6924261de5907a4e129bc22ace52fe9ae0cd5a758 \ + --hash=sha256:10f0434916994fe213ea7749268b88d77e3ebcbd1b99542cf64bb7d180f45470 \ + --hash=sha256:12e00b88147b03c148a95365f89dc1c45a0fc52f9c35aa75ff770ef65b615839 \ + --hash=sha256:141ffd6279411c562f6b707adc56b63e965a4fd7f21db83f5d4fcbd8c50ac546 \ + --hash=sha256:16d9870654946375b28280371d370d541641d1071da123d0d64d2c7ebba0cc56 \ + --hash=sha256:23b886a6c8a50b1101ccef2f2f3dc9c699b77633ef5bb5007090226c2ad3f9c2 \ + --hash=sha256:24c640c0746d984789fe2787a098f06cda456ef2dd78b90164d17884b350839a \ + --hash=sha256:263cb0e497910fb5e0a361ad1393b6d728b092178afecc56e8a786f3739960c3 \ + --hash=sha256:268420b92307ae6c5a16e3cf0e2ba1ae3c861650e992893922a0ce08db07cfdb \ + --hash=sha256:28b174f41718a7041cfbe0f48913020875ff1aaa4793942b2451ac6d2baf3f07 \ + --hash=sha256:307f216ed319ea07644f2ef9974406c830f01bc8e677e2147e9bfcdf9e3ca8ad \ + --hash=sha256:3192a61c2a532d3faccdff508bc8427de9530b587888218bfc0226eb33a84e11 \ + --hash=sha256:3fa4bd840de63509c74867b4b092541720a01db1e07351206011c34e0777dc96 \ + --hash=sha256:402f86c00b08f875cd0990f0c4dc52eb3e0bc5d630066cdf3c798631976f1937 \ + --hash=sha256:40f50b07c479eaf33981d81cad274c68cf9fb81dbe79cbf991f59491c88a4705 \ + --hash=sha256:426d78565eb91d3366569b20e92b8f14bffef5f57b2acd05b60bbb9ce5c056a1 \ + --hash=sha256:505ccd413669d5132a53834d792c707974248088c4f60c497deb1b416e366397 \ + --hash=sha256:50ad80e2f438e9127a87c10927e6ac16a987df39c248b19ab2cd31330129be3c \ + --hash=sha256:54a8934cb3bf13b1f8f6cbdae8e382e25a26e67de08ea6ebfd0a467131b67227 \ + --hash=sha256:56c6768a6f601f93daab7c2487f9f110548a896a91e00a6e119445ada2575323 \ + --hash=sha256:64915259276482fa23417b284d1fdc7e3a618ee2f819bb6ea7f974c075633df6 \ + --hash=sha256:689c1aad373556bd2ab1aa1c2dad8939a2891465a1fbd2cbbdd42b488fb40ec8 \ + --hash=sha256:6ea77ad1e649cec38f8622ba28dcdfbe7bf519bc132abbcf5df759b3975b5a73 \ + --hash=sha256:7489559e6c5ecbba49d535c2e03cf77c2594a3190b6aca7da5b508ba1664a89a \ + --hash=sha256:755a991601b27dd3555310d0f95b19a05e622a80d7b4e7a91fa6f5f3ef3f3b80 \ + --hash=sha256:7da069ca769903c5dee56c5f7ab47b2b7b91030eee48912630db5f4f3ec5954a \ + --hash=sha256:7e5cad896af896482240979b996bf4136b0d18dc40c56c72c5641bf0ea085dfb \ + --hash=sha256:7fff6526bb6f4eea615663117b86de6ede0d17c477b600d3d8302be3502bd3c3 \ + --hash=sha256:83b2af5c327f7da4f08afc34fddfaf6d24fa0c000b6b70a527c8125e493b6080 \ + --hash=sha256:873aac4ac0b0fb197557c0ac15458b780b9221daa4a716881cbd1a9016c8459f \ + --hash=sha256:8aaa29e763adf3496ab9d371e3caed8da5d3ce5ff8fb57433e2a2f2b5036e5c8 \ + --hash=sha256:953046c190fa9ab9a09a546a909b847cdbb4c1fe34e9bfa4a15b6ee1585a86aa \ + --hash=sha256:9b61b99205308c96b1162de59bd67ecadcad3d166a4a1f03a3d9e826c39cd375 \ + --hash=sha256:9d7dc0e4d0cd491fac679a61e9ede348c64ca449f99a284f9a01851aa1dbc7f6 \ + --hash=sha256:a19188ecd385cdc649e3fec370f38d5fd7f1651aeed0b3fb403180f38fc88e8a \ + --hash=sha256:a585796939b09b3205b1980e4a55e745c0251e45a5c637afbcac3c6cc9ad6f90 \ + --hash=sha256:a92f6bd395eadea6eed722a8188d3bdd49db1c9fa3c38710456d6148ab71bad7 \ + --hash=sha256:ab644415458d782c16ba7252de9cec1e3125371641cafea2e53a8c1cf85dd58d \ + --hash=sha256:af8f62cc9339b75fe8434325083e6a7cae88c9c21efd74bbb6ba4e3623219469 \ + --hash=sha256:b181158b5761bdaf40f6854f016ab7ddff64d3db4fca55cb3ca0f73813dd76d6 \ + --hash=sha256:b194a65a0fd91f305d2d1e7010f44111774a28533e1e44dd2a76e7de81a219b9 \ + --hash=sha256:b68f1bc80387554eb43f2b62795c173bed9e37201f39dc5084ac437c90a79c9f \ + --hash=sha256:c360823e1063784efc2335617e0f28573d7a594c5a8a05d85e850a9621cccb1f \ + --hash=sha256:c5cb6c054daadaf01a88c8f49f3edd9e829c9b76a82cbb4269e3f9878254540b \ + --hash=sha256:c740a10cd0f50321d048c8ca318eefb4c42b8bffef982dcd89c946d374192702 \ + --hash=sha256:c8b8be01fd40b3e38a76c60a524f956548a3a7566e5530a833a48a695f3d6c12 \ + --hash=sha256:cb5661941707bd41ec7a9c273d698113ac50392444f785088e9d9706c6a5937b \ + --hash=sha256:cd748fab8e4426dbcb2e0fa2979558333934d24365e0de5672fbabfe337d880c \ + --hash=sha256:cdf53dc4b2a13bd072d6c2c18ac073dbf0f798555bc27ba4f7546a275eb16a0f \ + --hash=sha256:ce82070ccf92c3599d331b9eaaefd9d4562976fb86a8d6bccf05c4a0b8389f2a \ + --hash=sha256:d14186bd96783d13b8fd0e5b289f2e137a8a25479638b73a1c7e4a99a8d70753 \ + --hash=sha256:dee554f0a589377bdaea0eb70e212bf3f35dc6a51a2aa86c9351345e21fd2f07 \ + --hash=sha256:dfa500fd7ae95ca152a5f8062b870532fa3e27efcef6d00612e1f28b9f72615f \ + --hash=sha256:dff0e7dd53a0ca35b64cda843253d5cac944db26663dc097b3a1adf2c49514ad \ + --hash=sha256:e000f0533eedf3d6dfbe30bb3c58a054c58f0a7778390342fa577a0dc47adab3 \ + --hash=sha256:e851ab66a31794e40df1bc6f649cdc56c998c637f5a1b9410c97a90f6b6cb855 \ + --hash=sha256:fd689910002adfac8734f237cdea1573e38345f27ed7fd445482813b65a29457 + # via grpcio +cython==3.2.5 \ + --hash=sha256:05c22cd606ac8d14a9cf17e48668bb37734c803978bf4d793c7f11ef54c4451f \ + --hash=sha256:0a81220817ff954eddf4512a5b82089094a2f523eb1dc4ad555efd6f07b009b4 \ + --hash=sha256:0bc29c7f870b09efdb1f583fbec9592b33af81a7ce273b89c8f5163d7572d5c1 \ + --hash=sha256:220e8b160b2a4ddc362ad8a8c2ab885aa7156099702cdc48f6518a5de921b553 \ + --hash=sha256:224149d18d980e6ea5001b70fc7ce096c1891d59035dfa9cc5ede50f55804913 \ + --hash=sha256:268aecadcabcdad9f773b8a5694746e0b9ee7894b56b84e2e3a2ccb6c929ea79 \ + --hash=sha256:29243859d6824e2d33bae92fc83d591c3671b6d9ac1b757fa264b894ae906c2b \ + --hash=sha256:34d21aeb08477c9173e8be7a566b19e880a7c8109ec6bb47a4b20cb680141114 \ + --hash=sha256:3795237ab49753647e329181b140c424e8aa97543074f171f8d2c45e5014a06e \ + --hash=sha256:382122de8d6b6024fc374fabc3a2b14ba5860ed981c25055ed14fe44278b9dc7 \ + --hash=sha256:3864da4ca2ebe4660d8f672f2143b02840bf3045655222f6090486171c84298f \ + --hash=sha256:39acb30eba78ba6d995d5cf3d97d57d450663d93aac6f8b93753d2b89d768c60 \ + --hash=sha256:3dd42e4cf36ad15f265bdfec2337cc00c688c8eb6d374ffd13bb19437c27bba1 \ + --hash=sha256:3e5e519bad217a0b96fc281666720ed7d339da618acaa012bea712980b8fe6c9 \ + --hash=sha256:45baf00cb8b222a2ca7e9c48add5dac3ceb6e65be4f591150a6b6767ce1f86b0 \ + --hash=sha256:4d00e2c976ee96da4deff50506c7882ccebb4a932fc178ef27eb42bfde959839 \ + --hash=sha256:561613ddd1ee83088eb126e80a5a7d73ee6eb82e0b1aea09afbe170287e5e27f \ + --hash=sha256:56c97c5e43782ec9d9e66c465e253d2ccde0c578c364c46445efe484965524f0 \ + --hash=sha256:5887c24ebd19604b7a76d8ea57446cb562a590f7f2557e5954a69aae38b3195e \ + --hash=sha256:605c447188aecf2941709f53a2ce44862be256e54601c01b38ab710d83db8047 \ + --hash=sha256:677bb60fd8f5949e26c0a7898983967dbbb65f7628481d8480956b85ca766554 \ + --hash=sha256:69cd71b90d4e0f142fd15b2353982c3f9171fc5e613001f16bcb366ffb29004b \ + --hash=sha256:6e5d7a60835345a8bd29d3aa57070880cc3ce017ea0ade7b9f771ce4bf539b1f \ + --hash=sha256:75f5295dc1b32d084fec598f9507e6f264311d78c07da640bc9a05dc47f7ac2c \ + --hash=sha256:85b2944c3eddfc230f9082720195a2e9f869908e5a8b3185be1be832755ee7fc \ + --hash=sha256:8d7b81e6a52a84a02993f01aa5873786ba1dd593c892d93d5fe9866da0bad297 \ + --hash=sha256:91cb5b9ff599612737b3fd0dddcd401acdf904b78c2caf8cd1049501d0a53f2d \ + --hash=sha256:992a50e90d01813333752f374a4405863113059ec67102ab8d6a431a171ee328 \ + --hash=sha256:a3a423468ee77c3c5b26494f57d9c52e9318991fb7142f4c49fb01b99373e8d6 \ + --hash=sha256:a636c8b7824f3cb587eb2fdde59d8f4a14d433565508081cc290198e37567910 \ + --hash=sha256:b4bfb00baef07106a1e5e7252ace18de91225322f7fa29970995aea7c380fa21 \ + --hash=sha256:b8bc1325cf3e4394cc08a3c1ea7fa24f02f405eef0e8c156d5055f6f9a7a1565 \ + --hash=sha256:c4c79e697db55f082a2d3ba97702e71881d5bb1f56f0a80fa338e69101e4c59b \ + --hash=sha256:c80e1e5cba5b4b9890364e9360939fc298c474f25754bb4bb861270d24bda6d6 \ + --hash=sha256:cce98a9011ac6a2560b3587db22912bd0138267669ec567b0d57eddd2d741b8b \ + --hash=sha256:dc1c8cebb7df5bce37f5f8dc1e5bf04313272a5973d50a55c0ec76c83812911b \ + --hash=sha256:eb38b89e5a8eb2508a1a0832063826b0703dfb02be84e4aa34b8818ce0ca50fe \ + --hash=sha256:f4e722ceab6d795b4682d693656218671c873d4aa74119c54a2b62de0e7c48ce \ + --hash=sha256:f9b564f67b01bffa2521f475794b49f2787709cec1f91d5935a38eba37f2b359 # via # pyarrow # uvloop -dunamai==1.26.0 \ - --hash=sha256:5396ac43aa20ed059040034e9f9798c7464cf4334c6fc3da3732e29273a2f97d \ - --hash=sha256:f584edf0fda0d308cce0961f807bc90a8fe3d9ff4d62f94e72eca7b43f0ed5f6 +dunamai==1.26.1 \ + --hash=sha256:2727d939c5b4257cb01ea404372803b477f5176e5a347c43beaf89cd5072e853 \ + --hash=sha256:3b46007bd65b00b4824ead0a1aee365fd22d0ec2b9c219497d4fd48f52860c8b # via uv-dynamic-versioning expandvars==1.1.2 \ --hash=sha256:6c5822b7b756a99a356b915dd1267f52ab8a4efaa135963bd7f4bd5d368f71d7 \ @@ -246,14 +345,6 @@ flit-core==3.12.0 \ # tomli # typing-extensions # wheel -gitdb==4.0.12 \ - --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ - --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf - # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 - # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ --hash=sha256:ce0134c40d63d874ac48f48ccc678b8f3b62b8e50e9318520d2bffc752eedaf3 @@ -280,9 +371,13 @@ hatch-vcs==0.5.0 \ # via # filelock # platformdirs -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.27.0 \ + --hash=sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6 \ + --hash=sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b + # via pymilvus +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # annotated-types # atpublic @@ -307,6 +402,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -319,97 +415,164 @@ jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # via uv-dynamic-versioning -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +libcst==1.8.6 \ + --hash=sha256:04030ea4d39d69a65873b1d4d877def1c3951a7ada1824242539e399b8763d30 \ + --hash=sha256:06fc56335a45d61b7c1b856bfab4587b84cfe31e9d6368f60bb3c9129d900f58 \ + --hash=sha256:089c58e75cb142ec33738a1a4ea7760a28b40c078ab2fd26b270dac7d2633a4d \ + --hash=sha256:08bd63a8ce674be431260649e70fca1d43f1554f1591eac657f403ff8ef82c7a \ + --hash=sha256:0c13d5bd3d8414a129e9dccaf0e5785108a4441e9b266e1e5e9d1f82d1b943c9 \ + --hash=sha256:0cbe17067055829607c5ba4afa46bfa4d0dd554c0b5a583546e690b7367a29b6 \ + --hash=sha256:16cfe0cfca5fd840e1fb2c30afb628b023d3085b30c3484a79b61eae9d6fe7ba \ + --hash=sha256:1a3a5e4ee870907aa85a4076c914ae69066715a2741b821d9bf16f9579de1105 \ + --hash=sha256:1dc3b897c8b0f7323412da3f4ad12b16b909150efc42238e19cbf19b561cc330 \ + --hash=sha256:203ec2a83f259baf686b9526268cd23d048d38be5589594ef143aee50a4faf7e \ + --hash=sha256:207481197afd328aa91d02670c15b48d0256e676ce1ad4bafb6dc2b593cc58f1 \ + --hash=sha256:25eaeae6567091443b5374b4c7d33a33636a2d58f5eda02135e96fc6c8807786 \ + --hash=sha256:25fc7a1303cad7639ad45ec38c06789b4540b7258e9a108924aaa2c132af4aca \ + --hash=sha256:2f04d3672bde1704f383a19e8f8331521abdbc1ed13abb349325a02ac56e5012 \ + --hash=sha256:351ab879c2fd20d9cb2844ed1ea3e617ed72854d3d1e2b0880ede9c3eea43ba8 \ + --hash=sha256:36473e47cb199b7e6531d653ee6ffed057de1d179301e6c67f651f3af0b499d6 \ + --hash=sha256:3649a813660fbffd7bc24d3f810b1f75ac98bd40d9d6f56d1f0ee38579021073 \ + --hash=sha256:375965f34cc6f09f5f809244d3ff9bd4f6cb6699f571121cebce53622e7e0b86 \ + --hash=sha256:3a926a4b42015ee24ddfc8ae940c97bd99483d286b315b3ce82f3bafd9f53474 \ + --hash=sha256:3f4fbb7f569e69fd9e89d9d9caa57ca42c577c28ed05062f96a8c207594e75b8 \ + --hash=sha256:42a4f68121e2e9c29f49c97f6154e8527cd31021809cc4a941c7270aa64f41aa \ + --hash=sha256:44f38139fa95e488db0f8976f9c7ca39a64d6bc09f2eceef260aa1f6da6a2e42 \ + --hash=sha256:455f49a93aea4070132c30ebb6c07c2dea0ba6c1fde5ffde59fc45dbb9cfbe4b \ + --hash=sha256:4d7bbdd35f3abdfb5ac5d1a674923572dab892b126a58da81ff2726102d6ec2e \ + --hash=sha256:4fc3fef8a2c983e7abf5d633e1884c5dd6fa0dcb8f6e32035abd3d3803a3a196 \ + --hash=sha256:536567441182a62fb706e7aa954aca034827b19746832205953b2c725d254a93 \ + --hash=sha256:5432e785322aba3170352f6e72b32bea58d28abd141ac37cc9b0bf6b7c778f58 \ + --hash=sha256:55ec021a296960c92e5a33b8d93e8ad4182b0eab657021f45262510a58223de1 \ + --hash=sha256:59a7e388c57d21d63722018978a8ddba7b176e3a99bd34b9b84a576ed53f2978 \ + --hash=sha256:5dcaaebc835dfe5755bc85f9b186fb7e2895dda78e805e577fef1011d51d5a5c \ + --hash=sha256:6366ab2107425bf934b0c83311177f2a371bfc757ee8c6ad4a602d7cbcc2f363 \ + --hash=sha256:6421a930b028c5ef4a943b32a5a78b7f1bf15138214525a2088f11acbb7d3d64 \ + --hash=sha256:6609291c41f7ad0bac570bfca5af8fea1f4a27987d30a1fa8b67fe5e67e6c78d \ + --hash=sha256:6a65f844d813ab4ef351443badffa0ae358f98821561d19e18b3190f59e71996 \ + --hash=sha256:6aa11df6c58812f731172b593fcb485d7ba09ccc3b52fea6c7f26a43377dc748 \ + --hash=sha256:6b23d14a7fc0addd9795795763af26b185deb7c456b1e7cc4d5228e69dab5ce8 \ + --hash=sha256:6cad63e3a26556b020b634d25a8703b605c0e0b491426b3e6b9e12ed20f09100 \ + --hash=sha256:6d8b67874f2188399a71a71731e1ba2d1a2c3173b7565d1cc7ffb32e8fbaba5b \ + --hash=sha256:72cca15800ffc00ba25788e4626189fe0bc5fe2a0c1cb4294bce2e4df21cc073 \ + --hash=sha256:7445479ebe7d1aff0ee094ab5a1c7718e1ad78d33e3241e1a1ec65dcdbc22ffb \ + --hash=sha256:7f04febcd70e1e67917be7de513c8d4749d2e09206798558d7fe632134426ea4 \ + --hash=sha256:8066f1b70f21a2961e96bedf48649f27dfd5ea68be5cd1bed3742b047f14acde \ + --hash=sha256:819c8081e2948635cab60c603e1bbdceccdfe19104a242530ad38a36222cb88f \ + --hash=sha256:85b7025795b796dea5284d290ff69de5089fc8e989b25d6f6f15b6800be7167f \ + --hash=sha256:87e74f7d7dfcba9efa91127081e22331d7c42515f0a0ac6e81d4cf2c3ed14661 \ + --hash=sha256:8a434c521fadaf9680788b50d5c21f4048fa85ed19d7d70bd40549fbaeeecab1 \ + --hash=sha256:98fa1ca321c81fb1f02e5c43f956ca543968cc1a30b264fd8e0a2e1b0b0bf106 \ + --hash=sha256:a20c5182af04332cc94d8520792befda06d73daf2865e6dddc5161c72ea92cb9 \ + --hash=sha256:b0d8c364c44ae343937f474b2e492c1040df96d94530377c2f9263fb77096e4f \ + --hash=sha256:b188e626ce61de5ad1f95161b8557beb39253de4ec74fc9b1f25593324a0279c \ + --hash=sha256:b6c1248cc62952a3a005792b10cdef2a4e130847be9c74f33a7d617486f7e532 \ + --hash=sha256:ba9ab2b012fbd53b36cafd8f4440a6b60e7e487cd8b87428e57336b7f38409a4 \ + --hash=sha256:bb9b4077bdf8857b2483879cbbf70f1073bc255b057ec5aac8a70d901bb838e9 \ + --hash=sha256:bdb14bc4d4d83a57062fed2c5da93ecb426ff65b0dc02ddf3481040f5f074a82 \ + --hash=sha256:bff00e1c766658adbd09a175267f8b2f7616e5ee70ce45db3d7c4ce6d9f6bec7 \ + --hash=sha256:c0a0cc80aebd8aa15609dd4d330611cbc05e9b4216bcaeabba7189f99ef07c28 \ + --hash=sha256:c188d06b583900e662cd791a3f962a8c96d3dfc9b36ea315be39e0a4c4792ebf \ + --hash=sha256:c41c76e034a1094afed7057023b1d8967f968782433f7299cd170eaa01ec033e \ + --hash=sha256:c9d7aeafb1b07d25a964b148c0dda9451efb47bbbf67756e16eeae65004b0eb5 \ + --hash=sha256:cb2679ef532f9fa5be5c5a283b6357cb6e9888a8dd889c4bb2b01845a29d8c0b \ + --hash=sha256:da95b38693b989eaa8d32e452e8261cfa77fe5babfef1d8d2ac25af8c4aa7e6d \ + --hash=sha256:e00e275d4ba95d4963431ea3e409aa407566a74ee2bf309a402f84fc744abe47 \ + --hash=sha256:f1472eeafd67cdb22544e59cf3bfc25d23dc94058a68cf41f6654ff4fcb92e09 \ + --hash=sha256:f729c37c9317126da9475bdd06a7208eb52fcbd180a6341648b45a56b4ba708b \ + --hash=sha256:fea5c7fa26556eedf277d4f72779c5ede45ac3018650721edd77fd37ccd4a2d4 + # via pyarrow +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -502,22 +665,23 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -maturin==1.12.6 \ - --hash=sha256:06fc8d089f98623ce924c669b70911dfed30f9a29956c362945f727f9abc546b \ - --hash=sha256:2cb41139295eed6411d3cdafc7430738094c2721f34b7eeb44f33cac516115dc \ - --hash=sha256:351f3af1488a7cbdcff3b6d8482c17164273ac981378a13a4a9937a49aec7d71 \ - --hash=sha256:3f32e0a3720b81423c9d35c14e728cb1f954678124749776dc72d533ea1115e8 \ - --hash=sha256:6892b4176992fcc143f9d1c1c874a816e9a041248eef46433db87b0f0aff4278 \ - --hash=sha256:6dbddfe4dc7ddee60bbac854870bd7cfec660acb54d015d24597d59a1c828f61 \ - --hash=sha256:75133e56274d43b9227fd49dca9a86e32f1fd56a7b55544910c4ce978c2bb5aa \ - --hash=sha256:8fdb0f63e77ee3df0f027a120e9af78dbc31edf0eb0f263d55783c250c33b728 \ - --hash=sha256:977290159d252db946054a0555263c59b3d0c7957135c69e690f4b1558ee9983 \ - --hash=sha256:bae91976cdc8148038e13c881e1e844e5c63e58e026e8b9945aa2d19b3b4ae89 \ - --hash=sha256:c0c742beeeef7fb93b6a81bd53e75507887e396fd1003c45117658d063812dad \ - --hash=sha256:d37be3a811a7f2ee28a0fa0964187efa50e90f21da0c6135c27787fa0b6a89db \ - --hash=sha256:e90dc12bc6a38e9495692a36c9e231c4d7e0c9bfde60719468ab7d8673db3c45 \ - --hash=sha256:fa84b7493a2e80759cacc2e668fa5b444d55b9994e90707c42904f55d6322c1e +maturin==1.13.3 \ + --hash=sha256:0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b \ + --hash=sha256:1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3 \ + --hash=sha256:2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b \ + --hash=sha256:3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c \ + --hash=sha256:3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018 \ + --hash=sha256:4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f \ + --hash=sha256:49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff \ + --hash=sha256:4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0 \ + --hash=sha256:53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323 \ + --hash=sha256:771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079 \ + --hash=sha256:a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11 \ + --hash=sha256:b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273 \ + --hash=sha256:c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a \ + --hash=sha256:def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6 # via + # ast-serialize # cryptography # orjson # pydantic-core @@ -541,85 +705,85 @@ mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # pandas # pyarrow -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # hatchling # meson-python @@ -627,17 +791,18 @@ packaging==26.0 \ # scikit-build-core # setuptools-git-versioning # setuptools-scm + # vcs-versioning # wheel -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -pdm-backend==2.4.7 \ - --hash=sha256:1599e3afa6f229b30cb4d3bd9caeca42229c42eb5730abd13e0b5256ec93c9f7 \ - --hash=sha256:a509d083850378ce919d41e7a2faddfc57a1764d376913c66731125d6b14110f +pdm-backend==2.4.9 \ + --hash=sha256:8d1064751dadb0c40b1026b46826a448d85c8228a564985c62fb53d4aba538a1 \ + --hash=sha256:c41a852ccbf4b567b033db9b2ae78660d7a4ea49307719959ab88a01f0aabb2e # via # annotated-doc # fastapi @@ -650,23 +815,22 @@ pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -poetry-core==2.3.1 \ - --hash=sha256:96f791d5d7d4e040f3983d76779425cf9532690e2756a24fd5ca0f86af19ef82 \ - --hash=sha256:db1cf63b782570deb38bfba61e2304a553eef0740dc17959a50cc0f5115ee634 +poetry-core==2.4.1 \ + --hash=sha256:89dceb6c10e9c6d8650a16183400e3c9ff9ddee13b0a81023b5575334a2b3744 \ + --hash=sha256:acf06f9537cd2625bdaec926d95d90b557ba15353bc71d27a3a8a441042b5316 # via # aiohappyeyeballs # dunamai # pkgconfig # rich - # rsa # tomlkit -pybind11-global==3.0.2 \ - --hash=sha256:00a26be4cd65974133eaae7e7532e7141ccb7a88cd131995bc8d1f652852aaf9 \ - --hash=sha256:e183b4456459c35fbbbc8296eb29e241f6cf0774c0bbc3fc8349789611c6df4b +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.2 \ - --hash=sha256:432f01aeb68e361a3a7fc7575c2c7f497595bf640f747acd909ff238dd766e06 \ - --hash=sha256:f8a6500548919cc33bcd220d5f984688326f574fa97f1107f2f4fdb4c6fb019f +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -676,39 +840,115 @@ pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ --hash=sha256:c72fa49418bb7c5a10f25e050c418009898d1c051721d19f98a6fb6da59a66cf # via meson-python +pyyaml==6.0.3 \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ + --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ + --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ + --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ + --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ + --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ + --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ + --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ + --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ + --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ + --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ + --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ + --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ + --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ + --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ + --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ + --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via libcst scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ --hash=sha256:6ea4730da400f9a998ec3287bd3ebc1d751fe45ad0a93451bead8618adbc02b1 # via # duckdb # patchelf + # pyarrow # pybind11 # pybind11-global semantic-version==2.10.0 \ --hash=sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c \ --hash=sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177 # via setuptools-rust -setuptools-git-versioning==3.0.1 \ - --hash=sha256:737c4d17e848edd46e28764a19dc424d8537fcb2257022e5f4f5c0c8e9b64c80 \ - --hash=sha256:c8a599bacf163b5d215552b5701faf5480ffc4d65426a5711a010b802e1590eb +setuptools-git-versioning==3.1.0 \ + --hash=sha256:3a68f3fd58a2a5e86b0792435cfa9d8e569ab60ee5e4c29228c09da9b637bf18 \ + --hash=sha256:612dfcf184addac9e1c2216f4f229724b2390e5bf613fb925ae80b84f2529172 # via toolz -setuptools-rust==1.12.0 \ - --hash=sha256:7e7db90547f224a835b45f5ad90c983340828a345554a9a660bdb2de8605dcdd \ - --hash=sha256:d94a93f0c97751c17014565f07bdc324bee45d396cd1bba83d8e7af92b945f0c - # via maturin -setuptools-scm==7.1.0 \ - --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ - --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e - # via python-dateutil -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-rust==1.12.1 \ + --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ + --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 + # via + # libcst + # maturin +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via # anyio + # cachetools # dask # duckdb # hatch-vcs # httpx-sse + # libcst # pluggy # pyarrow # pybindgen @@ -719,76 +959,75 @@ setuptools-scm==9.2.2 \ # tenacity # tqdm # typeguard - # ujson # urllib3 -smmap==5.0.3 \ - --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ - --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f - # via gitdb -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +setuptools-scm==7.1.0 \ + --hash=sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27 \ + --hash=sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e + # via python-dateutil +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260210 \ - --hash=sha256:5124a7daf67f195c6054e0f00f1d97c69caad12fdcf9113eba33eff0bce8cd2b \ - --hash=sha256:d9719fbbeb185254480ade1f25327c4654f8c00efda3fec36823379cebcdee58 +types-setuptools==82.0.0.20260518 \ + --hash=sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20 \ + --hash=sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -796,22 +1035,31 @@ typing-extensions==4.15.0 \ # via # mypy # setuptools-scm -uv-dynamic-versioning==0.13.0 \ - --hash=sha256:3220cbf10987d862d78e9931957782a274fa438d33efb1fa26b8155353749e06 \ - --hash=sha256:86d37b89fa2b6836a515301f74ea2d56a1bc59a46a74d66a24c869d1fc8f7585 +uv-dynamic-versioning==0.14.0 \ + --hash=sha256:574fbc07e87ace45c01d55967ad3b864871257b98ff5b8ac87c261227ac8db5b \ + --hash=sha256:e087c346a786e98d41292ac2315180fb700cedfb30565fc973d64ce11a112387 # via mcp +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm versioneer==0.29 \ --hash=sha256:0f1a137bb5d6811e96a79bb0486798aeae9b9c6efc24b389659cebb0ee396cb9 \ --hash=sha256:5ab283b9857211d61b53318b7c792cf68e798e765ee17c27ade9f6c924235731 # via # pandas # partd -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # google-crc32c + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # httpx-sse + # libcst # meson # mmh3 # pandas @@ -819,13 +1067,13 @@ wheel==0.46.3 \ # psycopg-c # psycopg-pool # pycparser - # pymilvus # python-dateutil # setuptools-git-versioning # shellingham # snowflake-connector-python # tzdata # uvloop + # wrapt # The following packages are considered to be unsafe in a requirements file: setuptools==80.10.2 \ @@ -836,6 +1084,7 @@ setuptools==80.10.2 \ # aiohttp # aiosignal # anyio + # cachetools # calver # certifi # cffi @@ -844,15 +1093,20 @@ setuptools==80.10.2 \ # dask # dill # frozenlist - # gitpython # google-api-core # google-cloud-bigquery # google-crc32c # googleapis-common-protos # greenlet # grpc-google-iam-v1 + # grpcio + # grpcio-health-checking + # grpcio-reflection + # grpcio-status # gunicorn + # httptools # httpx-sse + # libcst # librt # markupsafe # maturin @@ -865,25 +1119,23 @@ setuptools==80.10.2 \ # pathspec # pluggy # prometheus-client - # propcache # proto-plus # psutil # psycopg - # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser # pyjwt - # pymilvus # pymysql # python-dotenv # pyyaml + # requests # setuptools-git-versioning # setuptools-rust # setuptools-scm # shellingham + # snowballstemmer # snowflake-connector-python # sqlalchemy # sqlglot @@ -894,22 +1146,22 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql - # types-setuptools # tzdata # uvloop + # vcs-versioning # versioneer # websockets # wrapt - # yarl -setuptools==80.9.0 \ - --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ - --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c - # via httptools +setuptools==80.3.1 \ + --hash=sha256:31e2c58dbb67c99c289f51c16d899afedae292b978f8051efaf6262d8212f927 \ + --hash=sha256:ea8e00d7992054c4c592aeb892f6ad51fe1b4d90cc6947cc45c45717c40ec537 + # via psycopg-c setuptools==82.0.1 \ --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via + # propcache # python-dateutil - # setuptools-scm - # ujson + # types-pymysql + # types-setuptools + # yarl diff --git a/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt index 9310559bc4d..651bdb1d313 100644 --- a/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt @@ -1,135 +1,136 @@ # This file was autogenerated by uv via the following command: # uv pip compile -p 3.12 --no-strip-extras pyproject.toml --extra minimal-sdist-build --no-emit-package milvus-lite --generate-hashes --output-file sdk/python/requirements/py3.12-minimal-sdist-requirements.txt -aiobotocore==2.23.1 \ - --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ - --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 +aiobotocore==3.7.0 \ + --hash=sha256:680bde7c64679a821a9312641b759d9497f790ba8b2e88c6959e6273ee765b8e \ + --hash=sha256:c64d871ed5491a6571948dd48eabd185b46c6c23b64e3afd0c059fc7593ada30 # via feast (pyproject.toml) -aiohappyeyeballs==2.6.1 \ - --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ - --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 +aiohappyeyeballs==2.6.2 \ + --hash=sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4 \ + --hash=sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64 # via aiohttp -aiohttp==3.13.3 \ - --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ - --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ - --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ - --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ - --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ - --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ - --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ - --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ - --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ - --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ - --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ - --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ - --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ - --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ - --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ - --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ - --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ - --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ - --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ - --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ - --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ - --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ - --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ - --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ - --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ - --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ - --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ - --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ - --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ - --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ - --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ - --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ - --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ - --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ - --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ - --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ - --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ - --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ - --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ - --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ - --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ - --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ - --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ - --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ - --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ - --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ - --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ - --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ - --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ - --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ - --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ - --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ - --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ - --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ - --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ - --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ - --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ - --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ - --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ - --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ - --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ - --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ - --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ - --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ - --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ - --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ - --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ - --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ - --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ - --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ - --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ - --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ - --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ - --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ - --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ - --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ - --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ - --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ - --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ - --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ - --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ - --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ - --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ - --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ - --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ - --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ - --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ - --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ - --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ - --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ - --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ - --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ - --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ - --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ - --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ - --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ - --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ - --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ - --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ - --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ - --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ - --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ - --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ - --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ - --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ - --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ - --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ - --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ - --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ - --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ - --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ - --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ - --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ - --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ - --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ - --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ - --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ - --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ - --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ - --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 - # via aiobotocore +aiohttp==3.14.0 \ + --hash=sha256:02cb2ffbb7da32f82e21ad9952669c45bd88a80e0878264c2f59fe1c6fb2badd \ + --hash=sha256:0746d9fb0ac4fdef643a84494efe3f06d50335dd8c7a530228b86448aae0a803 \ + --hash=sha256:076cb014191ae2e65d949e1ad01f1dcfe33e32789b5172510f3e79c79fc04d50 \ + --hash=sha256:0fc2b75ae8d169d853be2862d960be8550da6c5c65711d5476407eb3fdb006bd \ + --hash=sha256:101df7779c80c0636014a6b2c6642acd3efb5b355d48347c9d7dfb720aee9430 \ + --hash=sha256:106ed074a856f3e21d186b8579e2c8afb6da598e267cdaab01059e13db2fc44d \ + --hash=sha256:1210d4c87cc00128160c7384ab41877a701295b97cffa6362f908a49b6e8a7ca \ + --hash=sha256:1394dce36e0f0d260ac0b555a654de19cb989f3c1b8bdd24f505314dfea18a00 \ + --hash=sha256:145262119b07d7f95abc1839add35ba2bfc84551d4b4660ca11542c0b215455b \ + --hash=sha256:16eee56bcc72d04600bc56c1759982c2385ec0b41d3fd3521f836bf64a0957ef \ + --hash=sha256:198cfe61bf253b19da1fb3e0fa122249dc4f14c12709493fed8054aa0411cc76 \ + --hash=sha256:19ca5fc84130675ba11c6ca5c7da5cb65f7bf8a32cdd2b616bf49cd334688aae \ + --hash=sha256:1a4a9f17e85b80878c176695c1998c790e83731d8271881e5d356488652a1f9e \ + --hash=sha256:1a78a77366ed158a0a54b076990e575d7b7cdb728cbfd02711eadab150f2269f \ + --hash=sha256:20144819e99db593e22bbd2f3f2691a5e149f879142d6b8670254708853ff4fb \ + --hash=sha256:22a8d06f204e0518a586d770032db3c7043c9ba3693081b3e3ad425e1458d594 \ + --hash=sha256:23e8314e7aed8576fbe33314d218bd81447a3adbc91dc36f1163bf583cd3084c \ + --hash=sha256:23f094a1ef64823fd35854ddf5c7a80a078162f37f9d2f7c6142b51a6affa456 \ + --hash=sha256:25400d710641a8040bf022a8a99f579e581ffa1c5bd42c33255d7d6f3957c127 \ + --hash=sha256:25d2326a4967bf705a9f9913a13005e93b6020ad8a9f6bd6bd78850d5171332e \ + --hash=sha256:25e9f1d2465a210d60edb64d7b204a147e85d4c194eecef3d1604fb5ace678ce \ + --hash=sha256:26b6d79aa54cb4ed50cc7d41ed14e99e0f1fc8e7c2d42f2e05b37aea897b2b52 \ + --hash=sha256:26d9224c6dd7f5c749aba4f61315a894601448b28d94d12f4dea0903e26d2096 \ + --hash=sha256:2882de819734c715fd1b9c11c97e09fa020d14438203d1d354d8ed1702791c9b \ + --hash=sha256:28eee8de1d69711c53116df8202f1c2aa0e3f80ef912a88fc18d159d53e7110b \ + --hash=sha256:2c2c7e05dd5335b298085abf45ddf98673934c3ee1c083d0b9ea13d4186ad500 \ + --hash=sha256:2cc736a9c9fc2bc4dd71fd404815741b6573df27c3f985948ec4076989ac57de \ + --hash=sha256:2d2ffe9b614f50f069068b3b52e73414e4107fc10b7efc939a76acff9251fdd2 \ + --hash=sha256:2e2514cb7195f6d7c219339635bea71ae47d1569b051300d32df9dcfabcdb869 \ + --hash=sha256:2f3fc37054564dee64a855b5b092d87ec35dcddfaabf7dacb1c8a2b1f83dc0a9 \ + --hash=sha256:30e8b7eeb42d02c120ca90d6c6e076a221a16b70a6dac9ae44c7ab5104cc7fe4 \ + --hash=sha256:32e735c3182de7b64f6941a4ede48b38c7f47d9437bd615dd30b5bda8fa1bc93 \ + --hash=sha256:3366751d68d237c621264233a32f3078bbc21b7904ab90a77e03d21390c742c6 \ + --hash=sha256:363ef9e91014e7891679bfb2ac0a7c6ea93435dbbfd10ecf41b9f06fcf506c5f \ + --hash=sha256:3b54fbff46127aeafdd764cecd0d99fa2f24a0e37ea5c18a7c3a4ac450df1db3 \ + --hash=sha256:3c7139100fbaae76515b73051d8f0aa3a3ff02e415eec8a8eee8e2223d9ba955 \ + --hash=sha256:3cdf534aa455593e589302990c5097aa5c92c06c4262a20da22934f9186a5fff \ + --hash=sha256:3ea81eb518a2ecb319d8ec6d1424a37c773f6634bd87d6985eb606b2faac419f \ + --hash=sha256:40ae7b0642c25632c7eabc4a04754012691864d2a1b93becf7cddb76027b838a \ + --hash=sha256:40af7ebe53c7990e110dc4ad03566b12c3ac996254298a3d39046dd69cfcb2c2 \ + --hash=sha256:44eca38755d0105bb32f47d085f5dd449846a449e1245fc105889e3279dcf8e3 \ + --hash=sha256:46fbbec4e4fab7428d4396a3823f9320e4560aa3113b89eeebce712c27c9ed5a \ + --hash=sha256:4714c70067a08b604d0bf3bc4dfdf82e52944afab41d0428d460862763d2f79b \ + --hash=sha256:49a33ded29b0b2fa7a367a02cf0fb89af602bb87542a16177ec8ce1c9c51d12a \ + --hash=sha256:4acfc34bd4d3c58754fc9f22ff1b5e92aabce68f3d4bf7b71a0b732d9bceb78a \ + --hash=sha256:4d6a998191f5ebe3b8c28463ff72bc030250008b3193c402464efadd08b5ca02 \ + --hash=sha256:4f770846edae8f00ecc57af825bce811f787f87a7dcf0e90d191790efe5b31f7 \ + --hash=sha256:514db9a79337068981ee2137310283a07b4b885c584991097a91a4da419bcb81 \ + --hash=sha256:540632bf882ff8fc88f2e1697be0761578e89e0d79fb4a8a6d65dc5da7e729d4 \ + --hash=sha256:54bf3522d6f7351e55f89a62d5c2bf138ad557b031670266c5df604ae88e0b5a \ + --hash=sha256:57ea07d28695a7a40304d42251892a8df765e5588c10ee32afeddcd5df33c0a2 \ + --hash=sha256:5a2e7ca615c3ddc15b82687e05a624e5f5cba3f1d6c20cb81172d70ea498451e \ + --hash=sha256:5ba10966d4f03dd96a14365be4b8e37c327c76f11c3ca867116966cdd9f98066 \ + --hash=sha256:5cbd50e6a50d6b99283a826b18cbdebf65b0797689a7535cb0e9dd37be0f63c3 \ + --hash=sha256:5e4646e9a6af29af354204011bf5769cb0276ec5b64653e42f90b3e13845169f \ + --hash=sha256:5f1c5be60add78fabb4aacd13c5a348ae79d2fcbfc7fa78da8f1eb192273b370 \ + --hash=sha256:610d68800435903e303ca0542b9d3e4eb72a12ff33a6d471a070c1d81eebd3c2 \ + --hash=sha256:6199707cc40e0e9cd39c36fbc97bec416c704e1d0ddce03412bb3b3e6a90ccd0 \ + --hash=sha256:6281aecdf2732940f4fe06bd6adec5ae4d59b78b080b8e3a6b81467301010988 \ + --hash=sha256:63e38be0d75a654deaa06be32fb4cab883a4222940be1d05861b6717679cbadb \ + --hash=sha256:666c7c5036df57b693026398b69b41874a1931ac5b3485fd910e57bfac253869 \ + --hash=sha256:667b881d083ccae3900ea5a241e17e5007ca78844c53ed389bb63d48f729d9c7 \ + --hash=sha256:692e409052e7436029bbb32977cd7c5bf806ac5fa4085b973996785ffadad33c \ + --hash=sha256:6a5f3532125233c261cf61f32df4059cfcf482eb793c7d3db8452e3142028b86 \ + --hash=sha256:6aa1a40f9cbb3da9f80714c5966b8946c21e6a2530d809b9498b33161e3c8733 \ + --hash=sha256:6c79a044cacf360ec46738d863d2f41c9300d2a06ef4a7402ea0df306a350e61 \ + --hash=sha256:6eb63b1417efaf7d1002a6ad034a40d44376afcc16508a57f8e74b49ad26a095 \ + --hash=sha256:70ea956f6cc4a37620966b56c2e205d88ca3e6d85ec063277e414b1035cddad3 \ + --hash=sha256:71b2604c9bfc1b115547d63a094d5244b3f02799833513a99a68aaa7b167c4cb \ + --hash=sha256:78d6f9286a629ce52728430afe18f8ed2b6c39a1fddb3802d7244b9983910ad2 \ + --hash=sha256:7a3fc4358e65826c515350f199c210de747cf669998211b1ee6c2e46de364b24 \ + --hash=sha256:7b33e751cab03fdc960095b1e326cb5a03f5ee577d6ded59f3d1c100f8668882 \ + --hash=sha256:85e0675f47be4eff0636bf88c02140ea89168ae0df3ff1f3f464e9de9610d277 \ + --hash=sha256:860a86bc2c80237f5dff52edcf427e10a8d8352271fd84845429a3e60199e02c \ + --hash=sha256:884a4edbdad77be9d0ef36142c8b504351b170df0bf62b51e784fadabf311c42 \ + --hash=sha256:89ed35666c95d3efe1955056afcde09e62a57a34e2a4398b17f9f6c1564f0b25 \ + --hash=sha256:8b93618102caf12801638a01a2b478a55410ddd71bd41cfaf6f707953a49ac43 \ + --hash=sha256:8fcaef74d2ab0f607d7ff85a0d15e21bb5a258c4a58df1908396eb50d7f4ed3c \ + --hash=sha256:95f5217e76a046b9f228a101717ef8d42b1eb3d9d196d15202db5bf41df88936 \ + --hash=sha256:9dc203d6ce6b9106d54e2a93f41dfdfebfbca2d99962ba503bfd3e5921a6549e \ + --hash=sha256:9e19d17ab02bf16832a2c8c0d55a486792c5b1645665652ee9531aebcc30cb72 \ + --hash=sha256:9f3a96b6d39a4872222beee72e1df41d2ff886ae96152cf3e757ef8c5673ef0e \ + --hash=sha256:a071be341c2bd9b0188e62d173509f024e0a35b1c342c53c50f8daaeda8c3bd8 \ + --hash=sha256:a150c0875ac8fd87f1c398650841308a30d65facf7416b12dbdb9cfdcbe5a48c \ + --hash=sha256:a1d209375c503472b3c0a340cdf3c55fcd82e84b46dda7caeaced59faba373ec \ + --hash=sha256:a8d93334d4961c9d566b1f046c81dee475b7c21eb730728d38237bfa70d1c8e6 \ + --hash=sha256:acdb400538cf4769543548bb5d1eb23d39bed4f96554a6078cb728c7cb2c268b \ + --hash=sha256:acf1581c4f21ed4b80a2dded504d87b055a071a84d5737ea966435f768275ac6 \ + --hash=sha256:b0a5747586d4467efd1f932710b269131c9717a872dce082cd92a00c1c13123a \ + --hash=sha256:b27d89af91a555f58e08e4902dbcbc48862fd40095720ca705990476bd93b7ac \ + --hash=sha256:b29518c9c2ec7e373e68259206a137c7f4f5439c58baaec4b5ab3ab799850a4e \ + --hash=sha256:b4141a3e5342ee3053a9cab54d25b64ed28289c1041e4c54b3d99839314d90ce \ + --hash=sha256:b5314743ebe926c2fda35d0a298c565c885505f6635c2a30936363404cf274a7 \ + --hash=sha256:b584dfe615d151e9b8f0a8ecb3aee6147f2927ec5b95ba25fe621f5377510928 \ + --hash=sha256:b62af5a8cc96a194eaa01a9ed7b34a3ffa58d3d8daaa1a0d7a749353ad12d228 \ + --hash=sha256:c20b9ad156a79eb97be5cf9e069eec01d2f0dc8472ffbd75299a8b2d4c2cbbde \ + --hash=sha256:c21ca9a1c63d4509158f478aeb9d02914dcc52adc68d1bc9dee2452284ee5996 \ + --hash=sha256:c452d17eeb95d563fc8b936f3050301dbd1d268126c4632d8b70ede9696202ee \ + --hash=sha256:c5492b9929826e07cc3fcb9739ae87aab05dff6b5e67a9b73fd1700c6d008981 \ + --hash=sha256:cb6c657104393b5fbff01a5f59b2023db74058a8077d94475d6c25d03882a108 \ + --hash=sha256:cc3c3e12cdaeb92d7dcf13db00e9f6b1956b910e47256e696df1cfa946d02159 \ + --hash=sha256:d1467d1e7b48a73ca7237e0ee4335f3d02b923dbc27b82fd254bc301c97d4026 \ + --hash=sha256:d336820adbb914debbc90a1d8c1bfc4bea55996aecf64866a989d35d1f9fd903 \ + --hash=sha256:d33e61021222ce7f9792bcac870d6f58d8adfceda33ab857b01264f4560f2c5f \ + --hash=sha256:d488e6e9d3bb8ba5ae7066d5be885ae9670eba021b8c6ccb9a3a568e6b19d6e5 \ + --hash=sha256:d925fba0c14d5b498a8028b0107beebdfd16c5d48d702ff54f879cb017aaaca3 \ + --hash=sha256:dbec68ce61b64cb73cab4d33df9433427b1713c8bcccb181dce695c1b6f8e87c \ + --hash=sha256:e03abdaa17d553f17e1d1d06bb266b3970106c78051d06795723e748d8e49d11 \ + --hash=sha256:e30871b2d58996cb81aac52d2b1d15ac05257131ef0f90f18c2115a380fbfe7c \ + --hash=sha256:e4c01b0bfc6209590960e68eac083cd22d5d87c21f974dd6208cafa5d3542bc8 \ + --hash=sha256:ea3b9806c89f61da22fddf1f12dd524fb368e5e28f1261fbdafe5c3cd8ce893b \ + --hash=sha256:ed94a81506e3d1bdbad5108f497a58f2a2354aedb4ca314d5326f07d1fd1ac2d \ + --hash=sha256:edc01ea4e1ec5a1649a28866262bf24195889ff7b27bdd947029a6086741de9b \ + --hash=sha256:f0b7b8bbbec3ce9467ee0ebe334622fd90624f593edd3136c567811453fc4fae \ + --hash=sha256:f12eb7896e81caf403a2b18c9406426f1207361e7239c057ab29c076d4257e83 \ + --hash=sha256:f13087e06f68fea4941c21a0c541c00553aa16e4f8fd7bbe2b198df761e964d6 \ + --hash=sha256:f4d2038c64f36df96cfd3fa0937910e231eafbf897e70a06c155a817bb632fa6 \ + --hash=sha256:f79bfd2847513a7ac801bbafd1de02348a37926ac439eeb4bfe96fcff4eada15 \ + --hash=sha256:ff82be7f1ef73634cb77890a770743239bc3d487b848669be1c599889336dc0a + # via + # aiobotocore + # kubernetes aioitertools==0.13.0 \ --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c @@ -152,9 +153,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # httpx # mcp @@ -165,13 +166,48 @@ asn1crypto==1.5.1 \ --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 # via snowflake-connector-python +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy atpublic==7.0.0 \ --hash=sha256:466ef10d0c8bbd14fd02a5fbd5a8b6af6a846373d91106d3a07c16d72d96b63e \ --hash=sha256:6702bd9e7245eb4e8220a3e222afcef7f87412154732271ee7deee4433b72b4b # via ibis-framework -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # aiohttp # jsonschema @@ -180,31 +216,35 @@ babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ --hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # via sphinx -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -boto3==1.38.27 \ - --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ - --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 +boto3==1.43.0 \ + --hash=sha256:80d44a943ef90aba7958ab31d30c155c198acc8a9581b5846b3878b2c8951086 \ + --hash=sha256:8ebe03754a4b73a5cb6ec2f14cca03ac33bd4760d0adea53da4724845130258b # via # feast (pyproject.toml) # snowflake-connector-python -botocore==1.38.46 \ - --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ - --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b +botocore==1.43.0 \ + --hash=sha256:cc5b15eaec3c6eac05d8012cb5ef17ebe891beb88a16ca13c374bfaece1241e6 \ + --hash=sha256:e933b31a2d644253e1d029d7d39e99ba41b87e29300534f189744cc438cdf928 # via # aiobotocore # boto3 # s3transfer # snowflake-connector-python +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via pymilvus calver==2025.3.31 \ --hash=sha256:07511edf5e7fa75ae97445c8c5921240e0fe62937289a3ebe6963eddd3c691b6 \ --hash=sha256:255d1a70bba8f97dc1eee3af4240ed35980508da69257feef94c79e5c6545fc7 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via # httpcore # httpx @@ -299,130 +339,145 @@ cffi==2.0.0 \ # via # feast (pyproject.toml) # cryptography -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask - # typer # uvicorn cloudpickle==3.1.2 \ --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ @@ -432,56 +487,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.5 \ - --hash=sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72 \ - --hash=sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235 \ - --hash=sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9 \ - --hash=sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356 \ - --hash=sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257 \ - --hash=sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad \ - --hash=sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4 \ - --hash=sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c \ - --hash=sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614 \ - --hash=sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed \ - --hash=sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31 \ - --hash=sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229 \ - --hash=sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0 \ - --hash=sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731 \ - --hash=sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b \ - --hash=sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4 \ - --hash=sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4 \ - --hash=sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263 \ - --hash=sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595 \ - --hash=sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1 \ - --hash=sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678 \ - --hash=sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48 \ - --hash=sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76 \ - --hash=sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0 \ - --hash=sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18 \ - --hash=sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d \ - --hash=sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d \ - --hash=sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1 \ - --hash=sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981 \ - --hash=sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7 \ - --hash=sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82 \ - --hash=sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2 \ - --hash=sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4 \ - --hash=sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663 \ - --hash=sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c \ - --hash=sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d \ - --hash=sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a \ - --hash=sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a \ - --hash=sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d \ - --hash=sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b \ - --hash=sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a \ - --hash=sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826 \ - --hash=sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee \ - --hash=sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9 \ - --hash=sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648 \ - --hash=sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da \ - --hash=sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2 \ - --hash=sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2 \ - --hash=sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87 +cryptography==48.0.0 \ + --hash=sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13 \ + --hash=sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6 \ + --hash=sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8 \ + --hash=sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25 \ + --hash=sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c \ + --hash=sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832 \ + --hash=sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12 \ + --hash=sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c \ + --hash=sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7 \ + --hash=sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c \ + --hash=sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec \ + --hash=sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5 \ + --hash=sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355 \ + --hash=sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c \ + --hash=sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741 \ + --hash=sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86 \ + --hash=sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321 \ + --hash=sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a \ + --hash=sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7 \ + --hash=sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920 \ + --hash=sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e \ + --hash=sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff \ + --hash=sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd \ + --hash=sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3 \ + --hash=sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f \ + --hash=sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602 \ + --hash=sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855 \ + --hash=sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18 \ + --hash=sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a \ + --hash=sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336 \ + --hash=sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239 \ + --hash=sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74 \ + --hash=sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a \ + --hash=sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c \ + --hash=sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4 \ + --hash=sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c \ + --hash=sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f \ + --hash=sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4 \ + --hash=sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db \ + --hash=sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166 \ + --hash=sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5 \ + --hash=sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f \ + --hash=sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae \ + --hash=sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20 \ + --hash=sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a \ + --hash=sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057 \ + --hash=sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb \ + --hash=sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c \ + --hash=sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b # via # google-auth # pyjwt @@ -553,13 +608,13 @@ cython==3.0.12 \ --hash=sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3 \ --hash=sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -db-dtypes==1.5.0 \ - --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ - --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 +db-dtypes==1.7.0 \ + --hash=sha256:30951c7cda9e5455e43636eebe041c9a637ff28bc49a95d82cb68759d7625467 \ + --hash=sha256:c80a1d9bc7dda3cc63638a3f2cf4ec27af50b809ec2d92b8a94cb9d8438cdc76 # via # google-cloud-bigquery # pandas-gbq @@ -571,50 +626,50 @@ docutils==0.22.4 \ --hash=sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968 \ --hash=sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # via sphinx -duckdb==1.5.0 \ - --hash=sha256:065ae50cb185bac4b904287df72e6b4801b3bee2ad85679576dd712b8ba07021 \ - --hash=sha256:0ee4dabe03ed810d64d93927e0fd18cd137060b81ee75dcaeaaff32cbc816656 \ - --hash=sha256:11ae50aaeda2145b50294ee0247e4f11fb9448b3cc3d2aea1cfc456637dfb977 \ - --hash=sha256:11dd05b827846c87f0ae2f67b9ae1d60985882a7c08ce855379e4a08d5be0e1d \ - --hash=sha256:122396041c0acb78e66d7dc7d36c55f03f67fe6ad012155c132d82739722e381 \ - --hash=sha256:13f94c49ca389731c439524248e05007fb1a86cd26f1e38f706abc261069cd41 \ - --hash=sha256:1b74cb205c21d3696d8f8b88adca401e1063d6e6f57c1c4f56a243610b086e30 \ - --hash=sha256:1df8c4f9c853a45f3ec1e79ed7fe1957a203e5ec893bbbb853e727eb93e0090f \ - --hash=sha256:238d576ae1dda441f8c79ed1370c5ccf863e4a5d59ca2563f9c96cd26b2188ac \ - --hash=sha256:2b546a30a6ac020165a86ab3abac553255a6e8244d5437d17859a6aa338611aa \ - --hash=sha256:2deebcbafd9d39c04f31ec968f4dd7cee832c021e10d96b32ab0752453e247c8 \ - --hash=sha256:3298bd17cf0bb5f342fb51a4edc9aadacae882feb2b04161a03eb93271c70c86 \ - --hash=sha256:47fbb1c053a627a91fa71ec883951561317f14a82df891c00dcace435e8fea78 \ - --hash=sha256:4a2cd73d50ea2c2bf618a4b7d22fe7c4115a1c9083d35654a0d5d421620ed999 \ - --hash=sha256:4f514e796a116c5de070e99974e42d0b8c2e6c303386790e58408c481150d417 \ - --hash=sha256:5ad8d9c91b7c280ab6811f59deff554b845706c20baa28c4e8f80a95690b252b \ - --hash=sha256:5faeebc178c986a7bfa68868a023001137a95a1110bf09b7356442a4eae0f7e7 \ - --hash=sha256:63a8ea3b060a881c90d1c1b9454abed3daf95b6160c39bbb9506fee3a9711730 \ - --hash=sha256:6be5e48e287a24d98306ce9dd55093c3b105a8fbd8a2e7a45e13df34bf081985 \ - --hash=sha256:6e56c19ffd1ffe3642fa89639e71e2e00ab0cf107b62fe16e88030acaebcbde6 \ - --hash=sha256:86525e565ec0c43420106fd34ba2c739a54c01814d476c7fed3007c9ed6efd86 \ - --hash=sha256:9409ed1184b363ddea239609c5926f5148ee412b8d9e5ffa617718d755d942f6 \ - --hash=sha256:9a3d3dfa2d8bc74008ce3ad9564761ae23505a9e4282f6a36df29bd87249620b \ - --hash=sha256:9ea988d1d5c8737720d1b2852fd70e4d9e83b1601b8896a1d6d31df5e6afc7dd \ - --hash=sha256:a1156e91e4e47f0e7d9c9404e559a1d71b372cd61790a407d65eb26948ae8298 \ - --hash=sha256:a43f8289b11c0b50d13f96ab03210489d37652f3fd7911dc8eab04d61b049da2 \ - --hash=sha256:a5ee41a0bf793882f02192ce105b9a113c3e8c505a27c7ef9437d7b756317113 \ - --hash=sha256:ab9d597b1e8668466f1c164d0ea07eaf0ebb516950f5a2e794b0f52c81ff3b16 \ - --hash=sha256:cb786d5472afc16cc3c7355eb2007172538311d6f0cc6f6a0859e84a60220375 \ - --hash=sha256:cf503ba2c753d97c76beb111e74572fef8803265b974af2dca67bba1de4176d2 \ - --hash=sha256:d4b618de670cd2271dd7b3397508c7b3c62d8ea70c592c755643211a6f9154fa \ - --hash=sha256:d6d2858c734d1a7e7a1b6e9b8403b3fce26dfefb4e0a2479c420fba6cd36db36 \ - --hash=sha256:dc92b238f4122800a7592e99134124cc9048c50f766c37a0778dd2637f5cbe59 \ - --hash=sha256:f8e42aaf3cd217417c5dc9ff522dc3939d18b25a6fe5f846348277e831e6f59c \ - --hash=sha256:f974b61b1c375888ee62bc3125c60ac11c4e45e4457dd1bb31a8f8d3cf277edd +duckdb==1.5.3 \ + --hash=sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836 \ + --hash=sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22 \ + --hash=sha256:10960400ed60cdf0fe05bab2086fa8eb733889cb0ceca18d07ff9a00c0e0be7b \ + --hash=sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888 \ + --hash=sha256:3248b49cd835ea322574bc6aac0ae7a83be85547f49d4f5f5777cb380ee6627f \ + --hash=sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538 \ + --hash=sha256:341a2672e2551ba51c95c1898f0ade983e76675e79038ccb16342c3d6cfb82d7 \ + --hash=sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7 \ + --hash=sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe \ + --hash=sha256:50379b85f3a0a169478d54880ef8bf971ecaa85772d05eeaa617d720c7704741 \ + --hash=sha256:5fd25f533cb1b6b2c84cc767a9a9bab7769bb1aa44571a2a0bfc91ac3e4a38ac \ + --hash=sha256:6d2835e39bb6af73891f73c0f8d4324f98afe00d0b00c6d34b2a582c2256cbb0 \ + --hash=sha256:6ef8faf121d7b3ad95aab1c3ce31169a28be49da75abfa6099a1bec2e9a70189 \ + --hash=sha256:70a18f932cf6d87bd0e554613657a515c1443a1724aacfc7ec5137dd28698b03 \ + --hash=sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4 \ + --hash=sha256:75d13308c9da3ee431d1e72b8ab720aa74a1b3e9159d4124cb62435924496334 \ + --hash=sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e \ + --hash=sha256:8001eccbc28be244dfd04d708526f34ddd6460b47a8aeb5d0e39d6f7f9e3fe15 \ + --hash=sha256:9fb7516255a8764545e30f7efacea408cc847764a3027b3b0b3e7d1a7bebbc5c \ + --hash=sha256:a3fb3bad9bc1a3e101d66d33269142ce075dc3d75202ba74ba97d7e44c50b9cd \ + --hash=sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30 \ + --hash=sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf \ + --hash=sha256:c5f18e7561403054433706c187589e86629a7af09a7efc23a06a8b308e6acc68 \ + --hash=sha256:c9e8fa408705081160ede7ead238d16e73a36b8561b700f2bf2d650ae48e7b92 \ + --hash=sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13 \ + --hash=sha256:d37650ec3ec8a951400ea12dc77edaea88e0baeda34801792776f95f2f922f4f \ + --hash=sha256:dd00f70231951a619908471b7b6397232ff3be8ccd1f49a47f1a2ccac59eaba1 \ + --hash=sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16 \ + --hash=sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc \ + --hash=sha256:e80eb4d0fb59869cb2c7d7ef494c07fb92014fe8e77d96c170cd1ebc1488a708 \ + --hash=sha256:f4eff89c12c3a362efa012262e57b7b4ab904a7f79bad9178fe365510077abe8 \ + --hash=sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76 \ + --hash=sha256:fdc65233f0fcf9022e4c6a8ba2ba751a79deb291501073d660afb1aa9874051f \ + --hash=sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1 \ + --hash=sha256:ff11a457258148337ef9a392148a8cdbd1069b6c27c21958816c7b67fe6c542d # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via # feast (pyproject.toml) # fastapi-mcp @@ -622,9 +677,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.0 \ - --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ - --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 +filelock==3.29.1 \ + --hash=sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b \ + --hash=sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -764,15 +819,15 @@ frozenlist==1.8.0 \ # via # aiohttp # aiosignal -fsspec==2024.9.0 \ - --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ - --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.0 \ - --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ - --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 +google-api-core[grpc]==2.31.0 \ + --hash=sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2 \ + --hash=sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab # via # feast (pyproject.toml) # google-cloud-bigquery @@ -782,9 +837,9 @@ google-api-core[grpc]==2.30.0 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.0 \ - --hash=sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae \ - --hash=sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87 +google-auth==2.53.0 \ + --hash=sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68 \ + --hash=sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c # via # google-api-core # google-auth-oauthlib @@ -796,37 +851,37 @@ google-auth==2.49.0 \ # google-cloud-storage # pandas-gbq # pydata-google-auth -google-auth-oauthlib==1.3.0 \ - --hash=sha256:386b3fb85cf4a5b819c6ad23e3128d975216b4cac76324de1d90b128aaf38f29 \ - --hash=sha256:cd39e807ac7229d6b8b9c1e297321d36fcc8a9e4857dff4301870985df51a528 +google-auth-oauthlib==1.4.0 \ + --hash=sha256:18b5e28880eb8eba9065c436becdc0ee8e4b59117a73a510679c82f70cd363d2 \ + --hash=sha256:251314f213a9ee46a5ae73988e84fd7cca8bb68e7ecf4bfd45940f9e7f51d070 # via # pandas-gbq # pydata-google-auth -google-cloud-bigquery[pandas]==3.40.1 \ - --hash=sha256:75afcfb6e007238fe1deefb2182105249321145ff921784fe7b1de2b4ba24506 \ - --hash=sha256:9082a6b8193aba87bed6a2c79cf1152b524c99bb7e7ac33a785e333c09eac868 +google-cloud-bigquery[pandas]==3.41.0 \ + --hash=sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe \ + --hash=sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa # via # feast (pyproject.toml) # pandas-gbq -google-cloud-bigquery-storage==2.36.2 \ - --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ - --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 +google-cloud-bigquery-storage==2.39.0 \ + --hash=sha256:8c192b6263804f7bdd6f57a17e763ba7f03fa4e53d7ecafca0187e0fd6467d48 \ + --hash=sha256:d5afd90ad06cf24d9167316cca70ab5b344e880fc13031d7392aa78ee76b8bb6 # via feast (pyproject.toml) -google-cloud-bigtable==2.35.0 \ - --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ - --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b +google-cloud-bigtable==2.38.0 \ + --hash=sha256:0ad24f0106c2eb0f38e278b1641052e65882a4da0141d1f9ad78ea691724aaa3 \ + --hash=sha256:9f6a4bdbefb34d0420f41c574d9805d8a63d080d10be5a176205e3b322c122a1 # via feast (pyproject.toml) -google-cloud-core==2.5.0 \ - --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ - --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 +google-cloud-core==2.6.0 \ + --hash=sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e \ + --hash=sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83 # via # google-cloud-bigquery # google-cloud-bigtable # google-cloud-datastore # google-cloud-storage -google-cloud-datastore==2.23.0 \ - --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ - --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 +google-cloud-datastore==2.25.0 \ + --hash=sha256:dd646a3d8f99c2750bb5f6e0f18ece7bed95fd76e02dacaddbfa35a2b22328ff \ + --hash=sha256:e47e25933bcfad7118335015b0de2f2b2b5444e81f6f029a62040f568f4f52eb # via feast (pyproject.toml) google-cloud-storage==2.19.0 \ --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ @@ -870,139 +925,163 @@ google-crc32c==1.8.0 \ # google-cloud-bigtable # google-cloud-storage # google-resumable-media -google-resumable-media==2.8.0 \ - --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ - --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae +google-resumable-media==2.10.0 \ + --hash=sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c \ + --hash=sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee # via # google-cloud-bigquery # google-cloud-storage -googleapis-common-protos[grpc]==1.73.0 \ - --hash=sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a \ - --hash=sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8 +googleapis-common-protos[grpc]==1.75.0 \ + --hash=sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd \ + --hash=sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed # via # feast (pyproject.toml) # google-api-core # grpc-google-iam-v1 # grpcio-status -greenlet==3.3.2 \ - --hash=sha256:02b0a8682aecd4d3c6c18edf52bc8e51eacdd75c8eac52a790a210b06aa295fd \ - --hash=sha256:18cb1b7337bca281915b3c5d5ae19f4e76d35e1df80f4ad3c1a7be91fadf1082 \ - --hash=sha256:1a9172f5bf6bd88e6ba5a84e0a68afeac9dc7b6b412b245dd64f52d83c81e55b \ - --hash=sha256:1e692b2dae4cc7077cbb11b47d258533b48c8fde69a33d0d8a82e2fe8d8531d5 \ - --hash=sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f \ - --hash=sha256:1fb39a11ee2e4d94be9a76671482be9398560955c9e568550de0224e41104727 \ - --hash=sha256:20154044d9085151bc309e7689d6f7ba10027f8f5a8c0676ad398b951913d89e \ - --hash=sha256:2eaf067fc6d886931c7962e8c6bede15d2f01965560f3359b27c80bde2d151f2 \ - --hash=sha256:34308836d8370bddadb41f5a7ce96879b72e2fdfb4e87729330c6ab52376409f \ - --hash=sha256:394ead29063ee3515b4e775216cb756b2e3b4a7e55ae8fd884f17fa579e6b327 \ - --hash=sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd \ - --hash=sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2 \ - --hash=sha256:43e99d1749147ac21dde49b99c9abffcbc1e2d55c67501465ef0930d6e78e070 \ - --hash=sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99 \ - --hash=sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be \ - --hash=sha256:4c956a19350e2c37f2c48b336a3afb4bff120b36076d9d7fb68cb44e05d95b79 \ - --hash=sha256:508c7f01f1791fbc8e011bd508f6794cb95397fdb198a46cb6635eb5b78d85a7 \ - --hash=sha256:527fec58dc9f90efd594b9b700662ed3fb2493c2122067ac9c740d98080a620e \ - --hash=sha256:59b3e2c40f6706b05a9cd299c836c6aa2378cabe25d021acd80f13abf81181cf \ - --hash=sha256:5d0e35379f93a6d0222de929a25ab47b5eb35b5ef4721c2b9cbcc4036129ff1f \ - --hash=sha256:63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506 \ - --hash=sha256:64970c33a50551c7c50491671265d8954046cb6e8e2999aacdd60e439b70418a \ - --hash=sha256:6c6f8ba97d17a1e7d664151284cb3315fc5f8353e75221ed4324f84eb162b395 \ - --hash=sha256:8b466dff7a4ffda6ca975979bab80bdadde979e29fc947ac3be4451428d8b0e4 \ - --hash=sha256:8c1fdd7d1b309ff0da81d60a9688a8bd044ac4e18b250320a96fc68d31c209ca \ - --hash=sha256:8c4dd0f3997cf2512f7601563cc90dfb8957c0cff1e3a1b23991d4ea1776c492 \ - --hash=sha256:8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab \ - --hash=sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358 \ - --hash=sha256:8e4ab3cfb02993c8cc248ea73d7dae6cec0253e9afa311c9b37e603ca9fad2ce \ - --hash=sha256:94ad81f0fd3c0c0681a018a976e5c2bd2ca2d9d94895f23e7bb1af4e8af4e2d5 \ - --hash=sha256:97245cc10e5515dbc8c3104b2928f7f02b6813002770cfaffaf9a6e0fc2b94ef \ - --hash=sha256:9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d \ - --hash=sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac \ - --hash=sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55 \ - --hash=sha256:a7945dd0eab63ded0a48e4dcade82939783c172290a7903ebde9e184333ca124 \ - --hash=sha256:aa6ac98bdfd716a749b84d4034486863fd81c3abde9aa3cf8eff9127981a4ae4 \ - --hash=sha256:ab0c7e7901a00bc0a7284907273dc165b32e0d109a6713babd04471327ff7986 \ - --hash=sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd \ - --hash=sha256:ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f \ - --hash=sha256:ae9e21c84035c490506c17002f5c8ab25f980205c3e61ddb3a2a2a2e6c411fcb \ - --hash=sha256:b26b0f4428b871a751968285a1ac9648944cea09807177ac639b030bddebcea4 \ - --hash=sha256:b568183cf65b94919be4438dc28416b234b678c608cafac8874dfeeb2a9bbe13 \ - --hash=sha256:b6997d360a4e6a4e936c0f9625b1c20416b8a0ea18a8e19cabbefc712e7397ab \ - --hash=sha256:b8bddc5b73c9720bea487b3bffdb1840fe4e3656fba3bd40aa1489e9f37877ff \ - --hash=sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a \ - --hash=sha256:c2e47408e8ce1c6f1ceea0dffcdf6ebb85cc09e55c7af407c99f1112016e45e9 \ - --hash=sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86 \ - --hash=sha256:ccd21bb86944ca9be6d967cf7691e658e43417782bce90b5d2faeda0ff78a7dd \ - --hash=sha256:cd6f9e2bbd46321ba3bbb4c8a15794d32960e3b0ae2cc4d49a1a53d314805d71 \ - --hash=sha256:d248d8c23c67d2291ffd47af766e2a3aa9fa1c6703155c099feb11f526c63a92 \ - --hash=sha256:d3a62fa76a32b462a97198e4c9e99afb9ab375115e74e9a83ce180e7a496f643 \ - --hash=sha256:e26e72bec7ab387ac80caa7496e0f908ff954f31065b0ffc1f8ecb1338b11b54 \ - --hash=sha256:e3cb43ce200f59483eb82949bf1835a99cf43d7571e900d7c8d5c62cdf25d2f9 +greenlet==3.5.1 \ + --hash=sha256:001775efe7b8e758861294c7a27c28af87f3f3f1c20468a2bc618c45b346c061 \ + --hash=sha256:00929c98ec525fd9bf075875d8c5f6a983a90906cdf78a66e6de2d8e466c2a19 \ + --hash=sha256:017a544f0385d441e88714160d089d6900ef46c9eff9d99b6715a5ef2d127747 \ + --hash=sha256:089fff7a6ce8d9316d1f65ebc00273a56be258c1725b32b94de90a3a979557e1 \ + --hash=sha256:1072b4f9edcc1e192d9283a66a3e68d6b84c561de33a83d7858beb9ba1effe10 \ + --hash=sha256:10a9a1c0bfbc93d41156ffcb90c75fbc05544054faf15dcc1fdf9765f8b607f0 \ + --hash=sha256:110a1ca7b49b014b097f6078272c3f4ed31af45b254de5228b79adba879f6af9 \ + --hash=sha256:111e2390ffffc47d5840b01711dd7fac07d4c09283d0283e7f3264b14e284c64 \ + --hash=sha256:17d86354f0ae6b61bf9be5148d0dd34e06c3cb7c602c671f79f29ac3b150e659 \ + --hash=sha256:1ffdb3c0bb002c99cd8f298957e046c3dbf6006b5b7cdf11a4e19194624a0a0a \ + --hash=sha256:2baee5ca02031757ffe8cc3d69f0cc0aec7065ce362622da74f32d3bcab1c541 \ + --hash=sha256:2c18ef16bf6d4dd410e4dd52996888ea1497be26892fe5bbc73580aba4287b8e \ + --hash=sha256:2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c \ + --hash=sha256:3bfbd69cc349e43bf3a8ae1c85548ff0718efc887615c2db16c3833d7b0b072d \ + --hash=sha256:3c8bb982ad117d29478ef8f5533e97df21f1e2befd17a299257b0c96d1371c0b \ + --hash=sha256:3d955c89b75eeca4723d7cc14135f393cd47c32e2a6cb4a8e4c6e760a26b0986 \ + --hash=sha256:4378720dd888136c27215a0214d32a4d37c3852765d45bc37aad0623423cfd78 \ + --hash=sha256:45718441607f9325d948db98cbc691276059316d0358c188c246da4e1d4d23d2 \ + --hash=sha256:5028648bf2253ec4745add746129d3904121fa7fe871a76bed23c5720573ce0a \ + --hash=sha256:50ae25a67bea74ea41fb14b960bc532df73eb713417b2d61892dced82fe8d3bc \ + --hash=sha256:51518ff74664078fc51bffcc6fc529b0df5ae58da192691cee765d45ce944a2b \ + --hash=sha256:540dae7b956209af4d70a3be35927b4055f617763771e5e84a5255bea934d2f5 \ + --hash=sha256:5a56aeb7d5d9cc4b3a735efb5095bd4b4f6f0e4f93e5ca876d0e2315137b7829 \ + --hash=sha256:5e300185139abc337ade480c327183adf42a875ac7181bfe66d7d4efea31fbea \ + --hash=sha256:67821bb03e4e98664490edb787ff6af501194c29bbee0f5c1dfdcf1dc3d9d436 \ + --hash=sha256:6c09df69dc1712d131332054a858a3e5cca400967fa3a672e2324fbb0971448c \ + --hash=sha256:6ebeb75c81211f5c702576cf81f315e77e23cfdb2c7c6fcb9dd143e6de35c360 \ + --hash=sha256:73f78f9b9f0a5c06e5c946ba1e8e36f5114923b6be109ee618c54f079c3ea14f \ + --hash=sha256:7546556f0d649f99f6a361098a55f761181bb2ea12ff150bb16d26092ad88244 \ + --hash=sha256:7715a5a2c3378ba602c3a440558261e13a820bb53a82693aacd7b7f6d964e283 \ + --hash=sha256:7b5f5fae05b8ac6d176a61b60c394a8cbdc2b5b91b81793066e68745cf165e54 \ + --hash=sha256:7eacb17a9d41538a2bc4912eba5ef13823c83cb69e4d141d0813debe7163187f \ + --hash=sha256:7ffdb990dcaa0234cf9845aead5df2e3c3a8b6507d409274dd87e0d5ab05ffc2 \ + --hash=sha256:80eb4b04dadc4e67df3fae179a32c4706a3f495bc7f22fc8a81115d5f5512188 \ + --hash=sha256:88e300d136eac057b2397aa1cfd7328b4c87c7eb66a09c7bc6a1292234db474e \ + --hash=sha256:89101bfd5011e069be974903cb3a4e4523845e4ece2d62dcd8d358933c0ef249 \ + --hash=sha256:8a17c42330e261299766b75ac1ea32caa437a9453c8f65d16a13140db378ecd3 \ + --hash=sha256:8a271fcd66c74615cda6a964fda3f304267a12e50a084472218a39bb0376f563 \ + --hash=sha256:8d8a23250ea3ec7b36de8fa4b541e9e2db3ee82915cc060ab0631609ad8b28de \ + --hash=sha256:92fd6d44ac5e5a887c8a5dc4a8ba0ba908527c31c12f78c6bc7dcfe8aab279f6 \ + --hash=sha256:975eac34b44a7077ca4d421348455b94f0f518246a7f14bc6d2fdcfe5b584368 \ + --hash=sha256:9ab3c3a0b2ae6198e67c898dad5215a49f9ae0d0081b3c3ec59f333e39eeca26 \ + --hash=sha256:9b1ec3274918a81d3ea778b9e75b56b72b33f300edb6cf7f3a7fe1dae56683de \ + --hash=sha256:9d59e840387076a51016777a9328b3f2c427c6f9208a6e958bad251be50a648d \ + --hash=sha256:a0cbed8bb44e23c5b199f888f4e4ce096b45ad9f25ff74a7ad0213875e936bb2 \ + --hash=sha256:a19570c52a21420dcbc94e661994bc325c0b5b11304540fed514586da5dc8f2e \ + --hash=sha256:a203a8bd0acb0701653d3bbb26e404854a68674139ed5cbb778830f42b09bb33 \ + --hash=sha256:a4764e0bfc6a4d114c865b32520805c16a990ef5f286a514413b05d5ecd6a23d \ + --hash=sha256:a57b0d05a0448eed231d59c0ceb287dde984551e54cbc51ac2d4865712838e9c \ + --hash=sha256:a5c81f74d204d3edd136ebfd50dce53acbb776995d721a0fe801626cfc93b8cd \ + --hash=sha256:a5ea42a752d47a145eae922b605cd1634665ac3d5ec1e72402d5048e8d60d207 \ + --hash=sha256:a6fdf2433a5441ef9a95464f7c3e674775da1c8c1177fff311cee1acad4626ed \ + --hash=sha256:add5217d68b31130f0beca584d7fef4878327d2e31642b66618a14eef312b63b \ + --hash=sha256:b0703c2cef53e01baec47f7a3868009913ad71ec678bbecb42a6f40895e4ce62 \ + --hash=sha256:b9152fca4a6466e114aaec745ae61cba739903a109754a9d4e1262f01e9259b1 \ + --hash=sha256:c0141e37414c10164e702b8fb1473304221ad98f71600850c6ef7ff4880feba0 \ + --hash=sha256:c3d35f87c7253b715d13d679e0783d845910144f282cb939fe1ba4ac8616269c \ + --hash=sha256:c5551170cf4f5ff5623e9af81323751979fee2c731e2287b61f73cd27257b823 \ + --hash=sha256:cbfc69be86e10dcfef5b1e6269d1d6926552aa89ee39e1de3353360c1b6989ab \ + --hash=sha256:cc6ab7e555c8a112ad3a76e368e86e12a2754bcae1652a5602e133ec7b635523 \ + --hash=sha256:cd443683db272ebaaca03af98c0b063ab30db70ea8a31a1559f35e3f7b744ccd \ + --hash=sha256:d0932b81d72f552ded9d810d00021b64d89f2195a91ce115b893f943b7a4ab3c \ + --hash=sha256:d40a890035c0058cadbdc4af7569800fd28a0e527a0fdbb7b5f9418f176846ce \ + --hash=sha256:d5ee3ea898009fa898f85f9982255d35278c477bebe185beca249cab42d4526c \ + --hash=sha256:d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07 \ + --hash=sha256:dc71ff466927a201b08305acac451ebe1aedfcea002f62f1f2f2ac2ac1e6a135 \ + --hash=sha256:de2daaaebd1a5aa88c49045b6baf9310b3263796bd88db713edf37cf53e7bb4e \ + --hash=sha256:ded7b068c7c31c1a8657d4fd42d886b3e051ae29f88b80c5ff9d502257b0f071 \ + --hash=sha256:e5cc9606aa5f4e0bde0d3bd502b44f743864c3ffa5cfa1011b1e30f5aa02366f \ + --hash=sha256:e630136e905fe5ff43e86945ae41220b6d1470956a39220e708110ac48d01ea5 \ + --hash=sha256:e6cd99ea59dd5d89f0c956606571d79bfe6f68c9eb7f4a4083a41a7f1587edee \ + --hash=sha256:e7516cf6ae6b8a582c2770a0caed47b8a48373ed732c33d69a72913ae6ac923e \ + --hash=sha256:ea37d5a157eb9493820d3792ac4ece28619a394391d2b9f2f78057d396ff0f0f \ + --hash=sha256:ea8da1e900d758d078810d4255d8c6aa572181896a31ec79d779eb79c3adc9ad \ + --hash=sha256:ed8cdb691169715a9a492844a83246f090182247d1a5031dc78a403f68ba1e97 \ + --hash=sha256:ef08c1567c78074b22d1a200183d52d04a14df447bf70bcbb6a3507a48e776fc \ + --hash=sha256:f16ba1efc0715b680a18b8123d90dad887c6112ae3555b4b5c32c149540c6b4e \ + --hash=sha256:fa4f98af3a528f0c3fd592a26df7f376f93329c8f4d987f6bb979057af8bf5e2 \ + --hash=sha256:ffea73584b216150eab159b6d12348fb253e68757974de1e2c40d8a318ac89ed # via feast (pyproject.toml) -grpc-google-iam-v1==0.14.3 \ - --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ - --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 +grpc-google-iam-v1==0.14.4 \ + --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ + --hash=sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964 # via google-cloud-bigtable -grpcio==1.62.3 \ - --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ - --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ - --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ - --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ - --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ - --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ - --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ - --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ - --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ - --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ - --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ - --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ - --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ - --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ - --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ - --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ - --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ - --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ - --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ - --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ - --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ - --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ - --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ - --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ - --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ - --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ - --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ - --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ - --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ - --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ - --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ - --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ - --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ - --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ - --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ - --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ - --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ - --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ - --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ - --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ - --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ - --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ - --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ - --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ - --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ - --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ - --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ - --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ - --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ - --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ - --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ - --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ - --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ - --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a +grpcio==1.81.0 \ + --hash=sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65 \ + --hash=sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0 \ + --hash=sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22 \ + --hash=sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a \ + --hash=sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f \ + --hash=sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2 \ + --hash=sha256:3755c9669307cad18e7e009860fdea98118978d2300451bd8530a53048e741e7 \ + --hash=sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757 \ + --hash=sha256:40edffb4ec3689373825d367c4457727047a6e554f03245265ecc8cc03215f22 \ + --hash=sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719 \ + --hash=sha256:4e032feb3bfb4e2749b140a2302a6baa8ead1b9781ff5cf7094e4402b5e9372e \ + --hash=sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696 \ + --hash=sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c \ + --hash=sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c \ + --hash=sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855 \ + --hash=sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33 \ + --hash=sha256:725801c7086d7e4cd160e42bb2f54e0aeb976b9568df3cc6f843b15d29b79fb1 \ + --hash=sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b \ + --hash=sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374 \ + --hash=sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce \ + --hash=sha256:8226ba097eed660ef14d36c6a69b85038552bb8b6d17b44a5aa6f9abf48b8e08 \ + --hash=sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141 \ + --hash=sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce \ + --hash=sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279 \ + --hash=sha256:909bb3222b53235498d2c5817a0596d82b0aaea490ba93fdf1b060e2938a543c \ + --hash=sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5 \ + --hash=sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa \ + --hash=sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8 \ + --hash=sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170 \ + --hash=sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5 \ + --hash=sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390 \ + --hash=sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe \ + --hash=sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47 \ + --hash=sha256:b4108e5d9d0f651b7eea749116181fe6c315b145661a80ec31f05ec2dbe21af7 \ + --hash=sha256:b76ea9d55cd08fcdbda25d28e0f76679536710acb7fbd5b1f70cb4ac49317265 \ + --hash=sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5 \ + --hash=sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b \ + --hash=sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005 \ + --hash=sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc \ + --hash=sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf \ + --hash=sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb \ + --hash=sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9 \ + --hash=sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8 \ + --hash=sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d \ + --hash=sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d \ + --hash=sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc \ + --hash=sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901 \ + --hash=sha256:f750a091fff3a3991731abc1f818bdc64874bb3528162732cb4d45f2e07821a6 \ + --hash=sha256:f85570a016d794c29b1e76cf22f67af4486ddbe779e0f30674f138fa4e1769ec \ + --hash=sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664 \ + --hash=sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b # via # feast (pyproject.toml) # google-api-core # google-cloud-bigquery # google-cloud-bigquery-storage + # google-cloud-bigtable # google-cloud-datastore # googleapis-common-protos # grpc-google-iam-v1 @@ -1010,21 +1089,21 @@ grpcio==1.62.3 \ # grpcio-reflection # grpcio-status # pymilvus -grpcio-health-checking==1.62.3 \ - --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ - --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d +grpcio-health-checking==1.81.0 \ + --hash=sha256:09f31674f1acdcf214bc4e640ebbbbef165b077a1fd64834795196d52bfdce39 \ + --hash=sha256:1024304a85eecddb7a08cb16e157a36dd1c5b08bdabba09f844a71d7e47c994f # via feast (pyproject.toml) -grpcio-reflection==1.62.3 \ - --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ - --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f +grpcio-reflection==1.81.0 \ + --hash=sha256:5191db7aa6cab1b6981b0879fa44fdcdd43ba644f0301c40b976f813eb4eff06 \ + --hash=sha256:85322a9c1ab62d9823b1262a9d78d653b1710b99b5764cdcef2673cfe352b9c1 # via feast (pyproject.toml) -grpcio-status==1.62.3 \ - --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ - --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 +grpcio-status==1.81.0 \ + --hash=sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab \ + --hash=sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69 # via google-api-core -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -1042,157 +1121,182 @@ hatch-vcs==0.4.0 \ --hash=sha256:093810748fe01db0d451fabcf2c1ac2688caefd232d4ede967090b1c1b07d9f7 \ --hash=sha256:b8a2b6bee54cf6f9fc93762db73890017ae59c9081d1038a41f16235ceaf8b2c # via feast (pyproject.toml) -hatchling==1.29.0 \ - --hash=sha256:50af9343281f34785fab12da82e445ed987a6efb34fd8c2fc0f6e6630dbcc1b0 \ - --hash=sha256:793c31816d952cee405b83488ce001c719f325d9cda69f1fc4cd750527640ea6 +hatchling==1.30.1 \ + --hash=sha256:161eacafb3c6f91526e92116d21426369f2c36e98c36a864f11a96345ad4ee31 \ + --hash=sha256:eee4fd45357f72ebb3d7a42e5d72cfb5e29ed426d79e8836288926c4258d5f2e # via # feast (pyproject.toml) # hatch-fancy-pypi-readme # hatch-vcs -hiredis==2.4.0 \ - --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ - --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ - --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ - --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ - --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ - --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ - --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ - --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ - --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ - --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ - --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ - --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ - --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ - --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ - --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ - --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ - --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ - --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ - --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ - --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ - --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ - --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ - --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ - --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ - --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ - --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ - --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ - --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ - --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ - --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ - --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ - --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ - --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ - --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ - --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ - --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ - --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ - --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ - --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ - --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ - --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ - --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ - --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ - --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ - --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ - --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ - --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ - --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ - --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ - --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ - --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ - --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ - --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ - --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ - --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ - --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ - --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ - --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ - --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ - --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ - --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ - --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ - --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ - --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ - --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ - --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ - --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ - --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ - --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ - --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ - --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ - --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ - --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ - --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ - --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ - --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ - --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ - --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ - --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ - --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ - --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ - --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ - --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ - --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ - --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ - --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ - --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ - --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ - --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ - --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ - --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ - --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ - --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ - --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def +hiredis==3.4.0 \ + --hash=sha256:02298551060cbfe17b1acb02e9d066eadd51e37357369736f8fc1f5533875255 \ + --hash=sha256:03374d663b0e025e4039757ef5fad02e3ff714f7a01e5b34c88de2a9c91359dc \ + --hash=sha256:04e54fc3bcecf8c7cb2846947b84baf7ce1507caba641bd23590c52fefade865 \ + --hash=sha256:05384fcfe5851b5af868bf24265c14ab86f38562679f9c6f712895b67a98163c \ + --hash=sha256:05c852c58fec65d4c9fb861372dd7391d8b2ce96c960ba8714145f8cd85cd0ec \ + --hash=sha256:06c163607f163a300cba9ef02fd8a234dd644a208bfafe972614f72e5287b9ba \ + --hash=sha256:0731dd9f2bf4d3417947a3cbbca4dd4d9fa6ad7cecfd4e16439c17a4562d6304 \ + --hash=sha256:0a68b0e48509e6e66f4c212e53d98f29178addf83b0701a71bf0fce792954419 \ + --hash=sha256:0a70df45cf167b5af99b9fe3e2044716919e30580a869dfa766f2a6467c0c320 \ + --hash=sha256:0b82cab9ad7a1574ab273a78942f780c1b1496101eb342b630c46c3e918ca21b \ + --hash=sha256:0bcb630add6bc9ea136fce691ddff0c46aa91cb860df4ca789fe44127eb7e90d \ + --hash=sha256:12ea5facb5b08fa23e4c101ec2151f3a3de8ecec412fec58dbde0a6eebca02c7 \ + --hash=sha256:12eca9aea1450d1a85dc15574a985c227e52abbc2b6466f48ad2aa3b82124701 \ + --hash=sha256:14524fdc751e3960d78d848872576b5442b40baae3cac14fbab1ba7ac523891f \ + --hash=sha256:163d8c43e2706d23490532ea0de8736fc1493cfa52f0ee65f85b0f074f2fe017 \ + --hash=sha256:165e6405b48f9bd66ddb4ad52ce28b0c0041a0308654d7a0cb4357a1939134dc \ + --hash=sha256:16a3ea8193c5f4ee6e8daafe0126207cef38eec5a923c97047e6985d9bb1b61f \ + --hash=sha256:18ff3d9b23ebe6c8248c3debca2402ad209d60c48495e7ed76407c2fe54cb9b4 \ + --hash=sha256:1bfb9ccfb13be63883e5f2e5ff7f6fc87bf256f8243af594257dfbed9dbc3cf0 \ + --hash=sha256:1c9e141b420dae63ea21303a7e8672282326cae67472768e9a3f6e7f0990bd28 \ + --hash=sha256:1d8c21fb85f2a3de9328cf5bace84b63da00028e771b92335ff4fdc00121dd5a \ + --hash=sha256:1fb0a139cd52535f3e5a532816b5c36b3aea95817410fbf28ca4a676026347a5 \ + --hash=sha256:24751054bb11353016d242d09a4a902ecf8f25e3b56fe396cccb6f056fdda016 \ + --hash=sha256:258f820cdd6ee6be39ae6a8ea94a76b8856d34113de6604f63bc81327ef06240 \ + --hash=sha256:282c4310af72afbe18b07d416459f4febeaeb805a067a7df790136e0e550fcb2 \ + --hash=sha256:2c432cce38190c3c13b6c28d6840ee85db50765ad510134007f1cfb3844dce73 \ + --hash=sha256:306aae11a52e495aaf0a14e3efcd7b51029e632c74b847bc03159e1e1f6db591 \ + --hash=sha256:3159c54fe560aa30bf1ab76e65c4c23dc45ad79d7cf4aecc25ec9942f5ea4cea \ + --hash=sha256:3348ba4e101f3a96c927447ff2edcb3e0026dc6df375ba117485a43edcbb6980 \ + --hash=sha256:35ab3653569b9867b8d8a3b4c0684a20dc769fe45d4666bedfe9a3391a61b30b \ + --hash=sha256:3774461209688790734b5db8934400a4456493fc1a172fb5298cc5d72201aceb \ + --hash=sha256:386b556f48fb0f9f09696b9d37f1cae554123fbd9f091d0ca23087f2aca02887 \ + --hash=sha256:393d5e7c8c67cdddf7109a8e925d885e788f3f43e5b1043f84390df40c59944b \ + --hash=sha256:4190bd07dd7879a8a7ddbb2a4f74d402721f3898276e35beb98851b85b5f539c \ + --hash=sha256:423570ac4d2665c0d55d8707b7859a331e9001da5e437b7b7a23e0acbce770c9 \ + --hash=sha256:43004b0b48abc628dda1ac3ac4871e1326c126f8cd9f11164d61934d827d7a3b \ + --hash=sha256:4404c557fd49bcfe24dff41f1209e4221c76d1607df2fb2dfd39474b5b086dcb \ + --hash=sha256:44660a91e0fbc803c29b337c1a9194c8d7b4cd3a3868d28f747cbec2df165483 \ + --hash=sha256:452cff764acb30c106d1e33f1bdf03fa9d4a9b0a9c995d722d4d39c998b40582 \ + --hash=sha256:454236d2a5bd917daf38914ce363e71aeef41240e6800f4799e04ee82689bfd2 \ + --hash=sha256:45c6c296056641b5df37cedafe7d1553f33bc247e2f81603a4d038b39261879b \ + --hash=sha256:46e041fc7a83eaa989ef5fe09526bc2353a6ba39b4ce5191684eabefc02e17b0 \ + --hash=sha256:4863b99b1bf739eaa60961798efc709f657864fbf5a142cb9b99d3e36a37208e \ + --hash=sha256:4b8f52844cd260d7805eca55c834e3e06b4c0d5b53a4178143b92242c2517c0d \ + --hash=sha256:4de6869be2b33490569dae0712366bb794b7f5e7a8b674de3e092b3e95712d6d \ + --hash=sha256:4e5530d7a6c71c1a9c3b850b08bbc8178ffc9556e3aef7f9c808fe9ff91a6f11 \ + --hash=sha256:4f0e3536eea76c03435d411099d165850bc3c9d873efe62843b995027135a763 \ + --hash=sha256:53233656e4fecf9f8ec654f1f4c5d445bf1c2957d7f63ffdedbba2682c9d1584 \ + --hash=sha256:5359caad5b57da0bce11d2880f22617ba3710f0866121a924745447848448034 \ + --hash=sha256:54b6267918c66d8ba4a3cf519db1235a4bd56d2a0969ca5b2ae3c6b6b7d9ed79 \ + --hash=sha256:5f1ddfe6429f9adc0a8d705afbcd40530fddeafa919873ffbb11f59eda44dbb9 \ + --hash=sha256:64cf54c1dad35830bf1d86b343ad3c55aed443af51c5ccead8afd1b547aca196 \ + --hash=sha256:6774f1fe2723001ca0cd42bf5d8b1235301226273915c581c5c1260d4d114c43 \ + --hash=sha256:68c81c04e0d8778c01163dd2bc6f0e0236fc7f650c291526f10d4faccd99e5a0 \ + --hash=sha256:696e0a2118e1df5ccacf8ecf8abe528cf0c4f1f1d867f64c34579bef77778cdb \ + --hash=sha256:69d0326f20354ce278cbb86f5ae47cb390e22bb94a66877031038af907c42fa5 \ + --hash=sha256:6c2852eaa26c0a73be4a30118cd5ad6a77c095d224ccb5ac38e40cb865747d22 \ + --hash=sha256:73dd607b47863633d8070f1eb3bab1b3b097ee747783fe69c0dd0f93ec673d8b \ + --hash=sha256:74bcfb26189939daba2a0eb4bad05a6a30773bb2461f3d9967b8ced224bd0de9 \ + --hash=sha256:7b159315df71a009375227384aa4219f98c2342ccd8eb33e3f4b58654f426376 \ + --hash=sha256:7e7ab4c1c8c4d365b02d9e82cdf25b01a065edf2ededd7b5acb043201ff80203 \ + --hash=sha256:7f7fc1535f6e1a190089eae46dee25f0c6b72bb221d377be07092803b8208733 \ + --hash=sha256:7ff29c9f5d3c91fda948c2fde58f457b3244550781d3bc0891b1b9d93c10f47f \ + --hash=sha256:82860f050aabd08c046f304eb57c105bb3d5a7370f79a4a0b74d2b771767cc13 \ + --hash=sha256:85a9abf2d16b4cb112f6cc6c32236d763b34d21c69b00c2f81a4ff3016fcc1d6 \ + --hash=sha256:88396e6a24b80c86f4dc180964d9cc467ba3aa3c886af6532fe077c5a5dc0c3c \ + --hash=sha256:899d5cea72c9a6c2d9b6e7b223de62c9e9f541f48267cc7135764070548735ce \ + --hash=sha256:89e95f50ec4d29645ba2da9010e8717861585dc9f3df354a367f43807a6db3c7 \ + --hash=sha256:8aaaab18314fd25453b5cf59c8cdca4110e419455bcb4c0737d19d4151513e75 \ + --hash=sha256:8b3f1d03046765c0a83558bf1756811101e3947649c7ca22a71d9dc3c92929d1 \ + --hash=sha256:8f2c8569460aa456a294d5e9a3579a382b825dc2e283e3cc398323dcfb6a3dee \ + --hash=sha256:92b570225f6097430615a82543c3eb7974ca354738a6cef38053138f7d983151 \ + --hash=sha256:94f83352295bf3d332678689ecd4ce190a4d233a20ad2f432724efd3ce03e49a \ + --hash=sha256:975a8e75a10425442037dd9c7abbaae31941c34328d9f01b1ca42d9db44ac31d \ + --hash=sha256:98e28c10e43d076f50ce9fa9f4017303d5796c3058b1b651f507c2a7d6ef402c \ + --hash=sha256:9e88048a66dfffec7a3f578f2a2a0fd907c75b5bd85b3c9184f76f0149ea399f \ + --hash=sha256:a2f9a9a591b3eaade523f3e778dfcd8684965ee6e954ae25cd2fd6d8c75e881d \ + --hash=sha256:a315009b441a0105a373a9a780ebb1c6f7d9ead88ac6ea5f2a15791353c6f590 \ + --hash=sha256:a3796094f616f72976ff51e4dc1a016e753c0f9af5393b2df96920b6bae1e19b \ + --hash=sha256:a427976ba339da624367613d7eba52a1516e6d5c7f8988dc8fb888fbcf52d8b6 \ + --hash=sha256:a45822bc8487da8151fe67c788de74b834582b1d510c67b888fcda64bf6ba4bb \ + --hash=sha256:a7e76904148c229549db7240a4f9963deb8bb328c0c0844fc9f2320aca05b530 \ + --hash=sha256:afff0876dafad6d3bb446c907da2836954876243f6bb9d5e44915d175e424aa4 \ + --hash=sha256:b0c29ac4f50fc61a904acfe76e4ce6bc37e16ab5a98089cb411476d466e1bb36 \ + --hash=sha256:b32afb576705fc5a02440d416ef476ddbcc827a20ff6c4a9d557882bc6b75135 \ + --hash=sha256:b6228afacadb19a858289319d72797023e2cb048f2f930b68b7fe57eaed5fb6b \ + --hash=sha256:b98f44bf873731d9ce99e6b3eeb6196bf7b27693ad9f6de0fba986b2b0845127 \ + --hash=sha256:bb44efa4fa3e3ed7779ad0ade3c08ed5d75ca7a6336893e9a4f2722093b4168a \ + --hash=sha256:bb8b2dd9c00d80ad2870ffbb51ce9af99fb2194c082d7b09f4125d90e21426f6 \ + --hash=sha256:bca175f02a2b0150ffe7f5dc8bf49c798f34d2c7024d17ace0ec97a7583560e3 \ + --hash=sha256:be4a41496a0a48c3abf57ef1bbeb11980060ce9c7a1dd8b92caa028a813a9c59 \ + --hash=sha256:c2245c46b4ced5f689469e6dcdfc8a0895bf873840a6600f5ea759cdf1b26a8b \ + --hash=sha256:c8c6337e7ad187e8039d06e4b33ee5148dcd73928819d94087e649eb37316a09 \ + --hash=sha256:ccc5c660e31d788ca534a20f2ccb7a80b946b960e18ed4e1db950fcac122b405 \ + --hash=sha256:ccdb63363c82ea9cea2d48126bc8e9241437b8b3b36413e967647a17add59643 \ + --hash=sha256:cfe23f8dcf2c0f4e03d107ff68a9ee9707f9d76abeddbe59633e5de1564a650c \ + --hash=sha256:d3a12ae5685e9621a988af07b5af0ad685c7d19d6a7246ac852e35060178cff4 \ + --hash=sha256:d5c33eb2da5c9ccd281c396e1c618cfe6a91eb841e957f17d2fa520383b3111d \ + --hash=sha256:d77901d058923a09ed25063ea6fb2842c153bbe75060a46e3949e73ad12ce352 \ + --hash=sha256:d95b602ab022f3505288ce51feaa48c072a62e57da55d6a7a38ecb8c5ad67d81 \ + --hash=sha256:da19331354433af6a2c54c21f2d70ba084933c0d7d2c43578ec5c5b446674ad5 \ + --hash=sha256:db13f8039ad8229f77f0e242be14e53bd67e8f3aadeb16f3af30944287cca092 \ + --hash=sha256:de3e2297a182253dfa4400883a9a4fb46d44946aed3157ea2da873b93e2525c4 \ + --hash=sha256:decc176d86127c620b5d280b3fe5f97a788be58ca945971f3852c3bf54f4d5ad \ + --hash=sha256:e29267ecdd08758926f1a9221af2671d90f475480c40aff409921b1f362f1bd5 \ + --hash=sha256:e6e8d5fa63ec2a0738d188488e828818cbe4cb4d37c0c706836cf3888d82c53d \ + --hash=sha256:ed1dba2695f6de009c67d63b39ff978cb43b8a79362f697acedffb7743e50d21 \ + --hash=sha256:ee6b4beb79a71df67af15a8451366babc2687fcac674d5c6eacec4197e4ce8c1 \ + --hash=sha256:f3c67f39b112dc35f68d5b59ee111db6121f037d1a60cf3840ecffbb2ec5686b \ + --hash=sha256:f7c7596fbb2b5202e943180353958e89014e763c7f25877a92f70bbde6cd7f19 \ + --hash=sha256:ff28eca77a57751488df90b0f385b472fd78e140a4d45097224648a5737acdf5 \ + --hash=sha256:ff6217da86a63a6a5ea954d9b9ed67916d9d94a566b44aa98e68ae34b40ebbbf # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 # via httpx -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ @@ -1208,9 +1312,9 @@ ibis-framework[duckdb]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # httpx @@ -1244,109 +1348,109 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -kubernetes==35.0.0 \ - --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ - --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee +kubernetes==36.0.2 \ + --hash=sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3 \ + --hash=sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6 # via feast (pyproject.toml) -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 # via partd -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -1439,9 +1543,9 @@ markupsafe==3.0.3 \ --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 # via jinja2 -mcp==1.26.0 \ - --hash=sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca \ - --hash=sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66 +mcp==1.27.2 \ + --hash=sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef \ + --hash=sha256:d6ff5160c6ca65d93013626efb3fc249de683c30b2d8570755ceddd490344de5 # via fastapi-mcp mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -1717,123 +1821,129 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask @@ -1845,85 +1955,85 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +orjson==3.11.9 \ + --hash=sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4 \ + --hash=sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62 \ + --hash=sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979 \ + --hash=sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0 \ + --hash=sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d \ + --hash=sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a \ + --hash=sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd \ + --hash=sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce \ + --hash=sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1 \ + --hash=sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180 \ + --hash=sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980 \ + --hash=sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697 \ + --hash=sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e \ + --hash=sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1 \ + --hash=sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09 \ + --hash=sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd \ + --hash=sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470 \ + --hash=sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b \ + --hash=sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877 \ + --hash=sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb \ + --hash=sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd \ + --hash=sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe \ + --hash=sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97 \ + --hash=sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c \ + --hash=sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5 \ + --hash=sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021 \ + --hash=sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362 \ + --hash=sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206 \ + --hash=sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4 \ + --hash=sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218 \ + --hash=sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9 \ + --hash=sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f \ + --hash=sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4 \ + --hash=sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02 \ + --hash=sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be \ + --hash=sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972 \ + --hash=sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586 \ + --hash=sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2 \ + --hash=sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124 \ + --hash=sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa \ + --hash=sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47 \ + --hash=sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c \ + --hash=sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244 \ + --hash=sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13 \ + --hash=sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10 \ + --hash=sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677 \ + --hash=sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48 \ + --hash=sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4 \ + --hash=sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624 \ + --hash=sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49 \ + --hash=sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0 \ + --hash=sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b \ + --hash=sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c \ + --hash=sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2 \ + --hash=sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db \ + --hash=sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92 \ + --hash=sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94 \ + --hash=sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e \ + --hash=sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61 \ + --hash=sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882 \ + --hash=sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff \ + --hash=sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254 \ + --hash=sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f \ + --hash=sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32 \ + --hash=sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff \ + --hash=sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673 \ + --hash=sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291 \ + --hash=sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0 \ + --hash=sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c \ + --hash=sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9 \ + --hash=sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f \ + --hash=sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e \ + --hash=sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7 \ + --hash=sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81 + # via pymilvus +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1937,6 +2047,7 @@ packaging==26.0 \ # setuptools-scm # snowflake-connector-python # sphinx + # vcs-versioning pandas==2.3.3 \ --hash=sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7 \ --hash=sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593 \ @@ -2002,9 +2113,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.0 \ - --hash=sha256:05c8856bc11806237f16e5b042554d2216a7093f8d97b764da60e0208900e638 \ - --hash=sha256:f1b06d9bfe0135ab666ff02c57d879b78977c06effb37dd3eca54694a53d7ec3 +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -2025,16 +2136,16 @@ patchelf==0.17.2.4 \ --hash=sha256:d842b51f0401460f3b1f3a3a67d2c266a8f515a5adfbfa6e7b656cb3ac2ed8bc \ --hash=sha256:d9b35ebfada70c02679ad036407d9724ffe1255122ba4ac5e4be5868618a5689 # via feast (pyproject.toml) -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # hatchling # mypy # scikit-build-core -platformdirs==4.9.4 \ - --hash=sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934 \ - --hash=sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ @@ -2044,151 +2155,150 @@ prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -propcache==0.4.1 \ - --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ - --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ - --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ - --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ - --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ - --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ - --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ - --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ - --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ - --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ - --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ - --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ - --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ - --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ - --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ - --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ - --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ - --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ - --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ - --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ - --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ - --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ - --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ - --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ - --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ - --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ - --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ - --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ - --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ - --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ - --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ - --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ - --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ - --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ - --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ - --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ - --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ - --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ - --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ - --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ - --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ - --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ - --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ - --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ - --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ - --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ - --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ - --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ - --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ - --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ - --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ - --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ - --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ - --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ - --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ - --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ - --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ - --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ - --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ - --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ - --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ - --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ - --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ - --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ - --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ - --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ - --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ - --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ - --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ - --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ - --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ - --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ - --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ - --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ - --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ - --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ - --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ - --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ - --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ - --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ - --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ - --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ - --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ - --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ - --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ - --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ - --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ - --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ - --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ - --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ - --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ - --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ - --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ - --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ - --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ - --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ - --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ - --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ - --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ - --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ - --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ - --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ - --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ - --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ - --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ - --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ - --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ - --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ - --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ - --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ - --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ - --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ - --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ - --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ - --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ - --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ - --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ - --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ - --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ - --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ - --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ - --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 +propcache==0.5.2 \ + --hash=sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427 \ + --hash=sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5 \ + --hash=sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa \ + --hash=sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7 \ + --hash=sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a \ + --hash=sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0 \ + --hash=sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660 \ + --hash=sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94 \ + --hash=sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917 \ + --hash=sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42 \ + --hash=sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3 \ + --hash=sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa \ + --hash=sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d \ + --hash=sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33 \ + --hash=sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a \ + --hash=sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511 \ + --hash=sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0 \ + --hash=sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84 \ + --hash=sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c \ + --hash=sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66 \ + --hash=sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821 \ + --hash=sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb \ + --hash=sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e \ + --hash=sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853 \ + --hash=sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56 \ + --hash=sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55 \ + --hash=sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6 \ + --hash=sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704 \ + --hash=sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82 \ + --hash=sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f \ + --hash=sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64 \ + --hash=sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999 \ + --hash=sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b \ + --hash=sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb \ + --hash=sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d \ + --hash=sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4 \ + --hash=sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab \ + --hash=sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f \ + --hash=sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03 \ + --hash=sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5 \ + --hash=sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba \ + --hash=sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979 \ + --hash=sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b \ + --hash=sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144 \ + --hash=sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d \ + --hash=sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e \ + --hash=sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67 \ + --hash=sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117 \ + --hash=sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa \ + --hash=sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb \ + --hash=sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96 \ + --hash=sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5 \ + --hash=sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476 \ + --hash=sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191 \ + --hash=sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78 \ + --hash=sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078 \ + --hash=sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837 \ + --hash=sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a \ + --hash=sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba \ + --hash=sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe \ + --hash=sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c \ + --hash=sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf \ + --hash=sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c \ + --hash=sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9 \ + --hash=sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8 \ + --hash=sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe \ + --hash=sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031 \ + --hash=sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913 \ + --hash=sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d \ + --hash=sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf \ + --hash=sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f \ + --hash=sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539 \ + --hash=sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b \ + --hash=sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285 \ + --hash=sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959 \ + --hash=sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d \ + --hash=sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4 \ + --hash=sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f \ + --hash=sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836 \ + --hash=sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274 \ + --hash=sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d \ + --hash=sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f \ + --hash=sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e \ + --hash=sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe \ + --hash=sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1 \ + --hash=sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a \ + --hash=sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39 \ + --hash=sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7 \ + --hash=sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a \ + --hash=sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164 \ + --hash=sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e \ + --hash=sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2 \ + --hash=sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0 \ + --hash=sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0 \ + --hash=sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335 \ + --hash=sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568 \ + --hash=sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4 \ + --hash=sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80 \ + --hash=sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2 \ + --hash=sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370 \ + --hash=sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4 \ + --hash=sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b \ + --hash=sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42 \ + --hash=sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a \ + --hash=sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e \ + --hash=sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757 \ + --hash=sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825 \ + --hash=sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0 \ + --hash=sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27 \ + --hash=sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf \ + --hash=sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f \ + --hash=sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d \ + --hash=sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366 \ + --hash=sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc \ + --hash=sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c \ + --hash=sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7 \ + --hash=sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702 \ + --hash=sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098 \ + --hash=sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751 \ + --hash=sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e \ + --hash=sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6 # via # aiohttp # yarl -proto-plus==1.27.1 \ - --hash=sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147 \ - --hash=sha256:e4643061f3a4d0de092d62aa4ad09fa4756b2cbb89d4627f3985018216f9fefc +proto-plus==1.28.0 \ + --hash=sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9 \ + --hash=sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8 # via # google-api-core # google-cloud-bigquery-storage # google-cloud-bigtable # google-cloud-datastore -protobuf==6.33.5 \ - --hash=sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c \ - --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \ - --hash=sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c \ - --hash=sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd \ - --hash=sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a \ - --hash=sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190 \ - --hash=sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c \ - --hash=sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5 \ - --hash=sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0 \ - --hash=sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b +protobuf==6.33.6 \ + --hash=sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326 \ + --hash=sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901 \ + --hash=sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3 \ + --hash=sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a \ + --hash=sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135 \ + --hash=sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e \ + --hash=sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3 \ + --hash=sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2 \ + --hash=sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593 \ + --hash=sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf # via # feast (pyproject.toml) # google-api-core @@ -2227,68 +2337,68 @@ psutil==7.2.2 \ # via # feast (pyproject.toml) # pandas-gbq -psycopg[c, pool]==3.2.5 \ - --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ - --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 +psycopg[c, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via feast (pyproject.toml) -psycopg-c==3.2.5 \ - --hash=sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b +psycopg-c==3.3.4 \ + --hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask @@ -2301,12 +2411,10 @@ pyarrow-hotfix==0.7 \ --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d # via ibis-framework -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b - # via - # pyasn1-modules - # rsa +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde + # via pyasn1-modules pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 @@ -2319,141 +2427,140 @@ pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 # via cffi -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi # fastapi-mcp # mcp # pydantic-settings -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.1 \ + --hash=sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de \ + --hash=sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa # via # fastapi-mcp # mcp @@ -2461,31 +2568,31 @@ pydata-google-auth==1.9.1 \ --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 # via pandas-gbq -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # feast (pyproject.toml) # rich # sphinx -pyjwt[crypto]==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt[crypto]==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via # feast (pyproject.toml) # mcp # snowflake-connector-python -pymilvus==2.5.18 \ - --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ - --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d +pymilvus==2.6.15 \ + --hash=sha256:329a20fed7eb78607306ec80289f55151d9238bcfd3ecc61605b653c268326aa \ + --hash=sha256:c9e67810b40973d917010c176c6c07d3221a8c65b577bd924ae74fb222da8500 # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.2.0 \ + --hash=sha256:62169ce6d5510f08e140c5e7990ee884a9764024e4a9a27b2cc11f1099322ae0 \ + --hash=sha256:6c7b17ca686988104d7426c27895b455cdeea3e9d3ceb1270f0c3704fead8c33 # via feast (pyproject.toml) -pyopenssl==25.3.0 \ - --hash=sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6 \ - --hash=sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329 +pyopenssl==26.2.0 \ + --hash=sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70 \ + --hash=sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387 # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2508,13 +2615,13 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.32 \ + --hash=sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e \ + --hash=sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23 # via mcp -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via # pandas # snowflake-connector-python @@ -2597,9 +2704,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.1 \ + --hash=sha256:1a1df5067062cf7cbe677994e391f8ee0840f499d370f1a71266e0dd3aa9308e \ + --hash=sha256:1fa4647af1c5e93a2c685aa248ee44cce092691146d41390518dabe9a99839b0 # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2607,9 +2714,9 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # feast (pyproject.toml) # fastapi-mcp @@ -2617,6 +2724,7 @@ requests==2.32.5 \ # google-cloud-bigquery # google-cloud-storage # kubernetes + # pymilvus # requests-oauthlib # snowflake-connector-python # sphinx @@ -2626,9 +2734,9 @@ requests-oauthlib==2.0.0 \ # via # google-auth-oauthlib # kubernetes -rich==14.3.3 \ - --hash=sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d \ - --hash=sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via # fastapi-mcp # ibis-framework @@ -2637,132 +2745,143 @@ roman-numerals==4.1.0 \ --hash=sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2 \ --hash=sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # via sphinx -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing -rsa==4.9.1 \ - --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ - --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 - # via google-auth -s3transfer==0.13.1 \ - --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ - --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf +s3transfer==0.17.1 \ + --hash=sha256:042dd5e3b1b512355e35a23f0223e426b7042e80b97830ea2680ddce327fc45e \ + --hash=sha256:5b9827d1044159bbb01b86ef8902760ea39281927f5de31de75e1d657177bf4c # via boto3 scikit-build-core==0.12.2 \ --hash=sha256:562e0bbc9de1a354c87825ccf732080268d6582a0200f648e8c4a2dcb1e3736d \ @@ -2775,11 +2894,10 @@ setuptools==80.10.2 \ # feast (pyproject.toml) # pandas-gbq # pydata-google-auth - # pymilvus # setuptools-scm -setuptools-scm==9.2.2 \ - --hash=sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57 \ - --hash=sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7 +setuptools-scm==10.0.5 \ + --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ + --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a # via hatch-vcs shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ @@ -2791,37 +2909,37 @@ six==1.17.0 \ # via # kubernetes # python-dateutil -snowballstemmer==3.0.1 \ - --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ - --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 +snowballstemmer==3.1.1 \ + --hash=sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752 \ + --hash=sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260 # via sphinx -snowflake-connector-python[pandas]==4.3.0 \ - --hash=sha256:08f5167a10d380fe66330d5b19d19bd8b4f4af27e9648e3b254e61da025646bf \ - --hash=sha256:120463ca391d9deda3bdb185104ba847e12f73c86ef411cfcf827ce49b64d1af \ - --hash=sha256:26a65c5c93d14c4d221b780fdb2f07b4dd83e848f39eabd4832778bf0e2694d4 \ - --hash=sha256:2e0f66acee330388815fb842f91a46c9cacdefdf02c816354e6adeca8c2c3f86 \ - --hash=sha256:3e2ce47485862fa14ffbf2732f0fd02aa69a7c68a50d5f6286f34ed17527cf87 \ - --hash=sha256:486d17332b9228d2e5975755b434e6a282756a447e0c6605d4e797944fa919da \ - --hash=sha256:55163c5d9b93e10d7217aabd56f776b16c0fe13774f8d5db9188824731da9586 \ - --hash=sha256:676b56eedcc268b7e25a447e736eb8bf8bcacfbc71196c94d6f45746672ee6d5 \ - --hash=sha256:726435b2769135b6282601efb2cd8fd53f7deb1ff2fb7da93d28141fa3c8b17e \ - --hash=sha256:762ffa9673465ccc630aba438d648e0b1a2452ba49669a54a60d1625f36898f3 \ - --hash=sha256:7763c0d5f8e6326ec31f8972cc806fb6d3e07b06ca59f67dfcdf02a34219bcbc \ - --hash=sha256:79cbf5e359cfc33b4c4307df1fe8f78cd5aee56f5c50b98a647fa0cd9ba82cfc \ - --hash=sha256:79f150297b39cfd2481b732554fc4d68b43c83c82eb01e670cc4051cffc089d6 \ - --hash=sha256:7c18b5021ffa6de8313f2c7f0ae6050c36bcee7cb33bb23d40a7fdf3e0a751f2 \ - --hash=sha256:9faa9280e41258fb479ec5395b6a17d3dbb316146832e436aed582b300de655e \ - --hash=sha256:ac18b37e03a29014a9c91aac10c7dbdfa11134c620c6f93dd16f4b99b6a38c2a \ - --hash=sha256:b5a8d91c3e0127360bc3de605df9d02ea4d87e4524a50bf2e7c5c4200f9abf78 \ - --hash=sha256:c1356a2c615e120f913e5235fe87ff8aadbb479ad5a5ac5c0a84881d5fbe981d \ - --hash=sha256:c6fa80373b82125552e691f47b603766ed783f3d90a5782564854aa224aee9d1 \ - --hash=sha256:ca9d22c61f4e3d171b0adad3e9211747917c3a978dfb99564307c1ceadb0f0cd \ - --hash=sha256:ce55b93120f8b429010bf39cc02e739610b6da2ccdd34fcfc0df04849d0fd9d4 \ - --hash=sha256:e3044e6a237b35f750394f199f5e3800dfeb3227c4c8562584877e814d2dc89a \ - --hash=sha256:e42dd9af46fa3ad0e61c1aa6a227357cace481916797ecb92dbb14adb61931e1 \ - --hash=sha256:e5d360d65d42dd97cf82e688a1a7f235b9bc048b4949c9c5c7052ff2783c444e \ - --hash=sha256:e96aaf23f2b021e0d2aac8ac1b541975cd1f6896d9115eefe0938114e694a562 \ - --hash=sha256:f5291c00f610b266ab8c79b1e008b3d0cb29bb5b86a0007529320921b4a3fc3c +snowflake-connector-python[pandas]==4.6.0 \ + --hash=sha256:00abbcfe958f60da18297191f3499b1e61802e64622521a2e8da1c059c14e1c0 \ + --hash=sha256:03b0a232d8d0a1c78eb0d4e9f8a422a1553b2f69ef1387d50a3223bb1829a249 \ + --hash=sha256:04ea8906ac06bdf98ab265f7870b532f32dd2b0f6b3b06a542b6e25a43e01665 \ + --hash=sha256:06e2dba02703da6fd60e07bb0574506f810a85e5831d3461247753ecce4b8335 \ + --hash=sha256:0829d57467bf1bb5af411f6e7723058cb2218fb7df07cf15d912e3b1a2c126eb \ + --hash=sha256:1894504c69a76ac4a205d01fbb3e18c6a6e974e6ad26dad263edd06343bea501 \ + --hash=sha256:18cc5402695b8e958503d6d7ab96403db90c481b63c31520305876ef3cb797e9 \ + --hash=sha256:1c8476781cfef961fc5f6f75a5238e668d3e0ca5ebf1d055661b2fcf2831c254 \ + --hash=sha256:1fe93d88278a0b7e0efde6140890bc298a49fbf1e04968a35aa22c801131cced \ + --hash=sha256:324b15278ee84ea6f0af7fef5e916778c23c4569b2c8ba7fdc90d288478772b9 \ + --hash=sha256:3ff98c3213674c5ed18ba6bb9288c4e88e790150f350824434d49a23d15c0fc3 \ + --hash=sha256:531dcb07eee8405e5d8a9f4e7f8c1ca7916e3afbb4ffb3dd2c9a12ec5bd0e46a \ + --hash=sha256:676162cd45df744aa966483960d34bf204cdcae87cecad77fba970f1c2fd570d \ + --hash=sha256:6d3f6120edeb0d6edd208831d006cc3e769ec51bc346727f22d7aeaecbf20f77 \ + --hash=sha256:72aaee21a70e00fbe4dadcc60b9b1012b6411dddc90f94804d5efe5706fb9621 \ + --hash=sha256:7ab64f46b18d77d1e6c159a29cd86eeff0be9ff01a9904fa873a3c29d20063d1 \ + --hash=sha256:8edc8bbcbaaa25a08d43f943fe45f00dc465684ef243859b0f3f7498d800f1ce \ + --hash=sha256:9dd8689123a7e7b873db0846f2d92745a02062b16665d20634fbaf34a9c88e7a \ + --hash=sha256:a7701b702dbeb348769c5d1248231e18544c4ff1fb4118ad73d48e8f801cfb6e \ + --hash=sha256:c3124fd4a5dc702173ccd73d821ceba1442134d5f347b4c8d1ecb76489f44671 \ + --hash=sha256:e0ca5a035b1afa690fb36a767ba59c8db85ef6295b88c2bbc2040449e99992ad \ + --hash=sha256:e8ccbf8b5e12177a86bd3ab8292cc5a99e9ac97d7645ef4a3ed0f767b4ec6594 \ + --hash=sha256:eab420406a38ebc059100bb1faa55d7d6306bb224cefadb739ec3cafeff65384 \ + --hash=sha256:ed40d1e9d867253596860b9d5240280489ff4692b7a3fa21e2d45d63b4b61d36 \ + --hash=sha256:f15e2493a316ce79ab3d7fb16add10252bb2401723e5cfbc7a2ebc44d89a7b2b \ + --hash=sha256:fe9005d226b234bf190409e5d7e8db9f7daba271880de9105f5173a6858b8e6b # via feast (pyproject.toml) sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ @@ -2855,83 +2973,79 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -sqlglot==29.0.1 \ - --hash=sha256:0010b4f77fb996c8d25dd4b16f3654e6da163ff1866ceabc70b24e791c203048 \ - --hash=sha256:06a473ea6c2b3632ac67bd38e687a6860265bf4156e66b54adeda15d07f00c65 +sqlglot==30.9.0 \ + --hash=sha256:20bed04b6482bf13560206cae517f451f46c321e04956ad71271ed1f12ce8802 \ + --hash=sha256:59b5f74f4d391e32e6980e8cd23cca8d47beac3c0140b711ead9ed05a824a8b5 # via ibis-framework -sse-starlette==3.3.2 \ - --hash=sha256:5c3ea3dad425c601236726af2f27689b74494643f57017cafcb6f8c9acfbb862 \ - --hash=sha256:678fca55a1945c734d8472a6cad186a55ab02840b4f6786f5ee8770970579dcd +sse-starlette==3.4.4 \ + --hash=sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0 \ + --hash=sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973 # via mcp -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 # via + # feast (pyproject.toml) # fastapi # mcp # sse-starlette @@ -2947,58 +3061,58 @@ toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via feast (pyproject.toml) -tomli==2.4.0 \ - --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ - --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ - --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ - --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ - --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ - --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ - --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ - --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ - --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ - --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ - --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ - --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ - --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ - --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ - --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ - --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ - --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ - --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ - --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ - --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ - --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ - --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ - --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ - --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ - --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ - --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ - --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ - --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ - --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ - --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ - --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ - --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ - --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ - --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ - --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ - --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ - --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ - --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ - --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ - --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ - --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ - --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ - --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ - --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ - --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ - --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ - --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 +tomli==2.4.1 \ + --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \ + --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \ + --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \ + --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \ + --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \ + --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \ + --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \ + --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \ + --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \ + --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \ + --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \ + --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \ + --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \ + --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \ + --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \ + --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \ + --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \ + --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \ + --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \ + --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \ + --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \ + --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \ + --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \ + --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \ + --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \ + --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \ + --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \ + --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \ + --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \ + --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \ + --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \ + --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \ + --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \ + --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \ + --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \ + --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \ + --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \ + --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \ + --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \ + --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \ + --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \ + --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \ + --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \ + --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \ + --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \ + --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \ + --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049 # via fastapi-mcp -tomlkit==0.14.0 \ - --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ - --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 +tomlkit==0.15.0 \ + --hash=sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738 \ + --hash=sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3 # via snowflake-connector-python toolz==1.1.0 \ --hash=sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 \ @@ -3007,39 +3121,41 @@ toolz==1.1.0 \ # dask # ibis-framework # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.6.1.19 \ + --hash=sha256:ab4c4ec93cc4a4e7815fa759906e05e6bb3f2fbd92ea0f897288c6a43efd15b3 \ + --hash=sha256:c5132b4b61a829d11cfbd2d72e97f20a45ed6edb95e45c5efdeb5e00836b2745 # via hatchling -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.26.7 \ + --hash=sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58 \ + --hash=sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a # via fastapi-mcp types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via feast (pyproject.toml) -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260518 \ + --hash=sha256:39a2448c4267dc4551e0824d2bfaecf7dfd171e89e6dbba90f4d4d45d55e4342 \ + --hash=sha256:cf697ce4e44124fc859e8e8a7f047c1dc864745c3c628b85a51b3ee01502ef98 # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 # via + # aiohttp # aiosignal # anyio # fastapi + # grpcio # ibis-framework # mcp # mypy @@ -3062,101 +3178,15 @@ typing-inspection==0.4.2 \ # mcp # pydantic # pydantic-settings -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via # ibis-framework # pandas -ujson==5.11.0 \ - --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ - --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ - --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ - --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ - --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ - --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ - --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ - --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ - --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ - --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ - --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ - --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ - --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ - --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ - --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ - --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ - --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ - --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ - --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ - --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ - --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ - --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ - --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ - --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ - --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ - --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ - --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ - --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ - --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ - --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ - --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ - --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ - --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ - --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ - --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ - --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ - --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ - --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ - --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ - --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ - --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ - --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ - --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ - --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ - --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ - --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ - --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ - --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ - --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ - --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ - --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ - --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ - --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ - --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ - --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ - --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ - --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ - --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ - --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ - --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ - --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ - --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ - --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ - --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ - --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ - --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ - --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ - --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ - --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ - --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ - --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ - --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ - --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ - --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ - --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ - --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ - --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ - --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ - --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ - --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ - --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ - --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ - --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ - --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 - # via pymilvus -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # botocore # kubernetes @@ -3224,116 +3254,118 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +vcs-versioning==1.1.1 \ + --hash=sha256:b541e2ba79fc6aaa3850f8a7f88af43d97c1c80649c01142ee4146eddbc599e4 \ + --hash=sha256:fabd75a3cab7dd8ac02fe24a3a9ba936bf258667b5a62ed468c9a1da0f5775bc + # via setuptools-scm +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websocket-client==1.9.0 \ --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ @@ -3402,218 +3434,203 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -wrapt==1.17.3 \ - --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ - --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ - --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ - --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ - --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ - --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ - --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ - --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ - --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ - --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ - --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ - --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ - --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ - --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ - --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ - --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ - --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ - --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ - --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ - --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ - --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ - --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ - --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ - --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ - --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ - --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ - --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ - --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ - --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ - --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ - --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ - --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ - --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ - --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ - --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ - --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ - --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ - --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ - --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ - --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ - --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ - --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ - --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ - --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ - --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ - --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ - --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ - --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ - --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ - --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ - --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ - --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ - --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ - --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ - --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ - --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ - --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ - --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ - --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ - --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ - --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ - --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ - --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ - --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ - --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ - --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ - --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ - --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ - --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ - --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ - --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ - --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ - --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ - --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ - --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ - --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ - --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ - --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ - --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ - --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ - --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c +wrapt==2.2.1 \ + --hash=sha256:036dfb40128819a751c6f451c6b9c10172c49e4c401aebcdb8ecf2aec1683598 \ + --hash=sha256:03df9ebed4c73ab93fa8c07e3d41d818dfca1852b15731a3de59457b27814624 \ + --hash=sha256:05d5cb74d1b232ec8cfa130a8f900708699ff2491d97b8f85a4cdc5996294b85 \ + --hash=sha256:07be671fa8875971222b0ba9059ed8b4dc738631122feba17c93aa36b4213e9a \ + --hash=sha256:09ac16c081bebfd15d8e4dfa5bdc805990bbd52249ecff22530da7a129d6120b \ + --hash=sha256:0d9ff006f420b2ec8296aa56ade43ea7da3e997e85769f0aafc5e0661aacb710 \ + --hash=sha256:0f68f478004475d97906686e702ddbddeaf717c0b68ad2794384308f2dc713ae \ + --hash=sha256:17de18fc12cea55b8a9587314cb830573e37fb33b247a7515696350863714188 \ + --hash=sha256:1ae574d65c9fa8e86f64f6a7c2668f9fcd507b183e0e577619f504b883cb0a6c \ + --hash=sha256:1c9934ea5d92957e3cd0adbc0845539dccfd62710ebe16195a8c66c53954db36 \ + --hash=sha256:1d676ee388bc42a04d56dd7deb5605244dac2e35cc2fadbb43c9fa25bbd93508 \ + --hash=sha256:1ffa9cfd4bdb581539951b14ae661ff20ed0c3599b3e911a131ee0ec5ac11337 \ + --hash=sha256:2076d2335085eb09b9547e7688656fa8f5cf0183eab589d33499cd353489d797 \ + --hash=sha256:211f595f8e7faae5c5930fcc64708f2ba36849e0ba0fd653a843de9fa8d7db77 \ + --hash=sha256:24c52546acf2ab82412f2ab6fc5948a7fe958d3b4f070202e8dcdd865489eaf9 \ + --hash=sha256:2d83966dc7f4f45e8b97b5933685ac2e6e67fc0e19246ea314bceb9a8970c956 \ + --hash=sha256:2de9e20769fe9c1f6dcdc893c6a89287c5ccf8537c90b5de78aed8017697aad5 \ + --hash=sha256:2e08688ab16525897da6589d56d0aebaf417bbe91c2d8e3b96203b1efa596e85 \ + --hash=sha256:2f8c90c8afde51969487be4e1343ae049b268854877d415c2510baf833775052 \ + --hash=sha256:368eac1e20fd0bb03dd3cc42bf9887154c3861b60989389ccb5fac032617d215 \ + --hash=sha256:3aafea2975caef8ca49400640dde02cc7426e798f24870ed01f490bc3cffd32f \ + --hash=sha256:3e2f02472a1cbbf3884b365714a810b5947134a95ad6952b554cb8cce9d492b0 \ + --hash=sha256:3ffad790d9d11d8ecf9f17c4bb671a5b4089e4d8b575c46c5129597f41f836b0 \ + --hash=sha256:401229e9d63ca09f9b8891ecf83798d26c11bbb445d11ed9f1836b6d4585b38a \ + --hash=sha256:436addbc4bb4fc0a88c702577f51195d7d73683a7f3e0e5b253d8404d7847243 \ + --hash=sha256:44255c84bc57554fed822e83e70036b51afa9edb56fc7ca56c54410ece7898c9 \ + --hash=sha256:50972a1d974ea07725a7f6b1cec5f8759008afd030a0024843ebe7d52de47f2b \ + --hash=sha256:5590d63f5243251641cf543009b4c9314a79d0598fdb8a8e4cfc918494536c53 \ + --hash=sha256:585916e210db57b23543342c2f298e42331b617fd0c934caf5c64df44de8640e \ + --hash=sha256:5f1845c2a8cc1180ccccfa45785dd06f562730d19ef75be180334254012b6283 \ + --hash=sha256:5fa9bf3b9e66336589d03f42abce2da1055ad5c69b0c2b764852a8471c9b9114 \ + --hash=sha256:61a0013344674d2b648bc6e6fe9828dd4fc1d3b4eb7523809792f8cb952e2f16 \ + --hash=sha256:61acce4257a9883669703c525447c5b4c392edf0f987ae77ec32668440158f0e \ + --hash=sha256:628f5220c7a904d5fc78f7075c8d7871433eb6d035c94728a22fdf85f193d2a8 \ + --hash=sha256:64b7deeda4b70408e382328d8bbe52a256fe9bc63ae3db86d804608367e5422c \ + --hash=sha256:6744f504375775d7609c82c8d3d94af1c9a6f05586984536905908ba905277b9 \ + --hash=sha256:67a97e5b6c457f0cd3cfc19ebb2d84463e60c3ece754cc831e4281a3ca29bb18 \ + --hash=sha256:69f2e9244542cb34dd59c7f073445b9e54ad9f3fce8d93606c368a1b499fc413 \ + --hash=sha256:6ce32763ac31ce94fe9aada947e479b1975012bff166da409b4b9e4e376cf7e5 \ + --hash=sha256:6f56a647e4eaf5f0ca40330fb070f566bdf9f7b0db89a1af20d71c28dcd7a0ab \ + --hash=sha256:727ab4244622cd6ad2390f322642090c877d2e83a608d2653a7643ae5368d926 \ + --hash=sha256:74d6a0c31472fe5d814917266b9f46495d7c61ed890af08b468acea92fb89a8d \ + --hash=sha256:78b0aa6bfb7be8deed0ab23e7aa028cc5210c29bc2d32a04d52b50e517a7307e \ + --hash=sha256:7975bc88ab4b0f72ef2a2d5ae9d77d87efb5ef95e8f8046242fa9afdaaf2030b \ + --hash=sha256:7a4fdb9326aab4a5a477a1640e5ad786a8495901009d7e7b038371edd23a9d2b \ + --hash=sha256:844c858fc3bb7eacc0ba8efa904935d16aac6a4470948ad1e7e55c9f5a2a665f \ + --hash=sha256:87bacdaf225117a342a20d9c03438d701c02112f6e3f351ce9b7f32354f14797 \ + --hash=sha256:8a983a603a18c8708f024f7f6991b2e66159219abbf894634c5056243c55f3cd \ + --hash=sha256:8d1b4d0e0c2119587a31f5c029abd547e0c81d93b89d394566fe1588659eb579 \ + --hash=sha256:9011395be8db1827d106c6449b4bb6dd17e331ff6ec521f227e4588f1c78e46f \ + --hash=sha256:93fc2bf40cd7f4a0256010dce073d44eeb4a351b9bca94d0477ce2b6e62532b3 \ + --hash=sha256:95821352042722cd9f1108874579a47989d0a7e12a37d87d2fc4af20fd99ab8a \ + --hash=sha256:9907a4402ab6db12b7077a0ea5d7a4d028ecb22c8eee2b53527080d347cd1562 \ + --hash=sha256:9a04c28c10ba7fd12842b109d2edb0678872a2fe65277ca4ff06a0d61edee245 \ + --hash=sha256:9a5934eaea872e17936b5f45501eba5ab0bce9a74122e172b663d7c28c459c4a \ + --hash=sha256:9b984d1eb252145d6302c1dbd5e87fc6d404d45531447c84eadec04bf1fcb027 \ + --hash=sha256:9c210a6994b21aa9b29e81c8d11560e8fdab54c117e9cff37870d0a27bde1343 \ + --hash=sha256:9d8f204c8e3a8bf9ece17e0a83d137fd807440977f8a5e762d59306795011440 \ + --hash=sha256:a8f7176b83664af44567e9cc06e0d3827823fcc1a5e52307ebb8ac3aa95860b9 \ + --hash=sha256:a9dec1aca52dddde7df94818310fa2fe79739c8f385b2014c4cb1035f5508199 \ + --hash=sha256:ab5be648d5a0b86b7438864f8df3c705a65cef35a2fd3e5561e3e203167e0f27 \ + --hash=sha256:abd621552ede77c4c69be7fac44ba911225b0c812b6ba604e5964cf98085b474 \ + --hash=sha256:ac2745950b2bff80219c15ebf2fa9d8427eba7e249739f97e55c9d169e47e9e1 \ + --hash=sha256:aed9658797d0b45d6c49adcfc6b41f66e6f2d0c6de3ec79e16cf4b1855df240f \ + --hash=sha256:b6c0febfe38f22df2eb565c0ce8a092bb80411e56861ca382c443da83105423f \ + --hash=sha256:b9cf53ba90717db2e292401de290776c498d4bbfb0d4a559ca2895db8b9dcb5c \ + --hash=sha256:ba519b2d765df9871a25879e6f7fa78948ea59a2a31f9c1a257e34b651994afc \ + --hash=sha256:c318a64b53d97b841d7b5e637517e50a27be64bc695128422953d4b21710954e \ + --hash=sha256:c3723ff8eb8721f4daac98bc0256f15158e05316d5e52648ce9cebee434fbdd5 \ + --hash=sha256:c754dafdf5aaf0b401b644a90a30046929a0dd1a536e0ff0ec959a59155d9c7f \ + --hash=sha256:c803a3d331796255af51ba2c79ed0ac8275865b516c09e61f248d1e7aff31ce9 \ + --hash=sha256:c8cc5094b08abeae52da9c73c8a32003623be691a5193df2f4e3eac3d557c394 \ + --hash=sha256:cf3638274ab9d9b724c9baa0b4c04e132cd6faefb78b4dd3dd1a02a4bdaad41e \ + --hash=sha256:d047f6498c973874ba08ac3f97c69a2c4b2211c8de6f4c205f75cb1c9522596e \ + --hash=sha256:d2beb1c7cab10603aecdc42f8edd6ff013f9a32e4543474e38e6b77ce9975aeb \ + --hash=sha256:d7f513d3185e6fec82d0c3518f2e6365d8b4e49f5f45f29640d5162d56a23b54 \ + --hash=sha256:dd57607acc85678925940bd5df0385ff8332083a32fa8d7a43f8767f4997263c \ + --hash=sha256:e0cb7e4dd71f4c32e5e84843cd3c4cd65dda034314004bbe1d7f99af2426ab80 \ + --hash=sha256:e3677c7146ce694874941ba82b57092cc4875445aadf29d72807351023105143 \ + --hash=sha256:e395f7bc31851ef9b612050368cb446e9bc14cd7454b025018980349caf25ae5 \ + --hash=sha256:e422b2d647a65d6b080cad5accd09055d3809bdff00c76fba8dca00ca935572a \ + --hash=sha256:ed55af48b3eb28f43228ca2306788892bcb629eb2b5c4876e2a3659872c2f17a \ + --hash=sha256:ed928d0fda15fc0adc8d13305c8b3c0f2fba5b0669950c9e6d019d9162a3b3e8 \ + --hash=sha256:f4e1a92032a39cd5e3c647ca57dbf33b6a1938fd975623175793f9dbb63236de \ + --hash=sha256:f53ac9f3ef573326d009ed809beff4efcac6451931c2b8132586da4b9e53ff31 \ + --hash=sha256:f5b9daf6b629fce418e0cc3dd0436eac045188fa35deadb7a7f3941d5b8203f9 \ + --hash=sha256:f6518b94edb9150452e9aba08027d4cc293433753ec1fbefb4629a21cbc74181 \ + --hash=sha256:f70db64e8266d7c45d3b735f2e08eeb434b5e03da9a479ae42b2e2e486a21a00 \ + --hash=sha256:fafb4e739e43544d12cb4abd1605fd4683b6ca6a9ad682b7fd8f4d21973eafa8 \ + --hash=sha256:fd0135d34387f5fd087d9be368ea77ea89cf2451dc1cd1c622d35021bcb3ab50 # via aiobotocore -yarl==1.23.0 \ - --hash=sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc \ - --hash=sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4 \ - --hash=sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85 \ - --hash=sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993 \ - --hash=sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222 \ - --hash=sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de \ - --hash=sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25 \ - --hash=sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e \ - --hash=sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2 \ - --hash=sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e \ - --hash=sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860 \ - --hash=sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957 \ - --hash=sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760 \ - --hash=sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52 \ - --hash=sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788 \ - --hash=sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912 \ - --hash=sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719 \ - --hash=sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035 \ - --hash=sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220 \ - --hash=sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412 \ - --hash=sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05 \ - --hash=sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41 \ - --hash=sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4 \ - --hash=sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 \ - --hash=sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd \ - --hash=sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748 \ - --hash=sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a \ - --hash=sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4 \ - --hash=sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34 \ - --hash=sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069 \ - --hash=sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25 \ - --hash=sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2 \ - --hash=sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb \ - --hash=sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f \ - --hash=sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 \ - --hash=sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8 \ - --hash=sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c \ - --hash=sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512 \ - --hash=sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6 \ - --hash=sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5 \ - --hash=sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9 \ - --hash=sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072 \ - --hash=sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5 \ - --hash=sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277 \ - --hash=sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a \ - --hash=sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6 \ - --hash=sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae \ - --hash=sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26 \ - --hash=sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2 \ - --hash=sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4 \ - --hash=sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70 \ - --hash=sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723 \ - --hash=sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c \ - --hash=sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9 \ - --hash=sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5 \ - --hash=sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e \ - --hash=sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c \ - --hash=sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4 \ - --hash=sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0 \ - --hash=sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2 \ - --hash=sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b \ - --hash=sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7 \ - --hash=sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750 \ - --hash=sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2 \ - --hash=sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474 \ - --hash=sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716 \ - --hash=sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7 \ - --hash=sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123 \ - --hash=sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007 \ - --hash=sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595 \ - --hash=sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe \ - --hash=sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea \ - --hash=sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 \ - --hash=sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679 \ - --hash=sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8 \ - --hash=sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83 \ - --hash=sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6 \ - --hash=sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f \ - --hash=sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94 \ - --hash=sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51 \ - --hash=sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120 \ - --hash=sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039 \ - --hash=sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1 \ - --hash=sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05 \ - --hash=sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb \ - --hash=sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144 \ - --hash=sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa \ - --hash=sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a \ - --hash=sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99 \ - --hash=sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928 \ - --hash=sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d \ - --hash=sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 \ - --hash=sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434 \ - --hash=sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86 \ - --hash=sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 \ - --hash=sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319 \ - --hash=sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67 \ - --hash=sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c \ - --hash=sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169 \ - --hash=sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c \ - --hash=sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59 \ - --hash=sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107 \ - --hash=sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4 \ - --hash=sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a \ - --hash=sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb \ - --hash=sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f \ - --hash=sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769 \ - --hash=sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 \ - --hash=sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090 \ - --hash=sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764 \ - --hash=sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d \ - --hash=sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4 \ - --hash=sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b \ - --hash=sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d \ - --hash=sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543 \ - --hash=sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24 \ - --hash=sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5 \ - --hash=sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b \ - --hash=sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d \ - --hash=sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b \ - --hash=sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6 \ - --hash=sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735 \ - --hash=sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e \ - --hash=sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28 \ - --hash=sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3 \ - --hash=sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401 \ - --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ - --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d +yarl==1.24.2 \ + --hash=sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b \ + --hash=sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30 \ + --hash=sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc \ + --hash=sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f \ + --hash=sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae \ + --hash=sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8 \ + --hash=sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75 \ + --hash=sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a \ + --hash=sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c \ + --hash=sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461 \ + --hash=sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44 \ + --hash=sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b \ + --hash=sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727 \ + --hash=sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9 \ + --hash=sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd \ + --hash=sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67 \ + --hash=sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420 \ + --hash=sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db \ + --hash=sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50 \ + --hash=sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b \ + --hash=sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50 \ + --hash=sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9 \ + --hash=sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1 \ + --hash=sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488 \ + --hash=sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2 \ + --hash=sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f \ + --hash=sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d \ + --hash=sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003 \ + --hash=sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536 \ + --hash=sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a \ + --hash=sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a \ + --hash=sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa \ + --hash=sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f \ + --hash=sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e \ + --hash=sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035 \ + --hash=sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12 \ + --hash=sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe \ + --hash=sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4 \ + --hash=sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294 \ + --hash=sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7 \ + --hash=sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761 \ + --hash=sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643 \ + --hash=sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413 \ + --hash=sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57 \ + --hash=sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36 \ + --hash=sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14 \ + --hash=sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd \ + --hash=sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5 \ + --hash=sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656 \ + --hash=sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad \ + --hash=sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c \ + --hash=sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0 \ + --hash=sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992 \ + --hash=sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342 \ + --hash=sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1 \ + --hash=sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf \ + --hash=sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024 \ + --hash=sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986 \ + --hash=sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb \ + --hash=sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d \ + --hash=sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543 \ + --hash=sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d \ + --hash=sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed \ + --hash=sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617 \ + --hash=sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996 \ + --hash=sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8 \ + --hash=sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2 \ + --hash=sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3 \ + --hash=sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535 \ + --hash=sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630 \ + --hash=sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215 \ + --hash=sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592 \ + --hash=sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf \ + --hash=sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b \ + --hash=sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac \ + --hash=sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0 \ + --hash=sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92 \ + --hash=sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122 \ + --hash=sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1 \ + --hash=sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8 \ + --hash=sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576 \ + --hash=sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8 \ + --hash=sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712 \ + --hash=sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1 \ + --hash=sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2 \ + --hash=sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b \ + --hash=sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a \ + --hash=sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53 \ + --hash=sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1 \ + --hash=sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d \ + --hash=sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208 \ + --hash=sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0 \ + --hash=sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c \ + --hash=sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607 \ + --hash=sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c \ + --hash=sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8 \ + --hash=sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39 \ + --hash=sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f \ + --hash=sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8 \ + --hash=sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90 \ + --hash=sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45 \ + --hash=sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2 \ + --hash=sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056 \ + --hash=sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14 # via aiohttp # The following packages were excluded from the output: diff --git a/sdk/python/requirements/py3.12-requirements.txt b/sdk/python/requirements/py3.12-requirements.txt index a19f386c13f..4606cef5b92 100644 --- a/sdk/python/requirements/py3.12-requirements.txt +++ b/sdk/python/requirements/py3.12-requirements.txt @@ -8,144 +8,195 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.13.0 \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc # via # starlette # watchfiles -attrs==25.4.0 \ - --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ - --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 +ast-serialize==0.5.0 \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy +attrs==26.1.0 \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 # via # jsonschema # referencing -bigtree==1.3.1 \ - --hash=sha256:a22a0ecd9b0abb283f4a1515370dbf1ec93adee70746767272e2c49d7af9f407 \ - --hash=sha256:c8b766b00188c532d3499bfd9e9666b357428db507fc701f088031a0d5c614d5 +bigtree==1.4.1 \ + --hash=sha256:78bf1fb50c46242012b26b237c652b21a28220b6e66f9f6a07cd059375618040 \ + --hash=sha256:81fffc6c6b92f4038710f5a5d60532deaad31e7ebacb8f527bc7eb1fbd286477 # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.5.20 \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d # via requests -charset-normalizer==3.4.5 \ - --hash=sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4 \ - --hash=sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 \ - --hash=sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54 \ - --hash=sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05 \ - --hash=sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765 \ - --hash=sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064 \ - --hash=sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 \ - --hash=sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e \ - --hash=sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412 \ - --hash=sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc \ - --hash=sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e \ - --hash=sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281 \ - --hash=sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af \ - --hash=sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2 \ - --hash=sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe \ - --hash=sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8 \ - --hash=sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262 \ - --hash=sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac \ - --hash=sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85 \ - --hash=sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c \ - --hash=sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf \ - --hash=sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139 \ - --hash=sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770 \ - --hash=sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d \ - --hash=sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918 \ - --hash=sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3 \ - --hash=sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7 \ - --hash=sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39 \ - --hash=sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d \ - --hash=sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990 \ - --hash=sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765 \ - --hash=sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1 \ - --hash=sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa \ - --hash=sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659 \ - --hash=sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d \ - --hash=sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9 \ - --hash=sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9 \ - --hash=sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2 \ - --hash=sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d \ - --hash=sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475 \ - --hash=sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c \ - --hash=sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81 \ - --hash=sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67 \ - --hash=sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99 \ - --hash=sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5 \ - --hash=sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694 \ - --hash=sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf \ - --hash=sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca \ - --hash=sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c \ - --hash=sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c \ - --hash=sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636 \ - --hash=sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f \ - --hash=sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02 \ - --hash=sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497 \ - --hash=sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f \ - --hash=sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2 \ - --hash=sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d \ - --hash=sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873 \ - --hash=sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a \ - --hash=sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e \ - --hash=sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1 \ - --hash=sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123 \ - --hash=sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550 \ - --hash=sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc \ - --hash=sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36 \ - --hash=sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644 \ - --hash=sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4 \ - --hash=sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0 \ - --hash=sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e \ - --hash=sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f \ - --hash=sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4 \ - --hash=sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98 \ - --hash=sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294 \ - --hash=sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22 \ - --hash=sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23 \ - --hash=sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8 \ - --hash=sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2 \ - --hash=sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362 \ - --hash=sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242 \ - --hash=sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4 \ - --hash=sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95 \ - --hash=sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d \ - --hash=sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94 \ - --hash=sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6 \ - --hash=sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2 \ - --hash=sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4 \ - --hash=sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8 \ - --hash=sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e \ - --hash=sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a \ - --hash=sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce \ - --hash=sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969 \ - --hash=sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f \ - --hash=sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923 \ - --hash=sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6 \ - --hash=sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee \ - --hash=sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6 \ - --hash=sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467 \ - --hash=sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f \ - --hash=sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193 \ - --hash=sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7 \ - --hash=sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9 \ - --hash=sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95 \ - --hash=sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763 \ - --hash=sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7 \ - --hash=sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98 \ - --hash=sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60 \ - --hash=sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade \ - --hash=sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c \ - --hash=sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2 \ - --hash=sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f \ - --hash=sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a \ - --hash=sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947 \ - --hash=sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3 +charset-normalizer==3.4.7 \ + --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ + --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ + --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ + --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ + --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ + --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ + --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ + --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ + --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ + --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ + --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ + --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ + --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ + --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ + --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ + --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ + --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ + --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ + --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ + --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ + --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ + --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ + --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ + --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ + --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ + --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ + --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ + --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ + --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ + --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ + --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ + --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ + --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.4.1 \ + --hash=sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2 \ + --hash=sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96 # via # feast (pyproject.toml) # dask @@ -158,25 +209,25 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -dask[dataframe]==2026.1.2 \ - --hash=sha256:1136683de2750d98ea792670f7434e6c1cfce90cab2cc2f2495a9e60fd25a4fc \ - --hash=sha256:46a0cf3b8d87f78a3d2e6b145aea4418a6d6d606fe6a16c79bd8ca2bb862bc91 +dask[dataframe]==2026.3.0 \ + --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ + --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -fastapi==0.135.1 \ - --hash=sha256:46e2fc5745924b7c840f71ddd277382af29ce1cdb7d5eab5bf697e3fb9999c9e \ - --hash=sha256:d04115b508d936d254cea545b7312ecaa58a7b3a0f84952535b4c9afae7668cd +fastapi==0.136.3 \ + --hash=sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620 \ + --hash=sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab # via feast (pyproject.toml) -fsspec==2026.2.0 \ - --hash=sha256:6544e34b16869f5aacd5b90bdf1a71acb37792ea3ddf6125ee69a22a53fb8bff \ - --hash=sha256:98de475b5cb3bd66bedd5c4679e87b4fdfe1a3bf4d707b151b3c07e58c9a2437 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # feast (pyproject.toml) # uvicorn-worker @@ -184,54 +235,61 @@ h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 # via uvicorn -httptools==0.7.1 \ - --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ - --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ - --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ - --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ - --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ - --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ - --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ - --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ - --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ - --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ - --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ - --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ - --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ - --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ - --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ - --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ - --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ - --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ - --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ - --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ - --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ - --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ - --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ - --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ - --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ - --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ - --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ - --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ - --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ - --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ - --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ - --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ - --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ - --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ - --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ - --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ - --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ - --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ - --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ - --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ - --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ - --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ - --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 +httptools==0.8.0 \ + --hash=sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683 \ + --hash=sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb \ + --hash=sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b \ + --hash=sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527 \ + --hash=sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124 \ + --hash=sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca \ + --hash=sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081 \ + --hash=sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c \ + --hash=sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77 \ + --hash=sha256:425f83884fd6343828d8c565f046cb72b6d19063f6924093e11bcd8e1548cd09 \ + --hash=sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f \ + --hash=sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085 \ + --hash=sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376 \ + --hash=sha256:5931891fb7b441b8a3853cf1b85c82c903defce084dd5f6771ca46e31bf862c5 \ + --hash=sha256:5d7fa4ba7292c1139c0526f0b5aad507c6263c948206ea1b1cbca015c8af1b62 \ + --hash=sha256:5eb911c515b96ee44bbd861e42cbefc488681d450545b1d02127f6136e3a86f5 \ + --hash=sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8 \ + --hash=sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681 \ + --hash=sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999 \ + --hash=sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1 \ + --hash=sha256:7b71e7d7031928c650e1006e6c03e911bf967f7c69c011d37d541c3e7bf55005 \ + --hash=sha256:880490234c10f70a9830743097e8958d6e4b9f5a0ffc24515023afeef984054d \ + --hash=sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d \ + --hash=sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d \ + --hash=sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d \ + --hash=sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba \ + --hash=sha256:9fc1644f415372cec4f8a5be3a64183737398f10dbb1263602a036427fe75247 \ + --hash=sha256:a1afd7c9fbff0d9f5d489c4ce2768bd09c84a46ddefc7161e6aa82ae35c85745 \ + --hash=sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07 \ + --hash=sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b \ + --hash=sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4 \ + --hash=sha256:b15fc622b0f869d19207c4089a501d9bcc63ca5e071ffdd2f03f922df882dcb2 \ + --hash=sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557 \ + --hash=sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d \ + --hash=sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826 \ + --hash=sha256:c08ffe3e79756e0963cbc8fe410139f38a5884874b6f2e17761bef6563fdcd9b \ + --hash=sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813 \ + --hash=sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0 \ + --hash=sha256:cd96f29b4bab1d42fa6e3d008711c75e0f79e94e06827330160e3a304227f150 \ + --hash=sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e \ + --hash=sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77 \ + --hash=sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568 \ + --hash=sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6 \ + --hash=sha256:df31ef5494f406ab6cf827b7e64a22841c6e2d654100e6a116ea15b46d02d5e8 \ + --hash=sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b \ + --hash=sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7 \ + --hash=sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168 \ + --hash=sha256:ef7c3c97f4311c7be57e2986629df89d49cb434dbff78eafcd48c2bff986b15a \ + --hash=sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0 \ + --hash=sha256:fe2a4c95aeba2209434e7b31172da572846cae8ca0bf1e7013e61b99fbbf5e72 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # anyio # requests @@ -247,97 +305,97 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -librt==0.8.1 \ - --hash=sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6 \ - --hash=sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d \ - --hash=sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440 \ - --hash=sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a \ - --hash=sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed \ - --hash=sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5 \ - --hash=sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04 \ - --hash=sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3 \ - --hash=sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d \ - --hash=sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14 \ - --hash=sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972 \ - --hash=sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c \ - --hash=sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78 \ - --hash=sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732 \ - --hash=sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c \ - --hash=sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6 \ - --hash=sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed \ - --hash=sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1 \ - --hash=sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551 \ - --hash=sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7 \ - --hash=sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382 \ - --hash=sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac \ - --hash=sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a \ - --hash=sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99 \ - --hash=sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac \ - --hash=sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb \ - --hash=sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc \ - --hash=sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7 \ - --hash=sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0 \ - --hash=sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb \ - --hash=sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2 \ - --hash=sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7 \ - --hash=sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0 \ - --hash=sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7 \ - --hash=sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363 \ - --hash=sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624 \ - --hash=sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9 \ - --hash=sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7 \ - --hash=sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd \ - --hash=sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3 \ - --hash=sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f \ - --hash=sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a \ - --hash=sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0 \ - --hash=sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb \ - --hash=sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e \ - --hash=sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc \ - --hash=sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071 \ - --hash=sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730 \ - --hash=sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35 \ - --hash=sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc \ - --hash=sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe \ - --hash=sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4 \ - --hash=sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6 \ - --hash=sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71 \ - --hash=sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0 \ - --hash=sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d \ - --hash=sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b \ - --hash=sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040 \ - --hash=sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596 \ - --hash=sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a \ - --hash=sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee \ - --hash=sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965 \ - --hash=sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7 \ - --hash=sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da \ - --hash=sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9 \ - --hash=sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128 \ - --hash=sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851 \ - --hash=sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73 \ - --hash=sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61 \ - --hash=sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b \ - --hash=sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891 \ - --hash=sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7 \ - --hash=sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994 \ - --hash=sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583 \ - --hash=sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac \ - --hash=sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3 \ - --hash=sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6 \ - --hash=sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921 \ - --hash=sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0 \ - --hash=sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79 \ - --hash=sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd \ - --hash=sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012 \ - --hash=sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023 \ - --hash=sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4 \ - --hash=sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05 \ - --hash=sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c \ - --hash=sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e \ - --hash=sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9 \ - --hash=sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b \ - --hash=sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444 +librt==0.11.0 \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783 \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677 \ + --hash=sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f \ + --hash=sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412 \ + --hash=sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0 \ + --hash=sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb \ + --hash=sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1 \ + --hash=sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9 \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab \ + --hash=sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c \ + --hash=sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192 \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e \ + --hash=sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73 \ + --hash=sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29 \ + --hash=sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89 \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1 \ + --hash=sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280 \ + --hash=sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5 \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4 \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5 \ + --hash=sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0 \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c \ + --hash=sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -543,206 +601,136 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.19.1 \ - --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ - --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ - --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ - --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ - --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ - --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ - --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ - --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ - --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ - --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ - --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ - --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ - --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ - --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ - --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ - --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ - --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ - --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ - --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ - --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ - --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ - --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ - --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ - --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ - --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ - --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ - --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ - --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ - --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ - --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ - --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ - --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ - --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ - --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ - --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ - --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ - --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ - --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e +mypy==2.1.0 \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666 \ + --hash=sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc \ + --hash=sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563 \ + --hash=sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849 \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41 \ + --hash=sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e \ + --hash=sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8 \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389 \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via mypy -numpy==2.4.3 \ - --hash=sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5 \ - --hash=sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc \ - --hash=sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657 \ - --hash=sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd \ - --hash=sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02 \ - --hash=sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a \ - --hash=sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26 \ - --hash=sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92 \ - --hash=sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22 \ - --hash=sha256:23b46bb6d8ecb68b58c09944483c135ae5f0e9b8d8858ece5e4ead783771d2a9 \ - --hash=sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9 \ - --hash=sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9 \ - --hash=sha256:29363fbfa6f8ee855d7569c96ce524845e3d726d6c19b29eceec7dd555dab152 \ - --hash=sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168 \ - --hash=sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e \ - --hash=sha256:2b3f8d2c4589b1a2028d2a770b0fc4d1f332fb5e01521f4de3199a896d158ddd \ - --hash=sha256:2ddb7919366ee468342b91dea2352824c25b55814a987847b6c52003a7c97f15 \ - --hash=sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093 \ - --hash=sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5 \ - --hash=sha256:33b3bf58ee84b172c067f56aeadc7ee9ab6de69c5e800ab5b10295d54c581adb \ - --hash=sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b \ - --hash=sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd \ - --hash=sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18 \ - --hash=sha256:4b42639cdde6d24e732ff823a3fa5b701d8acad89c4142bc1d0bd6dc85200ba5 \ - --hash=sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950 \ - --hash=sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e \ - --hash=sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a \ - --hash=sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd \ - --hash=sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4 \ - --hash=sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0 \ - --hash=sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef \ - --hash=sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5 \ - --hash=sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24 \ - --hash=sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476 \ - --hash=sha256:715de7f82e192e8cae5a507a347d97ad17598f8e026152ca97233e3666daaa71 \ - --hash=sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc \ - --hash=sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e \ - --hash=sha256:76dbb9d4e43c16cf9aa711fcd8de1e2eeb27539dcefb60a1d5e9f12fae1d1ed8 \ - --hash=sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c \ - --hash=sha256:77e76d932c49a75617c6d13464e41203cd410956614d0a0e999b25e9e8d27eec \ - --hash=sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875 \ - --hash=sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a \ - --hash=sha256:7e58765ad74dcebd3ef0208a5078fba32dc8ec3578fe84a604432950cd043d79 \ - --hash=sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f \ - --hash=sha256:8ba7b51e71c05aa1f9bc3641463cd82308eab40ce0d5c7e1fd4038cbf9938147 \ - --hash=sha256:8e236dbda4e1d319d681afcbb136c0c4a8e0f1a5c58ceec2adebb547357fe857 \ - --hash=sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368 \ - --hash=sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720 \ - --hash=sha256:a016db5c5dba78fa8fe9f5d80d6708f9c42ab087a739803c0ac83a43d686a470 \ - --hash=sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b \ - --hash=sha256:a1988292870c7cb9d0ebb4cc96b4d447513a9644801de54606dc7aabf2b7d920 \ - --hash=sha256:a315e5234d88067f2d97e1f2ef670a7569df445d55400f1e33d117418d008d52 \ - --hash=sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73 \ - --hash=sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349 \ - --hash=sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4 \ - --hash=sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3 \ - --hash=sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7 \ - --hash=sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee \ - --hash=sha256:bc71942c789ef415a37f0d4eab90341425a00d538cd0642445d30b41023d3395 \ - --hash=sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c \ - --hash=sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611 \ - --hash=sha256:c6b124bfcafb9e8d3ed09130dbee44848c20b3e758b6bbf006e641778927c028 \ - --hash=sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d \ - --hash=sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7 \ - --hash=sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070 \ - --hash=sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0 \ - --hash=sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc \ - --hash=sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687 \ - --hash=sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0 \ - --hash=sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f \ - --hash=sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97 \ - --hash=sha256:eb610595dd91560905c132c709412b512135a60f1851ccbd2c959e136431ff67 +numpy==2.4.6 \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \ + --hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 # via # feast (pyproject.toml) # dask # pandas -orjson==3.11.7 \ - --hash=sha256:043d3006b7d32c7e233b8cfb1f01c651013ea079e08dcef7189a29abd8befe11 \ - --hash=sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e \ - --hash=sha256:0724e265bc548af1dedebd9cb3d24b4e1c1e685a343be43e87ba922a5c5fff2f \ - --hash=sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8 \ - --hash=sha256:14f440c7268c8f8633d1b3d443a434bd70cb15686117ea6beff8fdc8f5917a1e \ - --hash=sha256:1d98b30cc1313d52d4af17d9c3d307b08389752ec5f2e5febdfada70b0f8c733 \ - --hash=sha256:1eb80451a9c351a71dfaf5b7ccc13ad065405217726b59fdbeadbcc544f9d223 \ - --hash=sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d \ - --hash=sha256:23d6c20517a97a9daf1d48b580fcdc6f0516c6f4b5038823426033690b4d2650 \ - --hash=sha256:26c3b9132f783b7d7903bf1efb095fed8d4a3a85ec0d334ee8beff3d7a4749d5 \ - --hash=sha256:31c80ce534ac4ea3739c5ee751270646cbc46e45aea7576a38ffec040b4029a1 \ - --hash=sha256:3726be79e36e526e3d9c1aceaadbfb4a04ee80a72ab47b3f3c17fefb9812e7b8 \ - --hash=sha256:390a1dce0c055ddf8adb6aa94a73b45a4a7d7177b5c584b8d1c1947f2ba60fb3 \ - --hash=sha256:3a2479753bbb95b0ebcf7969f562cdb9668e6d12416a35b0dda79febf89cdea2 \ - --hash=sha256:3c4bc6c6ac52cdaa267552544c73e486fecbd710b7ac09bc024d5a78555a22f6 \ - --hash=sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910 \ - --hash=sha256:4682d1db3bcebd2b64757e0ddf9e87ae5f00d29d16c5cdf3a62f561d08cc3dd2 \ - --hash=sha256:4a2e9c5be347b937a2e0203866f12bba36082e89b402ddb9e927d5822e43088d \ - --hash=sha256:57036b27ac8a25d81112eb0cc9835cd4833c5b16e1467816adc0015f59e870dc \ - --hash=sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a \ - --hash=sha256:5fdfad2093bdd08245f2e204d977facd5f871c88c4a71230d5bcbd0e43bf6222 \ - --hash=sha256:623ad1b9548ef63886319c16fa317848e465a21513b31a6ad7b57443c3e0dcf5 \ - --hash=sha256:652c6c3af76716f4a9c290371ba2e390ede06f6603edb277b481daf37f6f464e \ - --hash=sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471 \ - --hash=sha256:6e776b998ac37c0396093d10290e60283f59cfe0fc3fccbd0ccc4bd04dd19892 \ - --hash=sha256:71924496986275a737f38e3f22b4e0878882b3f7a310d2ff4dc96e812789120c \ - --hash=sha256:733ae23ada68b804b222c44affed76b39e30806d38660bf1eb200520d259cc16 \ - --hash=sha256:7477aa6a6ec6139c5cb1cc7b214643592169a5494d200397c7fc95d740d5fcf3 \ - --hash=sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b \ - --hash=sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504 \ - --hash=sha256:800988273a014a0541483dc81021247d7eacb0c845a9d1a34a422bc718f41539 \ - --hash=sha256:814be4b49b228cfc0b3c565acf642dd7d13538f966e3ccde61f4f55be3e20785 \ - --hash=sha256:845c3e0d8ded9c9271cd79596b9b552448b885b97110f628fb687aee2eed11c1 \ - --hash=sha256:849e38203e5be40b776ed2718e587faf204d184fc9a008ae441f9442320c0cab \ - --hash=sha256:89e13dd3f89f1c38a9c9eba5fbf7cdc2d1feca82f5f290864b4b7a6aac704576 \ - --hash=sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b \ - --hash=sha256:8ff206156006da5b847c9304b6308a01e8cdbc8cce824e2779a5ba71c3def141 \ - --hash=sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62 \ - --hash=sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c \ - --hash=sha256:962d046ee1765f74a1da723f4b33e3b228fe3a48bd307acce5021dfefe0e29b2 \ - --hash=sha256:996b65230271f1a97026fd0e6a753f51fbc0c335d2ad0c6201f711b0da32693b \ - --hash=sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49 \ - --hash=sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960 \ - --hash=sha256:9e54f3808e2b6b945078c41aa8d9b5834b28c50843846e97807e5adb75fa9705 \ - --hash=sha256:a02c833f38f36546ba65a452127633afce4cf0dd7296b753d3bb54e55e5c0174 \ - --hash=sha256:a12b80df61aab7b98b490fe9e4879925ba666fccdfcd175252ce4d9035865ace \ - --hash=sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b \ - --hash=sha256:a56df3239294ea5964adf074c54bcc4f0ccd21636049a2cf3ca9cf03b5d03cf1 \ - --hash=sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561 \ - --hash=sha256:ab49d4b2a6a1d415ddb9f37a21e02e0d5dbfe10b7870b21bf779fc21e9156157 \ - --hash=sha256:ae9e0b37a834cef7ce8f99de6498f8fad4a2c0bf6bfc3d02abd8ed56aa15b2de \ - --hash=sha256:b4a9eefdc70bf8bf9857f0290f973dec534ac84c35cd6a7f4083be43e7170a8f \ - --hash=sha256:b63c6e6738d7c3470ad01601e23376aa511e50e1f3931395b9f9c722406d1a67 \ - --hash=sha256:b7b1dae39230a393df353827c855a5f176271c23434cfd2db74e0e424e693e10 \ - --hash=sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5 \ - --hash=sha256:b9f95dcdea9d4f805daa9ddf02617a89e484c6985fa03055459f90e87d7a0757 \ - --hash=sha256:b9fc4d0f81f394689e0814617aadc4f2ea0e8025f38c226cbf22d3b5ddbf025d \ - --hash=sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f \ - --hash=sha256:bd0d68edd7dfca1b2eca9361a44ac9f24b078de3481003159929a0573f21a6bf \ - --hash=sha256:bda117c4148e81f746655d5a3239ae9bd00cb7bc3ca178b5fc5a5997e9744183 \ - --hash=sha256:bf742e149121dc5648ba0a08ea0871e87b660467ef168a3a5e53bc1fbd64bb74 \ - --hash=sha256:c2428d358d85e8da9d37cba18b8c4047c55222007a84f97156a5b22028dfbfc0 \ - --hash=sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e \ - --hash=sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d \ - --hash=sha256:cededd6738e1c153530793998e31c05086582b08315db48ab66649768f326baa \ - --hash=sha256:d06e5c5fed5caedd2e540d62e5b1c25e8c82431b9e577c33537e5fa4aa909539 \ - --hash=sha256:d772afdb22555f0c58cfc741bdae44180122b3616faa1ecadb595cd526e4c993 \ - --hash=sha256:d897e81f8d0cbd2abb82226d1860ad2e1ab3ff16d7b08c96ca00df9d45409ef4 \ - --hash=sha256:de0a37f21d0d364954ad5de1970491d7fbd0fb1ef7417d4d56a36dc01ba0c0a0 \ - --hash=sha256:e7745312efa9e11c17fbd3cb3097262d079da26930ae9ae7ba28fb738367cbad \ - --hash=sha256:ed46f17096e28fb28d2975834836a639af7278aa87c84f68ab08fbe5b8bd75fa \ - --hash=sha256:f4f7c956b5215d949a1f65334cf9d7612dde38f20a95f2315deef167def91a6f \ - --hash=sha256:f50979824bde13d32b4320eedd513431c921102796d86be3eee0b58e58a3ecd1 \ - --hash=sha256:f904c24bdeabd4298f7a977ef14ca2a022ca921ed670b92ecd16ab6f3d01f867 - # via feast (pyproject.toml) -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -809,23 +797,23 @@ partd==1.4.2 \ --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c # via dask -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy prometheus-client==0.24.1 \ --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 # via feast (pyproject.toml) -protobuf==7.34.0 \ - --hash=sha256:3871a3df67c710aaf7bb8d214cc997342e63ceebd940c8c7fc65c9b3d697591a \ - --hash=sha256:4a72a8ec94e7a9f7ef7fe818ed26d073305f347f8b3b5ba31e22f81fd85fca02 \ - --hash=sha256:8e329966799f2c271d5e05e236459fe1cbfdb8755aaa3b0914fa60947ddea408 \ - --hash=sha256:964cf977e07f479c0697964e83deda72bcbc75c3badab506fb061b352d991b01 \ - --hash=sha256:9d7a5005fb96f3c1e64f397f91500b0eb371b28da81296ae73a6b08a5b76cdd6 \ - --hash=sha256:9f9079f1dde4e32342ecbd1c118d76367090d4aaa19da78230c38101c5b3dd40 \ - --hash=sha256:e3b914dd77fa33fa06ab2baa97937746ab25695f389869afdf03e81f34e45dc7 \ - --hash=sha256:f791ec509707a1d91bd02e07df157e75e4fb9fbdad12a81b7396201ec244e2e3 +protobuf==7.35.0 \ + --hash=sha256:4c4617b83ade0e279d1d2bfe04025a1adb87f9ed657de038620dc0ff959357f6 \ + --hash=sha256:4cbf5cc286130e06a6c9bbefac442431173906dfcc979712183d4adcc01b37ee \ + --hash=sha256:66be6c513931c794fa92c080ffee41671390da3d79da219cf9c0c0907f035dda \ + --hash=sha256:6c0f98f10c8a05ea30f8993dfef2de093d27b490fdae78bb60c8343795d55011 \ + --hash=sha256:a2efd84605f41e559f1881b0912b44099d0a2ac9bf46b3474823f10fb393b0e6 \ + --hash=sha256:c13f325cf242bad135c350629eeb5d54b24228eb472fb3e2e9ebbd4c5dc20ca0 \ + --hash=sha256:f05bcadf9a2a6b8dda047007075135fb7d08c73d9177aabc067e1be46881a201 \ + --hash=sha256:fcbe42a4ac09d3ec9c987ddfcd956afd0b15f1ff613bd8371bde9405ffd5c8e5 # via feast (pyproject.toml) psutil==7.2.2 \ --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ @@ -850,196 +838,195 @@ psutil==7.2.2 \ --hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \ --hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8 # via feast (pyproject.toml) -pyarrow==23.0.1 \ - --hash=sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07 \ - --hash=sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0 \ - --hash=sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350 \ - --hash=sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb \ - --hash=sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d \ - --hash=sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9 \ - --hash=sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1 \ - --hash=sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500 \ - --hash=sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5 \ - --hash=sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701 \ - --hash=sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c \ - --hash=sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56 \ - --hash=sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7 \ - --hash=sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1 \ - --hash=sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce \ - --hash=sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730 \ - --hash=sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d \ - --hash=sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2 \ - --hash=sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca \ - --hash=sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f \ - --hash=sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8 \ - --hash=sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb \ - --hash=sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125 \ - --hash=sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677 \ - --hash=sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f \ - --hash=sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7 \ - --hash=sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05 \ - --hash=sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9 \ - --hash=sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f \ - --hash=sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2 \ - --hash=sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37 \ - --hash=sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690 \ - --hash=sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8 \ - --hash=sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814 \ - --hash=sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019 \ - --hash=sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67 \ - --hash=sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83 \ - --hash=sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886 \ - --hash=sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2 \ - --hash=sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41 \ - --hash=sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a \ - --hash=sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258 \ - --hash=sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78 \ - --hash=sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5 \ - --hash=sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d \ - --hash=sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222 \ - --hash=sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919 \ - --hash=sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f \ - --hash=sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1 \ - --hash=sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd +pyarrow==24.0.0 \ + --hash=sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba \ + --hash=sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68 \ + --hash=sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868 \ + --hash=sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495 \ + --hash=sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e \ + --hash=sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66 \ + --hash=sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275 \ + --hash=sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3 \ + --hash=sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838 \ + --hash=sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491 \ + --hash=sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6 \ + --hash=sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826 \ + --hash=sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a \ + --hash=sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981 \ + --hash=sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e \ + --hash=sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c \ + --hash=sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e \ + --hash=sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05 \ + --hash=sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b \ + --hash=sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb \ + --hash=sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136 \ + --hash=sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810 \ + --hash=sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37 \ + --hash=sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147 \ + --hash=sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0 \ + --hash=sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b \ + --hash=sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb \ + --hash=sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f \ + --hash=sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83 \ + --hash=sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca \ + --hash=sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931 \ + --hash=sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d \ + --hash=sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2 \ + --hash=sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795 \ + --hash=sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26 \ + --hash=sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74 \ + --hash=sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c \ + --hash=sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57 \ + --hash=sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1 \ + --hash=sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591 \ + --hash=sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19 \ + --hash=sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42 \ + --hash=sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde \ + --hash=sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699 \ + --hash=sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041 \ + --hash=sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91 \ + --hash=sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76 \ + --hash=sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b \ + --hash=sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a \ + --hash=sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072 # via # feast (pyproject.toml) # dask -pydantic==2.12.5 \ - --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ - --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d +pydantic==2.13.4 \ + --hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \ + --hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6 # via # feast (pyproject.toml) # fastapi -pydantic-core==2.41.5 \ - --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ - --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ - --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ - --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ - --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ - --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ - --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ - --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ - --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ - --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ - --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ - --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ - --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ - --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ - --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ - --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ - --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ - --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ - --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ - --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ - --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ - --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ - --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ - --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ - --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ - --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ - --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ - --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ - --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ - --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ - --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ - --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ - --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ - --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ - --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ - --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ - --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ - --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ - --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ - --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ - --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ - --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ - --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ - --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ - --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ - --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ - --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ - --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ - --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ - --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ - --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ - --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ - --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ - --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ - --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ - --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ - --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ - --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ - --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ - --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ - --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ - --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ - --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ - --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ - --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ - --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ - --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ - --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ - --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ - --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ - --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ - --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ - --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ - --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ - --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ - --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ - --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ - --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ - --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ - --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ - --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ - --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ - --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ - --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ - --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ - --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ - --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ - --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ - --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ - --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ - --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ - --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ - --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ - --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ - --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ - --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ - --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ - --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ - --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ - --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ - --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ - --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ - --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ - --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ - --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ - --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ - --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ - --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ - --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ - --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ - --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ - --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ - --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ - --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ - --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ - --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ - --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ - --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ - --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ - --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ - --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 +pydantic-core==2.46.4 \ + --hash=sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0 \ + --hash=sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262 \ + --hash=sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda \ + --hash=sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0 \ + --hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \ + --hash=sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b \ + --hash=sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594 \ + --hash=sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29 \ + --hash=sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2 \ + --hash=sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c \ + --hash=sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d \ + --hash=sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398 \ + --hash=sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d \ + --hash=sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3 \ + --hash=sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f \ + --hash=sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb \ + --hash=sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7 \ + --hash=sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5 \ + --hash=sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9 \ + --hash=sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462 \ + --hash=sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4 \ + --hash=sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b \ + --hash=sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d \ + --hash=sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df \ + --hash=sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2 \ + --hash=sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0 \ + --hash=sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519 \ + --hash=sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd \ + --hash=sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7 \ + --hash=sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac \ + --hash=sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6 \ + --hash=sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565 \ + --hash=sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898 \ + --hash=sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb \ + --hash=sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928 \ + --hash=sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6 \ + --hash=sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3 \ + --hash=sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a \ + --hash=sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596 \ + --hash=sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987 \ + --hash=sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e \ + --hash=sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d \ + --hash=sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712 \ + --hash=sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008 \ + --hash=sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd \ + --hash=sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1 \ + --hash=sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be \ + --hash=sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea \ + --hash=sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292 \ + --hash=sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33 \ + --hash=sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3 \ + --hash=sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4 \ + --hash=sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b \ + --hash=sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826 \ + --hash=sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac \ + --hash=sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7 \ + --hash=sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d \ + --hash=sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf \ + --hash=sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4 \ + --hash=sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc \ + --hash=sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15 \ + --hash=sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3 \ + --hash=sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b \ + --hash=sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914 \ + --hash=sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04 \ + --hash=sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c \ + --hash=sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b \ + --hash=sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9 \ + --hash=sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce \ + --hash=sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4 \ + --hash=sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a \ + --hash=sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f \ + --hash=sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424 \ + --hash=sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894 \ + --hash=sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9 \ + --hash=sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76 \ + --hash=sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201 \ + --hash=sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb \ + --hash=sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109 \ + --hash=sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4 \ + --hash=sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848 \ + --hash=sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526 \ + --hash=sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0 \ + --hash=sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01 \ + --hash=sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458 \ + --hash=sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e \ + --hash=sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba \ + --hash=sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a \ + --hash=sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39 \ + --hash=sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c \ + --hash=sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000 \ + --hash=sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b \ + --hash=sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf \ + --hash=sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4 \ + --hash=sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd \ + --hash=sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28 \ + --hash=sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9 \ + --hash=sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30 \ + --hash=sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983 \ + --hash=sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1 \ + --hash=sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76 \ + --hash=sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5 \ + --hash=sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4 \ + --hash=sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7 \ + --hash=sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c \ + --hash=sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066 \ + --hash=sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3 \ + --hash=sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02 \ + --hash=sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89 \ + --hash=sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50 \ + --hash=sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76 \ + --hash=sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49 \ + --hash=sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b \ + --hash=sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d \ + --hash=sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7 \ + --hash=sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4 \ + --hash=sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c \ + --hash=sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e \ + --hash=sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff \ + --hash=sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae # via pydantic -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via feast (pyproject.toml) -pyjwt==2.11.0 \ - --hash=sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623 \ - --hash=sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 +pyjwt==2.13.0 \ + --hash=sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423 \ + --hash=sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728 # via feast (pyproject.toml) python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -1049,9 +1036,9 @@ python-dotenv==1.2.2 \ --hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \ --hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3 # via uvicorn -pytz==2026.1.post1 \ - --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ - --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +pytz==2026.2 \ + --hash=sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 \ + --hash=sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a # via pandas pyyaml==6.0.3 \ --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ @@ -1137,126 +1124,141 @@ referencing==0.37.0 \ # via # jsonschema # jsonschema-specifications -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via feast (pyproject.toml) -rpds-py==0.30.0 \ - --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ - --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ - --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ - --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ - --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ - --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ - --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ - --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ - --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ - --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ - --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ - --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ - --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ - --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ - --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ - --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ - --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ - --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ - --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ - --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ - --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ - --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ - --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ - --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ - --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ - --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ - --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ - --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ - --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ - --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ - --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ - --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ - --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ - --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ - --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ - --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ - --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ - --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ - --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ - --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ - --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ - --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ - --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ - --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ - --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ - --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ - --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ - --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ - --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ - --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ - --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ - --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ - --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ - --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ - --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ - --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ - --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ - --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ - --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ - --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ - --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ - --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ - --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ - --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ - --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ - --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ - --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ - --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ - --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ - --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ - --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ - --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ - --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ - --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ - --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ - --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ - --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ - --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ - --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ - --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ - --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ - --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ - --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ - --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ - --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ - --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ - --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ - --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ - --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ - --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ - --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ - --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ - --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ - --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ - --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ - --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ - --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ - --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ - --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ - --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ - --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ - --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ - --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ - --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ - --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ - --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ - --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ - --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ - --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ - --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ - --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ - --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ - --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ - --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ - --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 +rpds-py==2026.5.1 \ + --hash=sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead \ + --hash=sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a \ + --hash=sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4 \ + --hash=sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256 \ + --hash=sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb \ + --hash=sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b \ + --hash=sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870 \ + --hash=sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc \ + --hash=sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08 \ + --hash=sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251 \ + --hash=sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473 \ + --hash=sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b \ + --hash=sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a \ + --hash=sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131 \ + --hash=sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9 \ + --hash=sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01 \ + --hash=sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba \ + --hash=sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad \ + --hash=sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db \ + --hash=sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d \ + --hash=sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0 \ + --hash=sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63 \ + --hash=sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee \ + --hash=sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7 \ + --hash=sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b \ + --hash=sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036 \ + --hash=sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb \ + --hash=sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16 \ + --hash=sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f \ + --hash=sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d \ + --hash=sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d \ + --hash=sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5 \ + --hash=sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78 \ + --hash=sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66 \ + --hash=sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972 \ + --hash=sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd \ + --hash=sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89 \ + --hash=sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732 \ + --hash=sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02 \ + --hash=sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef \ + --hash=sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a \ + --hash=sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c \ + --hash=sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723 \ + --hash=sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda \ + --hash=sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7 \ + --hash=sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca \ + --hash=sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02 \ + --hash=sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015 \ + --hash=sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1 \ + --hash=sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed \ + --hash=sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00 \ + --hash=sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a \ + --hash=sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195 \ + --hash=sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a \ + --hash=sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa \ + --hash=sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece \ + --hash=sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df \ + --hash=sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26 \ + --hash=sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa \ + --hash=sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842 \ + --hash=sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a \ + --hash=sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c \ + --hash=sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd \ + --hash=sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a \ + --hash=sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf \ + --hash=sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2 \ + --hash=sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f \ + --hash=sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf \ + --hash=sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049 \ + --hash=sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3 \ + --hash=sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964 \ + --hash=sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291 \ + --hash=sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14 \ + --hash=sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc \ + --hash=sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47 \ + --hash=sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5 \ + --hash=sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d \ + --hash=sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb \ + --hash=sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df \ + --hash=sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a \ + --hash=sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc \ + --hash=sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc \ + --hash=sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46 \ + --hash=sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb \ + --hash=sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2 \ + --hash=sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e \ + --hash=sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb \ + --hash=sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec \ + --hash=sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325 \ + --hash=sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600 \ + --hash=sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559 \ + --hash=sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41 \ + --hash=sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644 \ + --hash=sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b \ + --hash=sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162 \ + --hash=sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83 \ + --hash=sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038 \ + --hash=sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6 \ + --hash=sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b \ + --hash=sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3 \ + --hash=sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9 \ + --hash=sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34 \ + --hash=sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6 \ + --hash=sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb \ + --hash=sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa \ + --hash=sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6 \ + --hash=sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d \ + --hash=sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24 \ + --hash=sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838 \ + --hash=sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164 \ + --hash=sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97 \ + --hash=sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4 \ + --hash=sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2 \ + --hash=sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55 \ + --hash=sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3 \ + --hash=sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2 \ + --hash=sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358 \ + --hash=sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b \ + --hash=sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8 \ + --hash=sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0 \ + --hash=sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea \ + --hash=sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081 \ + --hash=sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d \ + --hash=sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1 \ + --hash=sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81 \ + --hash=sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3 \ + --hash=sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8 \ + --hash=sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1 \ + --hash=sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0 \ + --hash=sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd # via # jsonschema # referencing @@ -1264,75 +1266,72 @@ six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 # via python-dateutil -sqlalchemy[mypy]==2.0.48 \ - --hash=sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad \ - --hash=sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e \ - --hash=sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd \ - --hash=sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6 \ - --hash=sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0 \ - --hash=sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0 \ - --hash=sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc \ - --hash=sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b \ - --hash=sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f \ - --hash=sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0 \ - --hash=sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894 \ - --hash=sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b \ - --hash=sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8 \ - --hash=sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0 \ - --hash=sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131 \ - --hash=sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b \ - --hash=sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77 \ - --hash=sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f \ - --hash=sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb \ - --hash=sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9 \ - --hash=sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c \ - --hash=sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241 \ - --hash=sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658 \ - --hash=sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7 \ - --hash=sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a \ - --hash=sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae \ - --hash=sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616 \ - --hash=sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7 \ - --hash=sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89 \ - --hash=sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3 \ - --hash=sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b \ - --hash=sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0 \ - --hash=sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2 \ - --hash=sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d \ - --hash=sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76 \ - --hash=sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565 \ - --hash=sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99 \ - --hash=sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485 \ - --hash=sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617 \ - --hash=sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a \ - --hash=sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096 \ - --hash=sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7 \ - --hash=sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed \ - --hash=sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f \ - --hash=sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099 \ - --hash=sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6 \ - --hash=sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018 \ - --hash=sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2 \ - --hash=sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67 \ - --hash=sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933 \ - --hash=sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e \ - --hash=sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b \ - --hash=sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5 \ - --hash=sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd \ - --hash=sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79 \ - --hash=sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4 \ - --hash=sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571 \ - --hash=sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c \ - --hash=sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121 \ - --hash=sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457 \ - --hash=sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e \ - --hash=sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29 \ - --hash=sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb +sqlalchemy[mypy]==2.0.50 \ + --hash=sha256:03f4323c980ad0e918cc9e5369b015f759f4e534db5bbaf4dc36832c10d05064 \ + --hash=sha256:06a9210bdc5f4298cff0781087e2ff45683922252dacc452846373a58761f093 \ + --hash=sha256:0a31c5963d58d3e3d11c5b97709e248305705de1fdf51ec3bf396674c5898b7e \ + --hash=sha256:0e104e196f457ec608eb8af736c5eb4c6bc58f481b546f485a7f9c628ee532be \ + --hash=sha256:0f5e4ac70e9e757f6b3e87c0491ff034442ecd8dfd36d041a50564c322dafc0e \ + --hash=sha256:0fe7822866f3a9fc5f3db21a290ce8961a53050115f05edf9402b6a5feb92a9f \ + --hash=sha256:0fec460e18cdbb4c7773531122ce9a27e96c6ca17af3933941d94da475ad2c86 \ + --hash=sha256:110fdac56ace278949f00de805edacbd6141e382d992f9ba28238b3a0827a600 \ + --hash=sha256:1208050441471d003b7c8cb4054fb084f185cf35ac3f0ea270803865bca9939a \ + --hash=sha256:13b85b20f9ab714a666df9d8e72e253ec33c16c7e1e375c877e5bf6367a3e917 \ + --hash=sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39 \ + --hash=sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a \ + --hash=sha256:1aa6e403663a9c43c8fef7ce4bdb4cf48bcd8d352e91deda2a99f963270bd508 \ + --hash=sha256:1c5f858fe79c9f5d8fda065c06186356acb7f8df3cd52dbd5ee3f200e4b144f5 \ + --hash=sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e \ + --hash=sha256:23ae23d8b9d344d30d0a92f06d45825024a5790f1c1dd4cf452636a50d3e58cb \ + --hash=sha256:27b7062af702c61994e8806ad87e42d0a2c879e0a8e5c61c7f69d81dabe24fdf \ + --hash=sha256:287086e67275a212c4582d166a6fb03a65ccc5551d80866270ce0dd9f34eccd3 \ + --hash=sha256:2b9dcc43afef8ac157cd92fce96985d6b8b0cfbd3df4d666f66b4d55a75d202f \ + --hash=sha256:2c1920cde9d741ba3dda9b1aa5acd8c23ea17780ccfb2252d01878d5d0d628d3 \ + --hash=sha256:2dab927761d9108550f0cf8e66ff21af56f907a0ce0a689793db615e2b55f62c \ + --hash=sha256:31648fa14460537e768a7303b078e4344d208e0d23e06867c1f376a227ed82db \ + --hash=sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70 \ + --hash=sha256:3d10700bd519573f6ce5badbabbfe7f5baea84cdf370f2cbbfb4be28dfddbf1d \ + --hash=sha256:409a8121b917116b035bedc5e532ad470c74a2d279f6c302100985b6304e9f9e \ + --hash=sha256:47b71b933e7b4ebad407c8fdfd70d2c4f08b78b3238bb30eebdd6eb32ca51b89 \ + --hash=sha256:4a8e8af330cbb3a1931d3d6c91b239fc2ef135f7dd471dfa34c575028e0b1fa8 \ + --hash=sha256:51b637a84f9fa35ae1f9017e786cb142974a25305085e1b378b3647a67f65ad3 \ + --hash=sha256:545eae198d37bcf837a10ede3684e2af32458d6f35c597c35c2de7502dc38fc4 \ + --hash=sha256:60922d6599065ddca2c6f376b9aa2f41a6b85a271725e0909490bbc50b1998a5 \ + --hash=sha256:66e374271ecb7101273f57af1a62446a953d327eec4f8089147de57c591bbacc \ + --hash=sha256:68b154b08088b4ec32bb4d2958bfbb50e57549f91a4cd3e7f928e3553ed69031 \ + --hash=sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e \ + --hash=sha256:724f3dcbe53dd0151e3cb5e7ec4ba4c620bede579caacd16275dc35ce06e8615 \ + --hash=sha256:7af6eeb84985bf840ba779018ff9424d61ff69b52e66b8789d3c8da7bf5341b2 \ + --hash=sha256:7b1ddb7b5fc60dfa9df6a487f06a143c77def47c0351849da2bcea59b244a56c \ + --hash=sha256:7e36efdcc5493f8024ec873a4ee3855bfd2de0c5b19eba16f920e9d2a0d28622 \ + --hash=sha256:83a9fce296b7e052316d8c6943237b31b9c00f58ca9c253f2d165df52637a293 \ + --hash=sha256:8b53784972ade4f8174b9aa661f31a06f8a936d2cfdd602913ff3c6dd40ae873 \ + --hash=sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8 \ + --hash=sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9 \ + --hash=sha256:9602c07b03e1449747ecb69f9998a7194a589124475788b370adce57c9e9a56e \ + --hash=sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f \ + --hash=sha256:9d1af51558029a156a70986b7df88f042b3d158d7c8d8fb5072912d4b32d89c7 \ + --hash=sha256:adc0fe7d38d8c8058f7421c25508fcbc74df38233a42aa8324409844122dce8f \ + --hash=sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9 \ + --hash=sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d \ + --hash=sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d \ + --hash=sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52 \ + --hash=sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51 \ + --hash=sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0 \ + --hash=sha256:e195687f1af431c9515416288373b323b6eb599f774409814e89e9d603a56e39 \ + --hash=sha256:e6e814658818fd165e749e3d8490ef16cc7f379a118c37ada8b0589ffbaaac22 \ + --hash=sha256:e8e1b0f6a4dcd9b4839e2320afb5df37a6981cbc20ff9c423ae11c5537bdbd21 \ + --hash=sha256:ea1a8a2db4b2217d456c8d7a873bfc605f06fe3584d315264ea18c2a17585d0b \ + --hash=sha256:eefd9a03cc0047b14153872d228499d048bd7deaf926109c9ec25b15157b8e23 \ + --hash=sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086 \ + --hash=sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb # via feast (pyproject.toml) -starlette==0.52.1 \ - --hash=sha256:0029d43eb3d273bc4f83a08720b4912ea4b071087a3b48db01b7c839f7954d74 \ - --hash=sha256:834edd1b0a23167694292e94f597773bc3f89f362be6effee198165a35d62933 - # via fastapi +starlette==1.2.1 \ + --hash=sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89 \ + --hash=sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6 + # via + # feast (pyproject.toml) + # fastapi tabulate==0.10.0 \ --hash=sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d \ --hash=sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 @@ -1351,13 +1350,13 @@ toolz==1.1.0 \ # via # dask # partd -tqdm==4.67.3 \ - --hash=sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb \ - --hash=sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf +tqdm==4.68.0 \ + --hash=sha256:b79a3ae57db4c870a55352e43abb33b329557cd75b1483028909286ff22a2c03 \ + --hash=sha256:c627124266fe7904cabb70e88a940d75a06b889a0b11680307a67c18ce094f19 # via feast (pyproject.toml) -typeguard==4.5.1 \ - --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ - --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 +typeguard==4.5.2 \ + --hash=sha256:5a16dcac23502039299c97c8941651bc33d7ea8cc4b2f7d6bbb1b528f6eea423 \ + --hash=sha256:fcf9de18bd945cdb4c7b996e12b4c51ce83f92f191314a6d7cf1739586ec98cf # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -1379,13 +1378,13 @@ typing-inspection==0.4.2 \ # via # fastapi # pydantic -tzdata==2025.3 \ - --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ - --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 +tzdata==2026.2 \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 # via pandas -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via requests uvicorn[standard]==0.34.0 \ --hash=sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4 \ @@ -1448,116 +1447,114 @@ uvloop==0.22.1 \ --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 # via uvicorn -watchfiles==1.1.1 \ - --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ - --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ - --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ - --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ - --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ - --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ - --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ - --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ - --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ - --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ - --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ - --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ - --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ - --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ - --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ - --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ - --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ - --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ - --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ - --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ - --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ - --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ - --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ - --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ - --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ - --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ - --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ - --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ - --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ - --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ - --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ - --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ - --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ - --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ - --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ - --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ - --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ - --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ - --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ - --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ - --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ - --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ - --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ - --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ - --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ - --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ - --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ - --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ - --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ - --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ - --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ - --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ - --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ - --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ - --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ - --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ - --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ - --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ - --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ - --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ - --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ - --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ - --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ - --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ - --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ - --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ - --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ - --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ - --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ - --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ - --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ - --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ - --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ - --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ - --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ - --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ - --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ - --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ - --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ - --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ - --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ - --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ - --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ - --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ - --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ - --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ - --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ - --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ - --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ - --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ - --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ - --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ - --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ - --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ - --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ - --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ - --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ - --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ - --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ - --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ - --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ - --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ - --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ - --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ - --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ - --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ - --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ - --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ - --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf +watchfiles==1.2.0 \ + --hash=sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9 \ + --hash=sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98 \ + --hash=sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551 \ + --hash=sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d \ + --hash=sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7 \ + --hash=sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db \ + --hash=sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69 \ + --hash=sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242 \ + --hash=sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925 \ + --hash=sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f \ + --hash=sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5 \ + --hash=sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5 \ + --hash=sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427 \ + --hash=sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19 \ + --hash=sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4 \ + --hash=sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e \ + --hash=sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa \ + --hash=sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba \ + --hash=sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df \ + --hash=sha256:2581a94056e55d7d0a31a823ea92bf73749c489ca2285bfdc0fbe6b2bb49d50c \ + --hash=sha256:2995c176de7692b86a2e4c58d9ec718f753150a979cb4a754e2b4ffa38e70906 \ + --hash=sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65 \ + --hash=sha256:2cb93af48550faf1cea04c303107c8b75833de7013e57ce27d3b8d21d8d0f58c \ + --hash=sha256:2d95ddc1eb6914154253d239089900813f6a767e174b8e6a50e7fdacb7e4236c \ + --hash=sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30 \ + --hash=sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077 \ + --hash=sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374 \ + --hash=sha256:41bc1199f7523b3f82843c88cbb979180c949caef0342cf90968f178e5d49b01 \ + --hash=sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33 \ + --hash=sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831 \ + --hash=sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9 \ + --hash=sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2 \ + --hash=sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b \ + --hash=sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f \ + --hash=sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658 \ + --hash=sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579 \ + --hash=sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5 \ + --hash=sha256:56d8641cf834c2836922899105bd3ce3d0dfc69291d52edf0b4d0436829b34c0 \ + --hash=sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7 \ + --hash=sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666 \ + --hash=sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5 \ + --hash=sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201 \ + --hash=sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103 \ + --hash=sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6 \ + --hash=sha256:7571e4464cb6e434958f867f7f730b8ab0b75e3f8e5eac0499168486ab3c33a8 \ + --hash=sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1 \ + --hash=sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631 \ + --hash=sha256:7a2cffd17d27d2ecbb310c2b1d8174f222a5495b1a721894afa88ec11e25b898 \ + --hash=sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d \ + --hash=sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44 \ + --hash=sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2 \ + --hash=sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5 \ + --hash=sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a \ + --hash=sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1 \ + --hash=sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b \ + --hash=sha256:8f70d8b291ef6e88d19b1f297a6905ddb978888d9272b0d05e6f53309856bcfc \ + --hash=sha256:8fa585ede612ee9f9e91b18bebf9ba11b9ae29a4e3a0d0cf6fca3e382133f0d5 \ + --hash=sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377 \ + --hash=sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8 \ + --hash=sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add \ + --hash=sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281 \ + --hash=sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9 \ + --hash=sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994 \ + --hash=sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0 \ + --hash=sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e \ + --hash=sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0 \ + --hash=sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28 \ + --hash=sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7 \ + --hash=sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55 \ + --hash=sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb \ + --hash=sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07 \ + --hash=sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb \ + --hash=sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4 \ + --hash=sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0 \ + --hash=sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e \ + --hash=sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4 \ + --hash=sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9 \ + --hash=sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06 \ + --hash=sha256:bc13eb17538be00c874699dc0abe4ee2bc8d50bb1166a6b9e175ef3fd7eb8f26 \ + --hash=sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7 \ + --hash=sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4 \ + --hash=sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3 \ + --hash=sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3 \ + --hash=sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838 \ + --hash=sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71 \ + --hash=sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488 \ + --hash=sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717 \ + --hash=sha256:d20029a60a71a052a24c4db7673bc4de39ab89adbaccbfb5d67987c5d73f424d \ + --hash=sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44 \ + --hash=sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2 \ + --hash=sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b \ + --hash=sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2 \ + --hash=sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22 \ + --hash=sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6 \ + --hash=sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e \ + --hash=sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310 \ + --hash=sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165 \ + --hash=sha256:e53a384f76b631c3ae5334ce6a52f0baa3a911eb94a4eac7f160079868b716d5 \ + --hash=sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799 \ + --hash=sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8 \ + --hash=sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7 \ + --hash=sha256:f155b3a1b2a5fc89cdc70d47ee5d54e3b75e88efa34982028a35daef9ba00379 \ + --hash=sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925 \ + --hash=sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72 \ + --hash=sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4 \ + --hash=sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08 \ + --hash=sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4 # via uvicorn websockets==16.0 \ --hash=sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c \ diff --git a/sdk/python/tests/benchmarks/test_bigquery_partition_pruning_benchmark.py b/sdk/python/tests/benchmarks/test_bigquery_partition_pruning_benchmark.py new file mode 100644 index 00000000000..00123e79664 --- /dev/null +++ b/sdk/python/tests/benchmarks/test_bigquery_partition_pruning_benchmark.py @@ -0,0 +1,135 @@ +import os +from datetime import datetime, timedelta, timezone +from unittest.mock import Mock, patch + +import pytest + +from feast.infra.offline_stores.bigquery import ( + BigQueryOfflineStore, + BigQueryOfflineStoreConfig, +) +from feast.infra.offline_stores.bigquery_source import BigQuerySource +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.repo_config import RepoConfig + +__doc__ = """ +Environment variables: + FEAST_BQ_BENCH_PROJECT: BigQuery project to run dry-run queries in + FEAST_BQ_BENCH_TABLE: BigQuery table in Feast format: project:dataset.table + FEAST_BQ_BENCH_TIMESTAMP_FIELD: event timestamp column name used by Feast + FEAST_BQ_BENCH_PARTITION_COLUMN: partition column to prune (e.g. _PARTITIONDATE) + FEAST_BQ_BENCH_LOCATION: optional BigQuery location + FEAST_BQ_BENCH_START: optional ISO datetime (e.g. 2026-01-01T00:00:00+00:00) + FEAST_BQ_BENCH_END: optional ISO datetime + FEAST_BQ_BENCH_REQUIRE_REDUCTION: if truthy, requires strict byte reduction +""" + + +def _required_env(name: str) -> str: + val = os.environ.get(name) + if not val: + pytest.skip(f"Missing env var {name}") + return val + + +def _optional_iso_datetime(name: str) -> datetime | None: + val = os.environ.get(name) + if not val: + return None + return datetime.fromisoformat(val.replace("Z", "+00:00")) + + +def _estimate_bytes_processed(project: str, location: str | None, sql: str) -> int: + try: + from google.cloud import bigquery + except Exception as e: + pytest.skip(str(e)) + client = bigquery.Client(project=project, location=location) + job_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False) + job = client.query(sql, job_config=job_config) + return int(job.total_bytes_processed or 0) + + +@pytest.mark.benchmark(group="bigquery_partition_pruning") +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_bigquery_partition_pruning_bytes_processed( + mock_get_bigquery_client, benchmark +): + mock_get_bigquery_client.return_value = Mock() + + project = _required_env("FEAST_BQ_BENCH_PROJECT") + table = _required_env("FEAST_BQ_BENCH_TABLE") + timestamp_field = _required_env("FEAST_BQ_BENCH_TIMESTAMP_FIELD") + partition_column = _required_env("FEAST_BQ_BENCH_PARTITION_COLUMN") + location = os.environ.get("FEAST_BQ_BENCH_LOCATION") + + end = _optional_iso_datetime("FEAST_BQ_BENCH_END") + if end is None: + end = datetime.now(tz=timezone.utc).replace(microsecond=0) + start = _optional_iso_datetime("FEAST_BQ_BENCH_START") + if start is None: + start = end - timedelta(days=7) + + repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="bench", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + + source_without_partition = BigQuerySource( + table=table, + timestamp_field=timestamp_field, + ) + source_with_partition = BigQuerySource( + table=table, + timestamp_field=timestamp_field, + date_partition_column=partition_column, + ) + + job_without = BigQueryOfflineStore.pull_all_from_table_or_query( + config=repo_config, + data_source=source_without_partition, + join_key_columns=[], + feature_name_columns=[], + timestamp_field=timestamp_field, + start_date=start, + end_date=end, + ) + job_with = BigQueryOfflineStore.pull_all_from_table_or_query( + config=repo_config, + data_source=source_with_partition, + join_key_columns=[], + feature_name_columns=[], + timestamp_field=timestamp_field, + start_date=start, + end_date=end, + ) + + sql_without = job_without.to_sql() + sql_with = job_with.to_sql() + + def measure(): + bytes_without = _estimate_bytes_processed(project, location, sql_without) + bytes_with = _estimate_bytes_processed(project, location, sql_with) + return bytes_without, bytes_with + + bytes_without, bytes_with = benchmark(measure) + benchmark.extra_info["total_bytes_processed_without_partition_filter"] = ( + bytes_without + ) + benchmark.extra_info["total_bytes_processed_with_partition_filter"] = bytes_with + if bytes_without > 0: + benchmark.extra_info["bytes_ratio_with_over_without"] = ( + bytes_with / bytes_without + ) + + if os.environ.get("FEAST_BQ_BENCH_REQUIRE_REDUCTION", "").lower() in ( + "1", + "true", + "yes", + ): + assert bytes_with < bytes_without + else: + assert bytes_with <= bytes_without diff --git a/sdk/python/tests/component/ray/test_compute.py b/sdk/python/tests/component/ray/test_compute.py index 87a86b983e0..84735e87bee 100644 --- a/sdk/python/tests/component/ray/test_compute.py +++ b/sdk/python/tests/component/ray/test_compute.py @@ -1,3 +1,4 @@ +import tempfile from datetime import timedelta from typing import cast from unittest.mock import MagicMock @@ -19,11 +20,15 @@ from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( RayOfflineStore, ) +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + RaySource, +) from feast.transformation.ray_transformation import RayTransformation from feast.types import Float32, Int32, Int64 from tests.component.ray.ray_shared_utils import ( driver, now, + today, ) @@ -329,3 +334,318 @@ def tqdm_builder(length): assert len(ray_materialize_jobs) == 1 assert ray_materialize_jobs[0].status() == MaterializationJobStatus.SUCCEEDED + + +# --------------------------------------------------------------------------- +# RaySource integration tests — pull_latest and pull_all time-range filtering +# --------------------------------------------------------------------------- + + +def _write_ray_source_parquet(tmp_dir: str) -> str: + """Write a small driver-stats parquet with 4 rows (2 per entity) and return path.""" + yesterday = today - timedelta(days=1) + last_week = today - timedelta(days=7) + two_weeks_ago = today - timedelta(days=14) + + df = pd.DataFrame( + [ + # driver 1001 — two rows within the last 10 days + { + "driver_id": 1001, + "event_timestamp": yesterday, + "created": now, + "conv_rate": 0.8, + "acc_rate": 0.5, + "avg_daily_trips": 15, + }, + { + "driver_id": 1001, + "event_timestamp": last_week, + "created": now, + "conv_rate": 0.75, + "acc_rate": 0.9, + "avg_daily_trips": 14, + }, + # driver 1002 — recent row inside window, old row outside + { + "driver_id": 1002, + "event_timestamp": yesterday, + "created": now, + "conv_rate": 0.7, + "acc_rate": 0.4, + "avg_daily_trips": 12, + }, + { + "driver_id": 1002, + "event_timestamp": two_weeks_ago, + "created": now, + "conv_rate": 0.3, + "acc_rate": 0.6, + "avg_daily_trips": 11, + }, + ] + ) + path = f"{tmp_dir}/ray_source_features.parquet" + df.to_parquet(path, index=False) + return path + + +@pytest.mark.integration +@pytest.mark.xdist_group(name="ray") +def test_pull_latest_from_ray_source_filters_and_deduplicates(ray_environment): + """pull_latest_from_table_or_query with RaySource must: + + 1. Respect the start_date/end_date window — the row for driver 1002 at + two_weeks_ago falls outside the 10-day window and must be excluded. + 2. Deduplicate to the single latest row per entity — driver 1001 has two + rows inside the window; only the most recent (yesterday) must survive. + """ + with tempfile.TemporaryDirectory() as tmp_dir: + parquet_path = _write_ray_source_parquet(tmp_dir) + + source = RaySource( + name="driver_stats_ray", + reader_type="parquet", + path=parquet_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + start = now - timedelta(days=10) + end = now + + job = RayOfflineStore.pull_latest_from_table_or_query( + config=ray_environment.config, + data_source=source, + join_key_columns=["driver_id"], + feature_name_columns=["conv_rate", "acc_rate", "avg_daily_trips"], + timestamp_field="event_timestamp", + created_timestamp_column="created", + start_date=start, + end_date=end, + ) + + df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + # Exactly one row per entity + assert df["driver_id"].to_list() == [1001, 1002], ( + f"Expected [1001, 1002], got {df['driver_id'].to_list()}" + ) + + # driver 1001: latest row is yesterday (conv_rate=0.8) + assert abs(df.loc[df["driver_id"] == 1001, "conv_rate"].iloc[0] - 0.8) < 1e-5 + + # driver 1002: the two_weeks_ago row is outside the window; only yesterday survives + assert abs(df.loc[df["driver_id"] == 1002, "conv_rate"].iloc[0] - 0.7) < 1e-5 + + +@pytest.mark.integration +@pytest.mark.xdist_group(name="ray") +def test_pull_all_from_ray_source_filters_by_time_range(ray_environment): + """pull_all_from_table_or_query with RaySource must return all rows within + the time window without deduplication. + + - driver 1001: both rows (yesterday, last_week) are inside the 10-day window → 2 rows + - driver 1002: yesterday is inside, two_weeks_ago is outside → 1 row + - Total: 3 rows + """ + with tempfile.TemporaryDirectory() as tmp_dir: + parquet_path = _write_ray_source_parquet(tmp_dir) + + source = RaySource( + name="driver_stats_ray_all", + reader_type="parquet", + path=parquet_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + start = now - timedelta(days=10) + end = now + + job = RayOfflineStore.pull_all_from_table_or_query( + config=ray_environment.config, + data_source=source, + join_key_columns=["driver_id"], + feature_name_columns=["conv_rate", "acc_rate", "avg_daily_trips"], + timestamp_field="event_timestamp", + created_timestamp_column="created", + start_date=start, + end_date=end, + ) + + df = ( + job.to_df() + .sort_values(["driver_id", "event_timestamp"]) + .reset_index(drop=True) + ) + + # 3 rows: both for 1001, one for 1002 (the 14-day-old row is outside window) + assert len(df) == 3, ( + f"Expected 3 rows, got {len(df)}: " + f"{df[['driver_id', 'event_timestamp']].to_dict('records')}" + ) + assert sorted(df["driver_id"].to_list()) == [1001, 1001, 1002] + + +@pytest.mark.integration +@pytest.mark.xdist_group(name="ray") +def test_get_historical_features_with_ray_source(ray_environment): + """engine.get_historical_features() with a BatchFeatureView backed by RaySource. + + This exercises the DAG execution path (RayFeatureBuilder → RayReadNode → + _resolve_source_dataset) rather than pull_latest_from_table_or_query, which + is a distinct code path from the two pull_* tests above. Asserting on + returned feature values confirms the full read pipeline is correct, not just + that execution succeeded. + + Expected results with entity_df timestamp = today and TTL = 10 days: + - driver 1001: latest row is yesterday → conv_rate ≈ 0.8 + - driver 1002: latest row is yesterday → conv_rate ≈ 0.7 + (the two_weeks_ago row is outside the TTL window and must be excluded) + """ + with tempfile.TemporaryDirectory() as tmp_dir: + parquet_path = _write_ray_source_parquet(tmp_dir) + + source = RaySource( + name="driver_stats_ray_hist", + reader_type="parquet", + path=parquet_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + fs = ray_environment.feature_store + registry = fs.registry + + driver_stats_fv = BatchFeatureView( + name="driver_hourly_stats_ray_source", + entities=[driver], + mode="pandas", + ttl=timedelta(days=10), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + Field(name="driver_id", dtype=Int32), + ], + online=False, + offline=False, + source=source, + ) + + fs.apply([driver, driver_stats_fv]) + + entity_df = pd.DataFrame( + [ + {"driver_id": 1001, "event_timestamp": today}, + {"driver_id": 1002, "event_timestamp": today}, + ] + ) + + task = HistoricalRetrievalTask( + project=ray_environment.project, + entity_df=entity_df, + feature_view=driver_stats_fv, + full_feature_name=False, + registry=registry, + ) + + engine = RayComputeEngine( + repo_config=ray_environment.config, + offline_store=RayOfflineStore(), + online_store=MagicMock(), + ) + + job = engine.get_historical_features(registry, task) + df_out = ( + cast(RayDAGRetrievalJob, job) + .to_ray_dataset() + .to_pandas() + .sort_values("driver_id") + .reset_index(drop=True) + ) + + assert df_out["driver_id"].to_list() == [1001, 1002] + assert ( + abs(df_out.loc[df_out["driver_id"] == 1001, "conv_rate"].iloc[0] - 0.8) + < 1e-5 + ) + assert ( + abs(df_out.loc[df_out["driver_id"] == 1002, "conv_rate"].iloc[0] - 0.7) + < 1e-5 + ) + + +@pytest.mark.integration +@pytest.mark.xdist_group(name="ray") +def test_pull_latest_from_ray_sql_source_filters_and_deduplicates(ray_environment): + """pull_latest_from_table_or_query with RaySource(reader_type="sql") using + a local SQLite database. + + SQLite requires no external server, making it CI-safe. This exercises the + non-file-backed RaySource path where data is loaded by read_sql and then + filtered/deduplicated by _load_and_filter_dataset_ray(pre_loaded_ds=...). + """ + pytest.importorskip("sqlalchemy", reason="sqlalchemy required for SQL reader") + + import sqlite3 + + with tempfile.TemporaryDirectory() as tmp_dir: + db_path = f"{tmp_dir}/driver_stats.db" + yesterday = today - timedelta(days=1) + last_week = today - timedelta(days=7) + two_weeks_ago = today - timedelta(days=14) + + conn = sqlite3.connect(db_path) + conn.execute( + "CREATE TABLE driver_stats " + "(driver_id INTEGER, event_timestamp TEXT, created TEXT, " + "conv_rate REAL, acc_rate REAL, avg_daily_trips INTEGER)" + ) + conn.executemany( + "INSERT INTO driver_stats VALUES (?,?,?,?,?,?)", + [ + (1001, yesterday.isoformat(), now.isoformat(), 0.8, 0.5, 15), + (1001, last_week.isoformat(), now.isoformat(), 0.75, 0.9, 14), + (1002, yesterday.isoformat(), now.isoformat(), 0.7, 0.4, 12), + (1002, two_weeks_ago.isoformat(), now.isoformat(), 0.3, 0.6, 11), + ], + ) + conn.commit() + conn.close() + + source = RaySource( + name="driver_stats_sql", + reader_type="sql", + timestamp_field="event_timestamp", + reader_options={ + "sql": "SELECT * FROM driver_stats", + "connection_url": f"sqlite:///{db_path}", + }, + ) + + start = now - timedelta(days=10) + end = now + + job = RayOfflineStore.pull_latest_from_table_or_query( + config=ray_environment.config, + data_source=source, + join_key_columns=["driver_id"], + feature_name_columns=["conv_rate", "acc_rate", "avg_daily_trips"], + timestamp_field="event_timestamp", + created_timestamp_column=None, + start_date=start, + end_date=end, + ) + + df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + # One row per entity, within the window + assert df["driver_id"].to_list() == [1001, 1002], ( + f"Expected [1001, 1002], got {df['driver_id'].to_list()}" + ) + + # Latest for each: 1001→yesterday (0.8), 1002→yesterday (0.7) + assert abs(df.loc[df["driver_id"] == 1001, "conv_rate"].iloc[0] - 0.8) < 1e-5 + assert abs(df.loc[df["driver_id"] == 1002, "conv_rate"].iloc[0] - 0.7) < 1e-5 diff --git a/sdk/python/tests/component/ray/test_nodes.py b/sdk/python/tests/component/ray/test_nodes.py index 0da4fcb956e..983b40a5ccc 100644 --- a/sdk/python/tests/component/ray/test_nodes.py +++ b/sdk/python/tests/component/ray/test_nodes.py @@ -299,6 +299,146 @@ def test_ray_dedup_node( assert "driver_id" in result_df.columns +def test_ray_dedup_node_materialization_within_block( + ray_session, ray_config, mock_context, column_info +): + """Materialization path: within-block duplicates are removed and the row + with the latest event_timestamp is kept. + + is_materialization=True uses per-block map_batches (streaming-safe). + No ds.schema() call should be triggered. + """ + now = datetime.now() + older_ts = now - timedelta(hours=3) + newer_ts = now - timedelta(hours=1) + + block = pd.DataFrame( + [ + { + "driver_id": 1001, + "event_timestamp": older_ts, + "conv_rate": 0.5, + }, + { + "driver_id": 1001, + "event_timestamp": newer_ts, + "conv_rate": 0.8, + }, + { + "driver_id": 1002, + "event_timestamp": now - timedelta(hours=2), + "conv_rate": 0.7, + }, + ] + ) + + ray_dataset = ray.data.from_pandas(block) + input_value = DAGValue(data=ray_dataset, format=DAGFormat.RAY) + dummy_node = DummyInputNode("input_node", input_value) + node = RayDedupNode( + name="dedup", + column_info=column_info, + config=ray_config, + is_materialization=True, + ) + node.add_input(dummy_node) + mock_context.node_outputs = {"input_node": input_value} + + result = node.execute(mock_context) + result_df = result.data.to_pandas().sort_values("driver_id").reset_index(drop=True) + + assert len(result_df) == 2, "One row per entity should survive within the block" + driver_1001 = result_df[result_df["driver_id"] == 1001].iloc[0] + assert driver_1001["event_timestamp"] == newer_ts, ( + "Latest timestamp should be kept for driver 1001" + ) + + +def test_ray_dedup_node_materialization_cross_block_duplicates_survive( + ray_session, ray_config, mock_context, column_info +): + """Materialization path: the same entity in two *different* blocks both + survive — cross-block dedup is delegated to the online-store UPSERT. + + This validates the per-block (streaming-safe) semantics: a global shuffle + is intentionally avoided so that slow upstream actors (EasyOCR, CLIP, etc.) + do not need to finish all blocks before writes begin. + """ + now = datetime.now() + block_a = pd.DataFrame( + [ + { + "driver_id": 1001, + "event_timestamp": now - timedelta(hours=3), + "conv_rate": 0.5, + } + ] + ) + block_b = pd.DataFrame( + [ + { + "driver_id": 1001, + "event_timestamp": now - timedelta(hours=1), + "conv_rate": 0.8, + } + ] + ) + + # Force two separate Ray blocks by passing a list of DataFrames. + ray_dataset = ray.data.from_pandas([block_a, block_b]) + input_value = DAGValue(data=ray_dataset, format=DAGFormat.RAY) + dummy_node = DummyInputNode("input_node", input_value) + node = RayDedupNode( + name="dedup", + column_info=column_info, + config=ray_config, + is_materialization=True, + ) + node.add_input(dummy_node) + mock_context.node_outputs = {"input_node": input_value} + + result = node.execute(mock_context) + result_df = result.data.to_pandas() + + assert len(result_df) == 2, ( + "Both blocks should each contribute one row; " + "cross-block dedup is the online store's responsibility" + ) + + +def test_ray_dedup_node_materialization_no_join_keys( + ray_session, ray_config, mock_context, sample_data +): + """Materialization path: when no join keys are present all rows pass through + unchanged (there is nothing to deduplicate on). + """ + empty_column_info = ColumnInfo( + join_keys=[], + feature_cols=["conv_rate", "acc_rate", "avg_daily_trips"], + ts_col="event_timestamp", + created_ts_col="created", + field_mapping=None, + ) + ray_dataset = ray.data.from_pandas(sample_data) + input_value = DAGValue(data=ray_dataset, format=DAGFormat.RAY) + dummy_node = DummyInputNode("input_node", input_value) + node = RayDedupNode( + name="dedup", + column_info=empty_column_info, + config=ray_config, + is_materialization=True, + ) + node.add_input(dummy_node) + mock_context.node_outputs = {"input_node": input_value} + + result = node.execute(mock_context) + result_df = result.data.to_pandas() + + assert len(result_df) == len(sample_data), ( + "All rows should survive when there are no join keys to deduplicate on" + ) + + def test_ray_config_validation(): """Test Ray configuration validation.""" # Test valid configuration diff --git a/sdk/python/tests/component/ray/test_ray_source.py b/sdk/python/tests/component/ray/test_ray_source.py new file mode 100644 index 00000000000..1ded06e5f04 --- /dev/null +++ b/sdk/python/tests/component/ray/test_ray_source.py @@ -0,0 +1,407 @@ +"""Unit tests for RaySource, load_ray_dataset_from_source, and to_ray_dataset. + +These tests run without a live Ray cluster using mocks and lightweight +in-process data, so they are fast and suitable for CI. + +Coverage: + - RaySource construction, validation, and proto round-trip + - load_ray_dataset_from_source reader dispatch (mocked ray_wrapper) + - RetrievalJob.to_ray_dataset() base-class Arrow fallback + - pull_latest_from_table_or_query time-range filtering for RaySource +""" + +from datetime import datetime +from unittest.mock import MagicMock, patch + +import pandas as pd +import pyarrow as pa +import pytest + +from feast.infra.offline_stores.contrib.ray_offline_store.ray_source import ( + SUPPORTED_READER_TYPES, + RaySource, +) + +# --------------------------------------------------------------------------- +# RaySource — construction and attribute access +# --------------------------------------------------------------------------- + + +class TestRaySourceConstruction: + def test_huggingface_source(self): + src = RaySource( + name="hf", + reader_type="huggingface", + reader_options={"dataset_name": "my/dataset", "split": "train"}, + ) + assert src.reader_type == "huggingface" + assert src.reader_options["dataset_name"] == "my/dataset" + assert src.path == "" + + def test_parquet_source(self): + src = RaySource( + name="parq", + reader_type="parquet", + path="s3://bucket/data.parquet", + ) + assert src.reader_type == "parquet" + assert src.path == "s3://bucket/data.parquet" + assert src.reader_options == {} + + def test_all_supported_reader_types_are_accepted(self): + for rt in SUPPORTED_READER_TYPES: + src = RaySource(name=f"src_{rt}", reader_type=rt, path="/tmp/x") + assert src.reader_type == rt + + def test_unsupported_reader_type_raises(self): + with pytest.raises(ValueError, match="reader_type"): + RaySource(name="bad", reader_type="unsupported_format") + + def test_timestamp_field_default(self): + src = RaySource(name="s", reader_type="csv", path="/tmp/f.csv") + assert src.get_table_column_names_and_types(MagicMock()) == [] + + +# --------------------------------------------------------------------------- +# RaySource — proto round-trip +# --------------------------------------------------------------------------- + + +class TestRaySourceProto: + def test_round_trip_preserves_reader_type_and_path(self): + original = RaySource( + name="proto_test", + reader_type="json", + path="gs://bucket/data.jsonl", + reader_options={"lines": True}, + ) + proto = original.to_proto() + restored = RaySource.from_proto(proto) + assert restored.reader_type == original.reader_type + assert restored.path == original.path + assert restored.reader_options == original.reader_options + + def test_round_trip_huggingface(self): + original = RaySource( + name="hf_proto", + reader_type="huggingface", + reader_options={"dataset_name": "foo/bar", "split": "train[:10]"}, + ) + restored = RaySource.from_proto(original.to_proto()) + assert restored.reader_options["dataset_name"] == "foo/bar" + assert restored.reader_options["split"] == "train[:10]" + + +# --------------------------------------------------------------------------- +# load_ray_dataset_from_source — reader dispatch (mocked wrapper) +# --------------------------------------------------------------------------- + + +class TestLoadRayDatasetFromSource: + """Each reader type is dispatched to the right ray_wrapper method.""" + + def _mock_wrapper(self): + w = MagicMock() + w.read_parquet.return_value = "parquet_ds" + w.read_csv.return_value = "csv_ds" + w.read_json.return_value = "json_ds" + w.read_text.return_value = "text_ds" + w.read_images.return_value = "images_ds" + w.read_binary_files.return_value = "binary_ds" + w.read_tfrecords.return_value = "tfrecords_ds" + w.read_webdataset.return_value = "webdataset_ds" + w.from_huggingface.return_value = "hf_ds" + w.read_mongo.return_value = "mongo_ds" + w.read_sql.return_value = "sql_ds" + return w + + @pytest.mark.parametrize( + "reader_type,path,expected", + [ + ("parquet", "s3://b/data.parquet", "parquet_ds"), + ("csv", "/tmp/data.csv", "csv_ds"), + ("json", "/tmp/data.json", "json_ds"), + ("text", "/tmp/data.txt", "text_ds"), + ("images", "/tmp/imgs/", "images_ds"), + ("binary_files", "/tmp/bin/", "binary_ds"), + ("tfrecords", "/tmp/data.tfrecord", "tfrecords_ds"), + ("webdataset", "/tmp/data.tar", "webdataset_ds"), + ], + ) + def test_file_readers_dispatch(self, reader_type, path, expected): + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + + src = RaySource(name="s", reader_type=reader_type, path=path) + mock_wrapper = self._mock_wrapper() + with patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader.get_ray_wrapper", + return_value=mock_wrapper, + ): + result = load_ray_dataset_from_source(src) + assert result == expected + + def test_huggingface_dispatch(self): + import sys + + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + + src = RaySource( + name="hf", + reader_type="huggingface", + reader_options={"dataset_name": "org/ds", "split": "train"}, + ) + mock_wrapper = self._mock_wrapper() + mock_hf_dataset = MagicMock() + + # Inject a fake `datasets` module so `from datasets import load_dataset` + # inside load_ray_dataset_from_source succeeds without the real package. + fake_datasets = MagicMock() + fake_datasets.load_dataset.return_value = mock_hf_dataset + + with ( + patch.dict(sys.modules, {"datasets": fake_datasets}), + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader.get_ray_wrapper", + return_value=mock_wrapper, + ), + ): + load_ray_dataset_from_source(src) + + mock_wrapper.from_huggingface.assert_called_once() + + def test_unknown_reader_type_raises(self): + from feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader import ( + load_ray_dataset_from_source, + ) + + # Bypass RaySource construction-time validation by patching the + # underlying RaySourceOptions directly (reader_type is a read-only + # property on RaySource that delegates to ray_source_options). + src = RaySource(name="s", reader_type="parquet", path="/x") + src.ray_source_options.reader_type = "not_a_thing" + mock_wrapper = self._mock_wrapper() + with patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader.get_ray_wrapper", + return_value=mock_wrapper, + ): + with pytest.raises(ValueError, match="Unknown reader_type"): + load_ray_dataset_from_source(src) + + +# --------------------------------------------------------------------------- +# RetrievalJob.to_ray_dataset() — base-class Arrow fallback +# --------------------------------------------------------------------------- + + +class TestRetrievalJobToRayDataset: + """The base-class default converts via to_arrow() → ray.data.from_arrow().""" + + def _make_job(self, arrow_table: pa.Table): + """Create a minimal concrete RetrievalJob whose _to_arrow_internal returns arrow_table.""" + from feast.infra.offline_stores.offline_store import RetrievalJob + + class _ConcreteJob(RetrievalJob): + @property + def full_feature_names(self): + return False + + @property + def on_demand_feature_views(self): + return [] + + def _to_df_internal(self, timeout=None): + return arrow_table.to_pandas() + + def _to_arrow_internal(self, timeout=None): + return arrow_table + + return _ConcreteJob() + + def test_returns_ray_dataset_with_correct_rows(self): + pytest.importorskip("ray") + table = pa.table({"a": [1, 2, 3], "b": ["x", "y", "z"]}) + job = self._make_job(table) + ds = job.to_ray_dataset() + assert ds.count() == 3 + + def test_import_error_without_ray(self): + import sys + + table = pa.table({"a": [1]}) + job = self._make_job(table) + with patch.dict(sys.modules, {"ray": None, "ray.data": None}): + with pytest.raises(ImportError, match="Ray is required"): + job.to_ray_dataset() + + def test_ray_retrieval_job_overrides_base(self): + """RayRetrievalJob.to_ray_dataset() must not call the Arrow fallback.""" + from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( + RayRetrievalJob, + ) + from feast.infra.offline_stores.offline_store import RetrievalJob + + base_impl = RetrievalJob.to_ray_dataset + ray_impl = RayRetrievalJob.__dict__.get("to_ray_dataset") + assert ray_impl is not None, ( + "RayRetrievalJob must define its own to_ray_dataset" + ) + assert ray_impl is not base_impl + + +# --------------------------------------------------------------------------- +# get_historical_features().to_ray_dataset() +# --------------------------------------------------------------------------- + + +class TestGetHistoricalFeaturesToRayDataset: + """Callers chain get_historical_features().to_ray_dataset() directly. + + FeatureStore has no separate to_ray_dataset() wrapper; to_ray_dataset() is + a first-class method on the RetrievalJob returned by get_historical_features(). + """ + + def test_chain_calls_to_ray_dataset_on_job(self): + mock_job = MagicMock() + sentinel = object() + mock_job.to_ray_dataset.return_value = sentinel + + store = MagicMock() + store.get_historical_features.return_value = mock_job + + entity_df = pd.DataFrame( + {"driver_id": [1], "event_timestamp": [datetime.now()]} + ) + result = store.get_historical_features( + features=["driver_stats:conv_rate"], + entity_df=entity_df, + ).to_ray_dataset() + + mock_job.to_ray_dataset.assert_called_once() + assert result is sentinel + + +# --------------------------------------------------------------------------- +# pull_latest_from_table_or_query — RaySource time-range filter and dedup +# --------------------------------------------------------------------------- + + +class TestPullLatestRaySourceFiltering: + """Verify that pull_latest_from_table_or_query applies time-range filtering + and deduplication for file-backed RaySource (e.g. reader_type="parquet"). + + RaySource without a timestamp_field (exotic sources such as HuggingFace + image datasets) must still be returned raw. + """ + + def _make_source(self, reader_type: str = "parquet") -> RaySource: + return RaySource( + name="test_src", + reader_type=reader_type, + path="s3://bucket/data.parquet", + timestamp_field="event_timestamp", + ) + + def test_load_and_filter_dataset_ray_pre_loaded(self): + """_load_and_filter_dataset_ray(pre_loaded_ds=...) must not raise and + must apply the shared field-mapping / normalise / batch pipeline.""" + from datetime import timezone + + from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( + RayOfflineStore, + ) + + start = datetime(2024, 1, 2, tzinfo=timezone.utc) + end = datetime(2024, 1, 4, tzinfo=timezone.utc) + + rows = pa.table( + { + "driver_id": [1, 1, 1], + "event_timestamp": pa.array( + [ + datetime(2024, 1, 1, tzinfo=timezone.utc), # before window + datetime(2024, 1, 3, tzinfo=timezone.utc), # inside window + datetime(2024, 1, 5, tzinfo=timezone.utc), # after window + ], + type=pa.timestamp("us", tz="UTC"), + ), + "feature_a": [10, 20, 30], + } + ) + + src = self._make_source() + + with ( + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray.normalize_timestamp_columns" + ) as mock_norm, + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray.apply_field_mapping" + ) as mock_map, + ): + import ray.data as rd + + mock_ds = rd.from_arrow(rows) + mock_norm.return_value = mock_ds + mock_map.return_value = mock_ds + + # We call the static method directly; it should not raise. + # Full integration (filter + sort) is verified in component tests. + store = RayOfflineStore() + _ = store._load_and_filter_dataset_ray( + None, + src, + join_key_columns=["driver_id"], + feature_name_columns=["feature_a"], + timestamp_field="event_timestamp", + created_timestamp_column=None, + start_date=start, + end_date=end, + pre_loaded_ds=mock_ds, + ) + + def test_pull_latest_raw_for_source_without_timestamp(self): + """When timestamp_field is empty, RaySource data must be returned raw.""" + src = RaySource( + name="hf_src", + reader_type="huggingface", + reader_options={"dataset_name": "cheques_sample_data"}, + ) + + raw_sentinel = object() + + with ( + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray.RayOfflineStore._init_ray" + ), + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray_offline_store_reader.load_ray_dataset_from_source", + return_value=raw_sentinel, + ), + patch( + "feast.infra.offline_stores.contrib.ray_offline_store.ray.RayRetrievalJob" + ) as mock_job_cls, + ): + from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( + RayOfflineStore, + ) + + mock_config = MagicMock() + mock_config.offline_store.storage_path = "/tmp/staging" + + RayOfflineStore.pull_latest_from_table_or_query( + config=mock_config, + data_source=src, + join_key_columns=[], + feature_name_columns=["feature_a"], + timestamp_field="", + created_timestamp_column=None, + start_date=datetime(2024, 1, 1), + end_date=datetime(2024, 1, 31), + ) + + # A RayRetrievalJob must still be created (just wrapping raw data). + mock_job_cls.assert_called_once() diff --git a/sdk/python/tests/component/ray/test_resource_scheduling.py b/sdk/python/tests/component/ray/test_resource_scheduling.py new file mode 100644 index 00000000000..7e26b72203a --- /dev/null +++ b/sdk/python/tests/component/ray/test_resource_scheduling.py @@ -0,0 +1,621 @@ +""" +Tests for GPU and worker resource scheduling support in the Ray compute engine +and offline store. + +Covers: +- RayComputeEngineConfig / RayOfflineStoreConfig: worker_task_options + num_gpus fields +- CodeFlareRayWrapper._get_task_options(): merge logic, num_gpus precedence +- RemoteDatasetProxy.map_batches: .options() applied, map_batches key filtering +- RayTransformationNode: worker_task_options threaded through map_batches +- RayResourceManager: GPU count read from cluster resources +- safe_batch_processor / _is_empty_batch: format-aware empty detection (regression + for AttributeError when gpu_batch_format is "numpy" or "pyarrow") +""" + +from datetime import datetime, timedelta +from unittest.mock import patch + +import numpy as np +import pandas as pd +import pyarrow as pa +import pytest +import ray + +from feast.infra.compute_engines.dag.model import DAGFormat +from feast.infra.compute_engines.dag.node import DAGNode +from feast.infra.compute_engines.dag.value import DAGValue +from feast.infra.compute_engines.ray.config import RayComputeEngineConfig +from feast.infra.compute_engines.ray.nodes import RayTransformationNode +from feast.infra.compute_engines.ray.utils import _is_empty_batch, safe_batch_processor +from feast.infra.offline_stores.contrib.ray_offline_store.ray import ( + RayOfflineStoreConfig, + RayResourceManager, +) +from feast.infra.ray_initializer import CodeFlareRayWrapper +from feast.infra.ray_shared_utils import RemoteDatasetProxy + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +class DummyInputNode(DAGNode): + def __init__(self, name, output): + super().__init__(name) + self._output = output + + def execute(self, context): + return self._output + + +@pytest.fixture(scope="module") +def ray_session(): + if not ray.is_initialized(): + ray.init(num_cpus=2, ignore_reinit_error=True, include_dashboard=False) + yield ray + ray.shutdown() + + +@pytest.fixture +def sample_df(): + return pd.DataFrame( + { + "driver_id": [1, 2, 3], + "conv_rate": [0.8, 0.7, 0.6], + "event_timestamp": [datetime.now() - timedelta(hours=i) for i in range(3)], + } + ) + + +# --------------------------------------------------------------------------- +# Config field tests +# --------------------------------------------------------------------------- + + +class TestRayComputeEngineConfigTaskOptions: + def test_defaults(self): + config = RayComputeEngineConfig() + assert config.num_gpus is None + assert config.gpu_batch_format == "pandas" + assert config.worker_task_options is None + + def test_num_gpus_set(self): + config = RayComputeEngineConfig(num_gpus=1) + assert config.num_gpus == 1 + + def test_fractional_num_gpus(self): + config = RayComputeEngineConfig(num_gpus=0.5) + assert config.num_gpus == 0.5 + + def test_gpu_batch_format(self): + config = RayComputeEngineConfig(num_gpus=1, gpu_batch_format="numpy") + assert config.gpu_batch_format == "numpy" + + def test_worker_task_options_roundtrip(self): + opts = { + "num_cpus": 4, + "memory": 8 * 1024**3, + "accelerator_type": "A100", + "max_retries": 5, + } + config = RayComputeEngineConfig(worker_task_options=opts) + assert config.worker_task_options["accelerator_type"] == "A100" + assert config.worker_task_options["num_cpus"] == 4 + assert config.worker_task_options["max_retries"] == 5 + + def test_worker_task_options_with_runtime_env(self): + config = RayComputeEngineConfig( + worker_task_options={ + "runtime_env": { + "pip": ["cudf-cu12==24.10.0"], + "env_vars": {"CUDA_VISIBLE_DEVICES": "0"}, + } + } + ) + assert config.worker_task_options["runtime_env"]["pip"] == [ + "cudf-cu12==24.10.0" + ] + + +class TestRayOfflineStoreConfigTaskOptions: + def test_defaults(self): + config = RayOfflineStoreConfig() + assert config.num_gpus is None + assert config.gpu_batch_format == "pandas" + assert config.worker_task_options is None + + def test_worker_task_options_roundtrip(self): + config = RayOfflineStoreConfig( + worker_task_options={"num_cpus": 2, "accelerator_type": "T4"} + ) + assert config.worker_task_options["num_cpus"] == 2 + assert config.worker_task_options["accelerator_type"] == "T4" + + +# --------------------------------------------------------------------------- +# CodeFlareRayWrapper._get_task_options() tests +# --------------------------------------------------------------------------- + + +class TestCodeFlareRayWrapperGetTaskOptions: + """Unit tests for _get_task_options() merge logic — no cluster connection needed.""" + + def _make_wrapper(self, num_gpus=0, worker_task_options=None): + """Construct a wrapper instance without triggering __init__ side-effects.""" + wrapper = CodeFlareRayWrapper.__new__(CodeFlareRayWrapper) + wrapper.num_gpus = num_gpus + wrapper.worker_task_options = worker_task_options or {} + return wrapper + + def test_empty_when_no_resources(self): + wrapper = self._make_wrapper() + assert wrapper._get_task_options() == {} + + def test_io_tasks_exclude_num_gpus_by_default(self): + """include_gpu defaults to False so I/O methods never consume GPU slots.""" + wrapper = self._make_wrapper(num_gpus=1) + opts = wrapper._get_task_options() # default: include_gpu=False + assert "num_gpus" not in opts + + def test_io_tasks_strip_num_gpus_from_worker_task_options(self): + """ + Regression: num_gpus set inside worker_task_options must also be stripped + for I/O tasks. Previously _get_task_options only blocked the first-class + num_gpus field; a num_gpus key already present in the copied + worker_task_options dict would leak through to .options() on I/O tasks. + """ + wrapper = self._make_wrapper( + num_gpus=0, # first-class field not set + worker_task_options={"num_gpus": 1, "num_cpus": 4}, + ) + opts = wrapper._get_task_options() # default: include_gpu=False + assert "num_gpus" not in opts + assert opts.get("num_cpus") == 4 # other keys unaffected + + def test_num_gpus_added_when_include_gpu_true(self): + """include_gpu=True is used for compute tasks that actually need GPUs.""" + wrapper = self._make_wrapper(num_gpus=1) + assert wrapper._get_task_options(include_gpu=True) == {"num_gpus": 1} + + def test_worker_task_options_passthrough(self): + wrapper = self._make_wrapper( + worker_task_options={"num_cpus": 4, "accelerator_type": "A100"} + ) + opts = wrapper._get_task_options() + assert opts["num_cpus"] == 4 + assert opts["accelerator_type"] == "A100" + + def test_num_gpus_takes_precedence_over_worker_task_options(self): + """First-class num_gpus must override worker_task_options['num_gpus'].""" + wrapper = self._make_wrapper(num_gpus=2, worker_task_options={"num_gpus": 1}) + opts = wrapper._get_task_options(include_gpu=True) + assert opts["num_gpus"] == 2 + + def test_combined_num_gpus_and_worker_task_options(self): + wrapper = self._make_wrapper( + num_gpus=1, + worker_task_options={ + "num_cpus": 4, + "memory": 8 * 1024**3, + "max_retries": 5, + }, + ) + opts = wrapper._get_task_options(include_gpu=True) + assert opts["num_gpus"] == 1 + assert opts["num_cpus"] == 4 + assert opts["memory"] == 8 * 1024**3 + assert opts["max_retries"] == 5 + + def test_zero_num_gpus_not_added(self): + """num_gpus=0 (falsy) must not be added to options.""" + wrapper = self._make_wrapper(num_gpus=0, worker_task_options={"num_cpus": 2}) + opts = wrapper._get_task_options(include_gpu=True) + assert "num_gpus" not in opts + assert opts["num_cpus"] == 2 + + +# --------------------------------------------------------------------------- +# RemoteDatasetProxy.map_batches resource key filtering +# --------------------------------------------------------------------------- + + +class TestRemoteDatasetProxyMapBatches: + """ + Verifies that map_batches applies .options() correctly and only forwards + the scheduling-relevant subset of keys into the Ray Data map_batches call. + """ + + def test_no_options_when_empty(self, ray_session, sample_df): + dataset = ray.data.from_pandas(sample_df) + proxy = RemoteDatasetProxy(ray.put(dataset)) + + with patch.object( + ray.remote(lambda d, f, b, r: d.map_batches(f, **b, **r)), + "options", + wraps=lambda **kw: None, + ): + result = proxy.map_batches(lambda b: b, batch_format="pandas") + assert isinstance(result, RemoteDatasetProxy) + + def test_map_batches_resource_keys_filtered(self): + """ + The filtering set inside map_batches must pass only scheduling-relevant + keys (num_gpus, num_cpus, accelerator_type, resources) to Ray Data's + map_batches, and strip non-scheduling keys (max_retries, runtime_env, + memory, scheduling_strategy). + """ + _MAP_BATCHES_RESOURCE_KEYS = { + "num_gpus", + "num_cpus", + "accelerator_type", + "resources", + } + + all_task_options = { + "num_gpus": 1, + "num_cpus": 4, + "accelerator_type": "A100", + "resources": {"custom": 1}, + "max_retries": 5, + "runtime_env": {"pip": ["cudf"]}, + "memory": 8 * 1024**3, + "scheduling_strategy": "SPREAD", + } + + map_resource_kwargs = { + k: v for k, v in all_task_options.items() if k in _MAP_BATCHES_RESOURCE_KEYS + } + + # Should-be-present keys + assert "num_gpus" in map_resource_kwargs + assert "num_cpus" in map_resource_kwargs + assert "accelerator_type" in map_resource_kwargs + assert "resources" in map_resource_kwargs + + # Should-be-absent keys + assert "max_retries" not in map_resource_kwargs + assert "runtime_env" not in map_resource_kwargs + assert "memory" not in map_resource_kwargs + assert "scheduling_strategy" not in map_resource_kwargs + + def test_orchestration_task_excludes_compute_keys(self): + """ + The @ray.remote orchestration wrapper must never hold compute-scheduling + resources (num_gpus, num_cpus, accelerator_type, resources). Only + non-scheduling keys (runtime_env, max_retries, memory, etc.) should + reach the orchestration task via .options(), avoiding the deadlock + where the orchestrator holds a GPU slot while waiting for data workers + that also need GPUs. + """ + _MAP_BATCHES_RESOURCE_KEYS = { + "num_gpus", + "num_cpus", + "accelerator_type", + "resources", + } + + all_opts = { + "num_gpus": 1, + "num_cpus": 4, + "accelerator_type": "A100", + "resources": {"custom": 1}, + "max_retries": 5, + "runtime_env": {"pip": ["cudf"]}, + "memory": 8 * 1024**3, + "scheduling_strategy": "SPREAD", + } + + orchestration_opts = { + k: v for k, v in all_opts.items() if k not in _MAP_BATCHES_RESOURCE_KEYS + } + + # Compute-scheduling keys must be absent from the orchestration task + assert "num_gpus" not in orchestration_opts + assert "num_cpus" not in orchestration_opts + assert "accelerator_type" not in orchestration_opts + assert "resources" not in orchestration_opts + + # Non-scheduling keys must be present (orchestration task can use them) + assert orchestration_opts["max_retries"] == 5 + assert orchestration_opts["runtime_env"] == {"pip": ["cudf"]} + assert orchestration_opts["memory"] == 8 * 1024**3 + assert orchestration_opts["scheduling_strategy"] == "SPREAD" + + +# --------------------------------------------------------------------------- +# RayTransformationNode — task_options and num_gpus threaded through +# --------------------------------------------------------------------------- + + +class TestRayTransformationNodeResourceScheduling: + @pytest.fixture + def mock_context(self): + class DummyOfflineStore: + def offline_write_batch(self, *args, **kwargs): + pass + + class Ctx: + registry = None + store = None + project = "test_project" + entity_data = None + config = None + node_outputs = {} + offline_store = DummyOfflineStore() + + return Ctx() + + def test_transformation_with_worker_task_options_executes( + self, ray_session, mock_context, sample_df + ): + """Node with worker_task_options runs end-to-end and produces correct output.""" + config = RayComputeEngineConfig( + max_workers=2, + worker_task_options={"num_cpus": 1}, + ) + dataset = ray.data.from_pandas(sample_df) + input_value = DAGValue(data=dataset, format=DAGFormat.RAY) + input_node = DummyInputNode("inp", input_value) + + def double_conv(df: pd.DataFrame) -> pd.DataFrame: + df["conv_rate"] = df["conv_rate"] * 2 + return df + + node = RayTransformationNode( + name="t", transformation=double_conv, config=config + ) + node.add_input(input_node) + mock_context.node_outputs = {"inp": input_value} + + result = node.execute(mock_context) + result_df = result.data.to_pandas() + assert len(result_df) == 3 + assert ( + abs(result_df["conv_rate"].iloc[0] - sample_df["conv_rate"].iloc[0] * 2) + < 1e-6 + ) + + def test_transformation_gpu_batch_format_applied( + self, ray_session, mock_context, sample_df + ): + """ + When num_gpus is set, gpu_batch_format is passed as batch_format and + num_gpus is included in the map_batches kwargs. + + The UDF receives a numpy dict (Dict[str, np.ndarray]) when + batch_format="numpy". safe_batch_processor must handle this without + raising AttributeError on .empty — this test is the regression guard. + """ + config = RayComputeEngineConfig( + max_workers=2, + num_gpus=1, + gpu_batch_format="numpy", + ) + dataset = ray.data.from_pandas(sample_df) + input_value = DAGValue(data=dataset, format=DAGFormat.RAY) + input_node = DummyInputNode("inp", input_value) + + # UDF receives Dict[str, np.ndarray] when batch_format="numpy" + def numpy_identity(batch): + return batch + + node = RayTransformationNode( + name="t", transformation=numpy_identity, config=config + ) + node.add_input(input_node) + mock_context.node_outputs = {"inp": input_value} + + captured_kwargs = {} + original_map_batches = ray.data.Dataset.map_batches + + def capturing_map_batches(self_ds, fn, **kwargs): + captured_kwargs.update(kwargs) + # Strip GPU-scheduling keys so local Ray (no GPU nodes, no batch_size + # requirement) can execute without raising ValueError. The correctness + # of safe_batch_processor on numpy dicts is covered by + # TestSafeBatchProcessorFormats — this test verifies config flow only. + safe_kwargs = {k: v for k, v in kwargs.items() if k not in ("num_gpus",)} + safe_kwargs.setdefault("batch_format", "pandas") + return original_map_batches(self_ds, fn, **safe_kwargs) + + with patch.object(ray.data.Dataset, "map_batches", capturing_map_batches): + node.execute(mock_context) + + assert captured_kwargs.get("batch_format") == "numpy" + assert captured_kwargs.get("num_gpus") == 1 + + def test_transformation_no_resource_keys_when_no_options( + self, ray_session, mock_context, sample_df + ): + """With no GPU/worker_task_options, map_batches only gets batch_format + concurrency.""" + config = RayComputeEngineConfig(max_workers=2) + dataset = ray.data.from_pandas(sample_df) + input_value = DAGValue(data=dataset, format=DAGFormat.RAY) + input_node = DummyInputNode("inp", input_value) + node = RayTransformationNode( + name="t", transformation=lambda df: df, config=config + ) + node.add_input(input_node) + mock_context.node_outputs = {"inp": input_value} + + captured_kwargs = {} + original_map_batches = ray.data.Dataset.map_batches + + def spy(self_ds, fn, **kwargs): + captured_kwargs.update(kwargs) + return original_map_batches(self_ds, fn, **kwargs) + + with patch.object(ray.data.Dataset, "map_batches", spy): + node.execute(mock_context) + + assert "num_gpus" not in captured_kwargs + assert "num_cpus" not in captured_kwargs + assert "accelerator_type" not in captured_kwargs + assert captured_kwargs.get("batch_format") == "pandas" + + +# --------------------------------------------------------------------------- +# RayResourceManager — GPU count from cluster resources +# --------------------------------------------------------------------------- + + +class TestRayResourceManagerGPU: + def test_reads_gpu_from_cluster_resources(self): + with ( + patch("ray.is_initialized", return_value=True), + patch( + "ray.cluster_resources", + return_value={"CPU": 8, "GPU": 4, "memory": 32 * 1024**3}, + ), + patch("ray.nodes", return_value=[{}, {}, {}, {}]), + ): + mgr = RayResourceManager() + assert mgr.available_gpus == 4 + assert mgr.available_cpus == 8 + assert mgr.num_nodes == 4 + + def test_available_gpus_zero_when_no_gpus(self): + with ( + patch("ray.is_initialized", return_value=True), + patch( + "ray.cluster_resources", + return_value={"CPU": 4, "memory": 8 * 1024**3}, + ), + patch("ray.nodes", return_value=[{}]), + ): + mgr = RayResourceManager() + assert mgr.available_gpus == 0 + + def test_available_gpus_zero_when_ray_not_initialized(self): + with patch("ray.is_initialized", return_value=False): + mgr = RayResourceManager() + assert mgr.available_gpus == 0 + + +# --------------------------------------------------------------------------- +# safe_batch_processor / _is_empty_batch — format-aware empty detection +# Regression tests for AttributeError when gpu_batch_format is "numpy"/"pyarrow" +# --------------------------------------------------------------------------- + + +class TestIsEmptyBatch: + """Unit tests for _is_empty_batch() across all Ray Data batch formats.""" + + def test_pandas_non_empty(self, sample_df): + assert _is_empty_batch(sample_df) is False + + def test_pandas_empty(self): + assert _is_empty_batch(pd.DataFrame()) is True + + def test_numpy_non_empty(self): + batch = {"col_a": np.array([1, 2, 3]), "col_b": np.array([4, 5, 6])} + assert _is_empty_batch(batch) is False + + def test_numpy_empty_arrays(self): + batch = {"col_a": np.array([]), "col_b": np.array([])} + assert _is_empty_batch(batch) is True + + def test_numpy_empty_dict(self): + assert _is_empty_batch({}) is True + + def test_pyarrow_non_empty(self, sample_df): + table = pa.Table.from_pandas(sample_df) + assert _is_empty_batch(table) is False + + def test_pyarrow_empty(self): + table = pa.table({"col_a": pa.array([], type=pa.int64())}) + assert _is_empty_batch(table) is True + + +class TestSafeBatchProcessorFormats: + """ + Regression tests: safe_batch_processor must not raise AttributeError + when receiving non-pandas batches (numpy dict or pyarrow Table). + """ + + def test_pandas_batch_passes_through(self, sample_df): + @safe_batch_processor + def double_conv(batch: pd.DataFrame) -> pd.DataFrame: + batch = batch.copy() + batch["conv_rate"] = batch["conv_rate"] * 2 + return batch + + result = double_conv(sample_df) + assert isinstance(result, pd.DataFrame) + assert result["conv_rate"].iloc[0] == pytest.approx( + sample_df["conv_rate"].iloc[0] * 2 + ) + + def test_pandas_empty_batch_returned_early(self): + called = [] + + @safe_batch_processor + def should_not_run(batch): + called.append(True) + return batch + + result = should_not_run(pd.DataFrame()) + assert called == [] + assert isinstance(result, pd.DataFrame) + + def test_numpy_batch_no_attribute_error(self): + """Regression: was raising AttributeError on batch.empty.""" + + @safe_batch_processor + def numpy_passthrough(batch): + return batch + + batch = { + "driver_id": np.array([1, 2, 3]), + "conv_rate": np.array([0.8, 0.7, 0.6]), + } + # Must not raise AttributeError + result = numpy_passthrough(batch) + assert result is batch + + def test_numpy_empty_batch_returned_early(self): + called = [] + + @safe_batch_processor + def should_not_run(batch): + called.append(True) + return batch + + empty_batch = {"col": np.array([])} + result = should_not_run(empty_batch) + assert called == [] + assert result is empty_batch + + def test_pyarrow_batch_no_attribute_error(self, sample_df): + """Regression: was raising AttributeError on batch.empty.""" + + @safe_batch_processor + def pyarrow_passthrough(batch): + return batch + + table = pa.Table.from_pandas(sample_df) + result = pyarrow_passthrough(table) + assert result is table + + def test_pyarrow_empty_batch_returned_early(self): + called = [] + + @safe_batch_processor + def should_not_run(batch): + called.append(True) + return batch + + empty_table = pa.table({"col": pa.array([], type=pa.int64())}) + result = should_not_run(empty_table) + assert called == [] + assert result is empty_table + + def test_exception_in_func_returns_original_batch(self): + @safe_batch_processor + def always_raises(batch): + raise ValueError("simulated error") + + df = pd.DataFrame({"x": [1, 2]}) + result = always_raises(df) + # Should return the original batch, not propagate + assert result is df diff --git a/sdk/python/tests/component/spark/test_spark_utils.py b/sdk/python/tests/component/spark/test_spark_utils.py new file mode 100644 index 00000000000..84a680e7a25 --- /dev/null +++ b/sdk/python/tests/component/spark/test_spark_utils.py @@ -0,0 +1,274 @@ +from unittest.mock import MagicMock, patch + +from feast.infra.compute_engines.spark.utils import _ensure_s3a_event_log_dir + +BOTO3_PATH = "feast.infra.compute_engines.spark.utils.boto3" +BOTOCONFIG_PATH = "feast.infra.compute_engines.spark.utils.BotoConfig" + + +def _base_conf(event_log_dir: str) -> dict: + return { + "spark.eventLog.enabled": "true", + "spark.eventLog.dir": event_log_dir, + "spark.hadoop.fs.s3a.endpoint": "http://minio:9000", + } + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_creates_placeholder_when_empty(mock_boto3): + """S3A prefix doesn't exist -> placeholder object is written.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 0} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/spark-events/")) + + s3.list_objects_v2.assert_called_once_with( + Bucket="my-bucket", Prefix="spark-events/", MaxKeys=1 + ) + s3.put_object.assert_called_once_with( + Bucket="my-bucket", Key="spark-events/.keep", Body=b"" + ) + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_skips_when_prefix_exists(mock_boto3): + """S3A prefix already has objects -> no placeholder written.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 3} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/spark-events/")) + + s3.put_object.assert_not_called() + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_noop_when_event_log_disabled(mock_boto3): + """spark.eventLog.enabled != true -> boto3 never called.""" + _ensure_s3a_event_log_dir( + {"spark.eventLog.enabled": "false", "spark.eventLog.dir": "s3a://b/p/"} + ) + mock_boto3.client.assert_not_called() + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_noop_for_non_s3a_path(mock_boto3): + """Non-S3A paths (hdfs://, file://, etc.) are left untouched.""" + _ensure_s3a_event_log_dir( + {"spark.eventLog.enabled": "true", "spark.eventLog.dir": "hdfs:///spark-logs"} + ) + mock_boto3.client.assert_not_called() + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_non_fatal_on_s3_error(mock_boto3): + """boto3 errors are swallowed -> SparkContext will surface its own error.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.side_effect = Exception("connection refused") + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/spark-events/")) + + +# --------------------------------------------------------------------------- +# Bucket-root edge cases (s3a://bucket, s3a://bucket/) +# --------------------------------------------------------------------------- + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_bucket_root_no_trailing_slash(mock_boto3): + """s3a://bucket (no path) -> .keep at bucket root, not /.keep.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 0} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket")) + + s3.list_objects_v2.assert_called_once_with(Bucket="my-bucket", Prefix="", MaxKeys=1) + s3.put_object.assert_called_once_with(Bucket="my-bucket", Key=".keep", Body=b"") + + +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_bucket_root_trailing_slash(mock_boto3): + """s3a://bucket/ (trailing slash, empty prefix) -> .keep at bucket root.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 0} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/")) + + s3.list_objects_v2.assert_called_once_with(Bucket="my-bucket", Prefix="", MaxKeys=1) + s3.put_object.assert_called_once_with(Bucket="my-bucket", Key=".keep", Body=b"") + + +# --------------------------------------------------------------------------- +# Credentials from spark config / env var fallback +# --------------------------------------------------------------------------- + + +@patch.dict( + "os.environ", + { + "AWS_ACCESS_KEY_ID": "env-ak", + "AWS_SECRET_ACCESS_KEY": "env-sk", # pragma: allowlist secret + "AWS_SESSION_TOKEN": "env-st", + }, +) +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_uses_spark_config_credentials(mock_boto3): + """Credentials in spark config take precedence over env vars.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + conf = { + **_base_conf("s3a://my-bucket/logs/"), + "spark.hadoop.fs.s3a.access.key": "spark-ak", + "spark.hadoop.fs.s3a.secret.key": "spark-sk", # pragma: allowlist secret + "spark.hadoop.fs.s3a.session.token": "spark-st", + } + _ensure_s3a_event_log_dir(conf) + + mock_boto3.client.assert_called_once() + kw = mock_boto3.client.call_args.kwargs + assert kw["aws_access_key_id"] == "spark-ak" + assert kw["aws_secret_access_key"] == "spark-sk" # pragma: allowlist secret + assert kw["aws_session_token"] == "spark-st" + + +@patch.dict( + "os.environ", + { + "AWS_ACCESS_KEY_ID": "env-ak", + "AWS_SECRET_ACCESS_KEY": "env-sk", # pragma: allowlist secret + "AWS_SESSION_TOKEN": "env-st", + }, +) +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_falls_back_to_env_credentials(mock_boto3): + """Without spark config keys, env vars are used.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/logs/")) + + mock_boto3.client.assert_called_once() + kw = mock_boto3.client.call_args.kwargs + assert kw["aws_access_key_id"] == "env-ak" + assert kw["aws_secret_access_key"] == "env-sk" # pragma: allowlist secret + assert kw["aws_session_token"] == "env-st" + + +@patch.dict("os.environ", {}, clear=True) +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_no_credentials_passes_none(mock_boto3): + """No credentials anywhere -> None passed to boto3 (anonymous / instance role).""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + conf = { + "spark.eventLog.enabled": "true", + "spark.eventLog.dir": "s3a://my-bucket/logs/", + } + _ensure_s3a_event_log_dir(conf) + + mock_boto3.client.assert_called_once() + kw = mock_boto3.client.call_args.kwargs + assert kw["aws_access_key_id"] is None + assert kw["aws_secret_access_key"] is None + assert kw["aws_session_token"] is None + + +# --------------------------------------------------------------------------- +# Path-style addressing (MinIO / S3-compatible) +# --------------------------------------------------------------------------- + + +@patch(BOTOCONFIG_PATH) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_path_style_when_enabled(mock_boto3, mock_config_cls): + """spark.hadoop.fs.s3a.path.style.access=true -> addressing_style='path'.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + conf = { + **_base_conf("s3a://my-bucket/logs/"), + "spark.hadoop.fs.s3a.path.style.access": "true", + } + _ensure_s3a_event_log_dir(conf) + + mock_config_cls.assert_called_once() + config_kwargs = mock_config_cls.call_args + assert config_kwargs.kwargs["s3"] == {"addressing_style": "path"} + + +@patch(BOTOCONFIG_PATH) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_virtual_hosted_style_by_default( + mock_boto3, mock_config_cls +): + """No path.style.access config -> addressing_style='auto'.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/logs/")) + + mock_config_cls.assert_called_once() + config_kwargs = mock_config_cls.call_args + assert config_kwargs.kwargs["s3"] == {"addressing_style": "auto"} + + +# --------------------------------------------------------------------------- +# Endpoint env var fallback (AWS_ENDPOINT_URL) +# --------------------------------------------------------------------------- + + +@patch.dict("os.environ", {"AWS_ENDPOINT_URL": "http://localhost:9000"}, clear=True) +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_endpoint_from_env(mock_boto3): + """AWS_ENDPOINT_URL env var is used when spark config has no endpoint.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + conf = { + "spark.eventLog.enabled": "true", + "spark.eventLog.dir": "s3a://my-bucket/logs/", + } + _ensure_s3a_event_log_dir(conf) + + mock_boto3.client.assert_called_once() + kw = mock_boto3.client.call_args.kwargs + assert kw["endpoint_url"] == "http://localhost:9000" + + +@patch.dict("os.environ", {"AWS_ENDPOINT_URL": "http://env-endpoint:9000"}, clear=True) +@patch(BOTOCONFIG_PATH, MagicMock()) +@patch(BOTO3_PATH) +def test_ensure_s3a_event_log_dir_spark_endpoint_over_env(mock_boto3): + """spark.hadoop.fs.s3a.endpoint takes precedence over AWS_ENDPOINT_URL.""" + s3 = MagicMock() + mock_boto3.client.return_value = s3 + s3.list_objects_v2.return_value = {"KeyCount": 1} + + _ensure_s3a_event_log_dir(_base_conf("s3a://my-bucket/logs/")) + + mock_boto3.client.assert_called_once() + kw = mock_boto3.client.call_args.kwargs + assert kw["endpoint_url"] == "http://minio:9000" diff --git a/sdk/python/tests/foo_provider.py b/sdk/python/tests/foo_provider.py index a04ff3cc456..82cfc7fb513 100644 --- a/sdk/python/tests/foo_provider.py +++ b/sdk/python/tests/foo_provider.py @@ -155,6 +155,7 @@ def retrieve_online_documents( query: List[float], top_k: int, distance_metric: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -174,6 +175,7 @@ def retrieve_online_documents_v2( top_k: int, distance_metric: Optional[str] = None, query_string: Optional[str] = None, + include_feature_view_version_metadata: bool = False, ) -> List[ Tuple[ Optional[datetime], @@ -206,6 +208,7 @@ def get_online_features( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: pass @@ -220,6 +223,7 @@ async def get_online_features_async( registry: BaseRegistry, project: str, full_feature_names: bool = False, + include_feature_view_version_metadata: bool = False, ) -> OnlineResponse: pass diff --git a/sdk/python/tests/unit/cli/test_cli_apply_duplicates.py b/sdk/python/tests/integration/cli/test_cli_apply_duplicates.py similarity index 99% rename from sdk/python/tests/unit/cli/test_cli_apply_duplicates.py rename to sdk/python/tests/integration/cli/test_cli_apply_duplicates.py index cf5b64dbd20..f29d07a67c1 100644 --- a/sdk/python/tests/unit/cli/test_cli_apply_duplicates.py +++ b/sdk/python/tests/integration/cli/test_cli_apply_duplicates.py @@ -2,8 +2,12 @@ from pathlib import Path from textwrap import dedent +import pytest + from tests.utils.cli_repo_creator import CliRunner, get_example_repo +pytestmark = pytest.mark.integration + def test_cli_apply_duplicated_featureview_names() -> None: run_simple_apply_test( diff --git a/sdk/python/tests/integration/conftest.py b/sdk/python/tests/integration/conftest.py index 5784ad30292..f4f70d31ec3 100644 --- a/sdk/python/tests/integration/conftest.py +++ b/sdk/python/tests/integration/conftest.py @@ -134,7 +134,7 @@ def start_keycloak_server(): @pytest.fixture(scope="session") def mysql_server(): - container = MySqlContainer("mysql:latest") + container = MySqlContainer("mysql:latest", dialect="pymysql") container.start() yield container diff --git a/sdk/python/feast/loaders/__init__.py b/sdk/python/tests/integration/doctest/__init__.py similarity index 100% rename from sdk/python/feast/loaders/__init__.py rename to sdk/python/tests/integration/doctest/__init__.py diff --git a/sdk/python/tests/doctest/test_all.py b/sdk/python/tests/integration/doctest/test_all.py similarity index 99% rename from sdk/python/tests/doctest/test_all.py rename to sdk/python/tests/integration/doctest/test_all.py index bf9e63be6e2..9620aabf55b 100644 --- a/sdk/python/tests/doctest/test_all.py +++ b/sdk/python/tests/integration/doctest/test_all.py @@ -5,9 +5,13 @@ import traceback import unittest +import pytest + import feast from feast.utils import _utc_now +pytestmark = pytest.mark.integration + FILES_TO_IGNORE = {"app"} diff --git a/sdk/python/tests/integration/local_feast_tests/__init__.py b/sdk/python/tests/integration/local_feast_tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/unit/local_feast_tests/test_e2e_local.py b/sdk/python/tests/integration/local_feast_tests/test_e2e_local.py similarity index 98% rename from sdk/python/tests/unit/local_feast_tests/test_e2e_local.py rename to sdk/python/tests/integration/local_feast_tests/test_e2e_local.py index 9019f577fc5..cee295775b1 100644 --- a/sdk/python/tests/unit/local_feast_tests/test_e2e_local.py +++ b/sdk/python/tests/integration/local_feast_tests/test_e2e_local.py @@ -18,11 +18,14 @@ from tests.utils.cli_repo_creator import CliRunner, get_example_repo from tests.utils.feature_records import validate_online_features +pytestmark = pytest.mark.integration + @pytest.mark.skipif( platform.system() == "Darwin" and os.environ.get("CI") == "true", reason="Skip on macOS CI due to Ray/uv subprocess compatibility issues", ) +@pytest.mark.timeout(600) def test_e2e_local() -> None: """ Tests the end-to-end workflow of apply, materialize, and online retrieval. diff --git a/sdk/python/tests/integration/materialization/test_snowflake.py b/sdk/python/tests/integration/materialization/test_snowflake.py index e6f600746d2..d79be84d33f 100644 --- a/sdk/python/tests/integration/materialization/test_snowflake.py +++ b/sdk/python/tests/integration/materialization/test_snowflake.py @@ -20,6 +20,11 @@ ) from tests.utils.e2e_test_validation import validate_offline_online_store_consistency +pytestmark = pytest.mark.skipif( + not os.getenv("SNOWFLAKE_CI_DEPLOYMENT"), + reason="Snowflake account not configured in CI (SNOWFLAKE_CI_DEPLOYMENT not set)", +) + SNOWFLAKE_ENGINE_CONFIG = { "type": "snowflake.engine", "account": os.getenv("SNOWFLAKE_CI_DEPLOYMENT", ""), diff --git a/sdk/python/tests/integration/monitoring/__init__.py b/sdk/python/tests/integration/monitoring/__init__.py new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/sdk/python/tests/integration/monitoring/__init__.py @@ -0,0 +1 @@ + diff --git a/sdk/python/tests/integration/monitoring/test_monitoring_integration.py b/sdk/python/tests/integration/monitoring/test_monitoring_integration.py new file mode 100644 index 00000000000..59e045bf0b5 --- /dev/null +++ b/sdk/python/tests/integration/monitoring/test_monitoring_integration.py @@ -0,0 +1,1041 @@ +"""Integration tests for the monitoring feature. + +Tests cover: +- Auto-compute (all granularities from source timestamps) +- Compute baseline (idempotent) +- Transient compute +- DQM job lifecycle +- CLI commands +- REST API endpoints +- RBAC enforcement +- Compute engine dispatch (SQL push-down vs Python fallback) +- Log source monitoring (feature serving logs) +""" + +from datetime import date, datetime, timezone +from unittest.mock import MagicMock, patch + +import pyarrow as pa +import pytest +from click.testing import CliRunner + +from feast.monitoring.monitoring_service import VALID_GRANULARITIES, MonitoringService +from feast.types import PrimitiveFeastType + +# ------------------------------------------------------------------ # +# Shared helpers +# ------------------------------------------------------------------ # + + +def _make_feature_field(name, dtype): + field = MagicMock() + field.name = name + field.dtype = dtype + return field + + +def _make_feature_view(name, features, entities=None, batch_source=None): + fv = MagicMock() + fv.name = name + fv.features = features + fv.entities = entities or [] + if batch_source is None: + batch_source = MagicMock() + batch_source.timestamp_field = "event_timestamp" + batch_source.created_timestamp_column = "" + fv.batch_source = batch_source + return fv + + +def _make_feature_service(name, fv_names, logging_config=None, feature_map=None): + """Create a mock FeatureService. + + Args: + feature_map: optional dict mapping view_name -> list of feature names. + Used to build realistic projections with features and name_to_use(). + """ + fs = MagicMock() + fs.name = name + fs.feature_view_projections = [MagicMock(name=n) for n in fv_names] + for proj, n in zip(fs.feature_view_projections, fv_names): + proj.name = n + proj.name_to_use.return_value = n + if feature_map and n in feature_map: + feats = [] + for fname in feature_map[n]: + f = MagicMock() + f.name = fname + feats.append(f) + proj.features = feats + else: + proj.features = [] + fs.logging_config = logging_config + return fs + + +def _make_logging_config_with_source(log_table_schema): + """Create a mock LoggingConfig whose destination.to_data_source() returns a DataSource.""" + logging_config = MagicMock() + mock_data_source = MagicMock() + mock_data_source.timestamp_field = "__log_timestamp" + mock_data_source.created_timestamp_column = "" + logging_config.destination.to_data_source.return_value = mock_data_source + return logging_config, mock_data_source + + +def _make_mock_store(feature_views, feature_services=None): + """Create a mock FeatureStore with offline store that uses Python fallback.""" + store = MagicMock() + store.project = "test_project" + store.config.project = "test_project" + store.config.offline_store = MagicMock() + + store.registry.list_feature_views.return_value = feature_views + store.registry.list_entities.return_value = [] + store.registry.list_feature_services.return_value = feature_services or [] + + if feature_views: + store.registry.get_feature_view.return_value = feature_views[0] + + if feature_services: + store.registry.get_feature_service.return_value = feature_services[0] + + arrow_table = pa.table( + { + "conv_rate": [0.1, 0.5, 0.9, 0.3, 0.7], + "acc_rate": [0.8, 0.6, 0.4, 0.9, 0.2], + "city": ["NYC", "LA", "NYC", "SF", "LA"], + "event_timestamp": [ + datetime(2025, 3, 25, tzinfo=timezone.utc), + datetime(2025, 3, 26, tzinfo=timezone.utc), + datetime(2025, 3, 26, tzinfo=timezone.utc), + datetime(2025, 3, 27, tzinfo=timezone.utc), + datetime(2025, 3, 27, tzinfo=timezone.utc), + ], + } + ) + + mock_retrieval = MagicMock() + mock_retrieval.to_arrow.return_value = arrow_table + + provider = MagicMock() + provider.offline_store.pull_all_from_table_or_query.return_value = mock_retrieval + provider.offline_store.compute_monitoring_metrics.side_effect = NotImplementedError + provider.offline_store.get_monitoring_max_timestamp.side_effect = ( + NotImplementedError + ) + + job_store = {} + + def _mock_save(config, metric_type, metrics): + if metric_type == "job": + for m in metrics: + job_store[m["job_id"]] = dict(m) + + def _mock_query(config, project, metric_type, filters=None, **kwargs): + if metric_type == "job": + results = list(job_store.values()) + if filters: + for key, value in filters.items(): + if value is not None: + results = [r for r in results if r.get(key) == value] + return results + return [] + + provider.offline_store.ensure_monitoring_tables.return_value = None + provider.offline_store.save_monitoring_metrics.side_effect = _mock_save + provider.offline_store.query_monitoring_metrics.side_effect = _mock_query + provider.offline_store.clear_monitoring_baseline.return_value = None + + store._get_provider.return_value = provider + + return store + + +# ------------------------------------------------------------------ # +# Test: Auto-compute +# ------------------------------------------------------------------ # + + +class TestAutoCompute: + def test_auto_compute_all_granularities(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + result = svc.auto_compute(project="test_project") + + assert result["status"] == "completed" + assert result["computed_feature_views"] == 1 + assert len(result["granularities"]) == len(VALID_GRANULARITIES) + for g in VALID_GRANULARITIES: + assert g in result["granularities"] + + provider = store._get_provider.return_value + provider.offline_store.save_monitoring_metrics.assert_called() + + def test_auto_compute_specific_view(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + result = svc.auto_compute( + project="test_project", + feature_view_name="driver_stats", + ) + + assert result["status"] == "completed" + assert result["computed_feature_views"] == 1 + + +# ------------------------------------------------------------------ # +# Test: Compute baseline +# ------------------------------------------------------------------ # + + +class TestComputeBaseline: + def test_compute_baseline_for_new_features(self): + fv = _make_feature_view( + "driver_stats", + [ + _make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64), + _make_feature_field("city", PrimitiveFeastType.STRING), + ], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + result = svc.compute_baseline(project="test_project") + + assert result["status"] == "completed" + assert result["is_baseline"] is True + assert result["computed_features"] == 2 + + provider = store._get_provider.return_value + provider.offline_store.clear_monitoring_baseline.assert_called() + provider.offline_store.save_monitoring_metrics.assert_called() + + def test_baseline_idempotent_skips_existing(self): + fv = _make_feature_view( + "driver_stats", + [ + _make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64), + _make_feature_field("acc_rate", PrimitiveFeastType.FLOAT64), + ], + ) + store = _make_mock_store([fv]) + + # Simulate conv_rate already has baseline via query_monitoring_metrics + provider = store._get_provider.return_value + existing_baseline = { + "project_id": "test_project", + "feature_view_name": "driver_stats", + "feature_name": "conv_rate", + "metric_date": "2025-01-01", + "granularity": "daily", + "data_source_type": "batch", + "computed_at": datetime.now(timezone.utc).isoformat(), + "is_baseline": True, + "feature_type": "numeric", + "row_count": 100, + "null_count": 0, + "null_rate": 0.0, + "mean": 5.0, + "stddev": 1.0, + "min_val": 0.0, + "max_val": 10.0, + "p50": 5.0, + "p75": 7.5, + "p90": 9.0, + "p95": 9.5, + "p99": 9.9, + "histogram": None, + } + + original_side_effect = ( + provider.offline_store.query_monitoring_metrics.side_effect + ) + + def _query_with_baseline(config, project, metric_type, filters=None, **kwargs): + if metric_type == "feature" and filters and filters.get("is_baseline"): + return [existing_baseline] + if original_side_effect: + return original_side_effect( + config, project, metric_type, filters=filters, **kwargs + ) + return [] + + provider.offline_store.query_monitoring_metrics.side_effect = ( + _query_with_baseline + ) + + svc = MonitoringService(store) + result = svc.compute_baseline(project="test_project") + + # Only acc_rate should be computed (conv_rate already has baseline) + assert result["computed_features"] == 1 + + +# ------------------------------------------------------------------ # +# Test: Transient compute +# ------------------------------------------------------------------ # + + +class TestTransientCompute: + def test_transient_returns_metrics_without_saving(self): + fv = _make_feature_view( + "driver_stats", + [ + _make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64), + _make_feature_field("city", PrimitiveFeastType.STRING), + ], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + result = svc.compute_transient( + project="test_project", + feature_view_name="driver_stats", + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 15), + ) + + assert result["status"] == "completed" + assert result["start_date"] == "2025-01-01" + assert result["end_date"] == "2025-01-15" + assert len(result["metrics"]) == 2 + + # Transient should NOT call save + provider = store._get_provider.return_value + provider.offline_store.save_monitoring_metrics.assert_not_called() + + def test_transient_empty_features(self): + fv = _make_feature_view( + "fv", + [_make_feature_field("ts", PrimitiveFeastType.UNIX_TIMESTAMP)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + result = svc.compute_transient( + project="test_project", + feature_view_name="fv", + ) + assert result["metrics"] == [] + + +# ------------------------------------------------------------------ # +# Test: DQM Job Manager +# ------------------------------------------------------------------ # + + +class TestDQMJobManager: + def _make_manager(self): + from feast.monitoring.dqm_job_manager import DQMJobManager + + stored = {} + + def mock_save(config, metric_type, metrics): + for m in metrics: + stored[m["job_id"]] = dict(m) + + def mock_query(config, project, metric_type, filters=None, **kwargs): + results = list(stored.values()) + if filters: + for key, value in filters.items(): + if value is not None: + results = [r for r in results if r.get(key) == value] + return results + + offline_store = MagicMock() + offline_store.save_monitoring_metrics.side_effect = mock_save + offline_store.query_monitoring_metrics.side_effect = mock_query + return DQMJobManager(offline_store, MagicMock()) + + def test_submit_and_get_job(self): + mgr = self._make_manager() + job_id = mgr.submit( + project="test_project", + job_type="auto_compute", + feature_view_name="driver_stats", + ) + + assert job_id is not None + assert len(job_id) == 36 # UUID format + + job = mgr.get_job(job_id) + assert job is not None + assert job["project_id"] == "test_project" + assert job["job_type"] == "auto_compute" + assert job["status"] == "pending" + + def test_update_status(self): + from feast.monitoring.dqm_job_manager import JOB_STATUS_RUNNING + + mgr = self._make_manager() + job_id = mgr.submit( + project="test_project", + job_type="compute", + ) + mgr.update_status(job_id, JOB_STATUS_RUNNING) + + job = mgr.get_job(job_id) + assert job["status"] == JOB_STATUS_RUNNING + assert job["started_at"] is not None + + +# ------------------------------------------------------------------ # +# Test: CLI +# ------------------------------------------------------------------ # + + +class TestComputeMetricsCLI: + def test_help(self): + from feast.cli.monitor import monitor_cmd + + runner = CliRunner() + result = runner.invoke(monitor_cmd, ["run", "--help"]) + assert result.exit_code == 0 + assert "--granularity" in result.output + assert "--set-baseline" in result.output + assert "--feature-view" in result.output + + @patch("feast.cli.monitor.create_feature_store") + @patch("feast.monitoring.monitoring_service.MonitoringService.auto_compute") + def test_run_auto_mode(self, mock_auto, mock_create_store): + from feast.cli.monitor import monitor_cmd + + mock_store = MagicMock() + mock_store.project = "proj" + mock_create_store.return_value = mock_store + + mock_auto.return_value = { + "status": "completed", + "computed_feature_views": 2, + "computed_features": 5, + "granularities": list(VALID_GRANULARITIES), + "duration_ms": 1200, + } + + runner = CliRunner() + result = runner.invoke(monitor_cmd, ["run"]) + + assert result.exit_code == 0 + assert "Auto-computing" in result.output + assert "Features computed: 5" in result.output + mock_auto.assert_called_once() + + @patch("feast.cli.monitor.create_feature_store") + @patch("feast.monitoring.monitoring_service.MonitoringService.compute_metrics") + def test_run_explicit_granularity(self, mock_compute, mock_create_store): + from feast.cli.monitor import monitor_cmd + + mock_store = MagicMock() + mock_store.project = "proj" + mock_create_store.return_value = mock_store + + mock_compute.return_value = { + "status": "completed", + "granularity": "weekly", + "computed_features": 3, + "computed_feature_views": 1, + "computed_feature_services": 1, + "metric_dates": ["2025-01-01"], + "duration_ms": 500, + } + + runner = CliRunner() + result = runner.invoke( + monitor_cmd, + [ + "run", + "--granularity", + "weekly", + "--start-date", + "2025-01-01", + "--end-date", + "2025-01-07", + ], + ) + + assert result.exit_code == 0 + assert "Granularity: weekly" in result.output + + +# ------------------------------------------------------------------ # +# Test: REST API +# ------------------------------------------------------------------ # + + +class TestRESTEndpoints: + @pytest.fixture + def app(self): + from fastapi import FastAPI + from fastapi.testclient import TestClient + + from feast.api.registry.rest.monitoring import get_monitoring_router + + mock_handler = MagicMock() + + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + mock_store = _make_mock_store([fv]) + + app = FastAPI() + app.include_router(get_monitoring_router(mock_handler, store=mock_store)) + + mock_server = MagicMock() + mock_server.store = mock_store + return TestClient(app), mock_server + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_auto_compute_endpoint(self, mock_perms, app): + client, _ = app + + response = client.post( + "/monitoring/auto_compute", + json={"project": "test_project"}, + ) + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "completed" + assert "job_id" in data + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_transient_compute_endpoint(self, mock_perms, app): + client, _ = app + + response = client.post( + "/monitoring/compute/transient", + json={ + "project": "test_project", + "feature_view_name": "driver_stats", + "start_date": "2025-01-05", + "end_date": "2025-01-20", + }, + ) + + assert response.status_code == 200 + data = response.json() + assert data["status"] == "completed" + assert len(data["metrics"]) >= 1 + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_get_metrics_with_granularity(self, mock_perms, app): + client, _ = app + + response = client.get( + "/monitoring/metrics/features", + params={"project": "test_project", "granularity": "weekly"}, + ) + + assert response.status_code == 200 + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_get_timeseries(self, mock_perms, app): + client, _ = app + + response = client.get( + "/monitoring/metrics/timeseries", + params={ + "project": "test_project", + "feature_view_name": "driver_stats", + "granularity": "daily", + }, + ) + + assert response.status_code == 200 + + +# ------------------------------------------------------------------ # +# Test: RBAC enforcement +# ------------------------------------------------------------------ # + + +class TestRBACEnforcement: + @pytest.fixture + def app(self): + from fastapi import FastAPI + from fastapi.testclient import TestClient + + from feast.api.registry.rest.monitoring import get_monitoring_router + + mock_handler = MagicMock() + + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + mock_store = _make_mock_store([fv]) + + app = FastAPI() + app.include_router(get_monitoring_router(mock_handler, store=mock_store)) + + mock_server = MagicMock() + mock_server.store = mock_store + return TestClient(app), mock_server + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_compute_requires_update(self, mock_perms, app): + client, _ = app + + from feast.permissions.action import AuthzedAction + + client.post( + "/monitoring/compute", + json={ + "project": "test_project", + "feature_view_name": "driver_stats", + }, + ) + + mock_perms.assert_called() + call_args = mock_perms.call_args + assert AuthzedAction.UPDATE in call_args.kwargs.get( + "actions", call_args[1].get("actions", []) + ) + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_transient_requires_describe(self, mock_perms, app): + client, _ = app + + from feast.permissions.action import AuthzedAction + + client.post( + "/monitoring/compute/transient", + json={ + "project": "test_project", + "feature_view_name": "driver_stats", + }, + ) + + mock_perms.assert_called() + call_args = mock_perms.call_args + assert AuthzedAction.DESCRIBE in call_args.kwargs.get( + "actions", call_args[1].get("actions", []) + ) + + @patch("feast.api.registry.rest.monitoring.assert_permissions") + def test_read_requires_describe(self, mock_perms, app): + client, _ = app + + from feast.permissions.action import AuthzedAction + + client.get( + "/monitoring/metrics/features", + params={"project": "test_project", "feature_view_name": "driver_stats"}, + ) + + mock_perms.assert_called() + call_args = mock_perms.call_args + assert AuthzedAction.DESCRIBE in call_args.kwargs.get( + "actions", call_args[1].get("actions", []) + ) + + +# ------------------------------------------------------------------ # +# Test: SQL push-down dispatch +# ------------------------------------------------------------------ # + + +class TestComputeEngineDispatch: + """Verify that MonitoringService prefers SQL push-down and falls back + to Python-based computation when the offline store doesn't support it.""" + + def _make_store_with_pushdown(self, pushdown_result): + """Create a mock store where the offline store supports push-down.""" + fv = _make_feature_view( + "driver_stats", + [ + _make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64), + _make_feature_field("city", PrimitiveFeastType.STRING), + ], + ) + store = _make_mock_store([fv]) + provider = store._get_provider.return_value + provider.offline_store.compute_monitoring_metrics.side_effect = None + provider.offline_store.compute_monitoring_metrics.return_value = pushdown_result + provider.offline_store.get_monitoring_max_timestamp.side_effect = None + provider.offline_store.get_monitoring_max_timestamp.return_value = datetime( + 2025, 3, 27, tzinfo=timezone.utc + ) + return store, fv + + def test_uses_sql_pushdown_when_available(self): + """When the offline store supports compute_monitoring_metrics, + pull_all_from_table_or_query should NOT be called.""" + sql_result = [ + { + "feature_name": "conv_rate", + "feature_type": "numeric", + "row_count": 100, + "null_count": 2, + "null_rate": 0.02, + "mean": 0.5, + "stddev": 0.2, + "min_val": 0.0, + "max_val": 1.0, + "p50": 0.5, + "p75": 0.75, + "p90": 0.9, + "p95": 0.95, + "p99": 0.99, + "histogram": { + "bins": [0.0, 0.5, 1.0], + "counts": [50, 50], + "bin_width": 0.5, + }, + }, + ] + store, _ = self._make_store_with_pushdown(sql_result) + svc = MonitoringService(store) + + result = svc.compute_transient( + project="test_project", + feature_view_name="driver_stats", + feature_names=["conv_rate"], + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 15), + ) + + assert result["status"] == "completed" + assert len(result["metrics"]) == 1 + assert result["metrics"][0]["mean"] == 0.5 + + provider = store._get_provider.return_value + provider.offline_store.compute_monitoring_metrics.assert_called_once() + provider.offline_store.pull_all_from_table_or_query.assert_not_called() + + def test_falls_back_to_python_when_not_supported(self): + """When compute_monitoring_metrics raises NotImplementedError, + the service falls back to pulling data + Python compute.""" + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + + svc = MonitoringService(store) + result = svc.compute_transient( + project="test_project", + feature_view_name="driver_stats", + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 15), + ) + + assert result["status"] == "completed" + assert len(result["metrics"]) == 1 + assert result["metrics"][0]["feature_name"] == "conv_rate" + + provider = store._get_provider.return_value + provider.offline_store.pull_all_from_table_or_query.assert_called() + + def test_auto_compute_uses_pushdown_for_max_timestamp(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + provider = store._get_provider.return_value + + provider.offline_store.get_monitoring_max_timestamp.side_effect = None + provider.offline_store.get_monitoring_max_timestamp.return_value = datetime( + 2025, 3, 27, tzinfo=timezone.utc + ) + provider.offline_store.compute_monitoring_metrics.side_effect = None + provider.offline_store.compute_monitoring_metrics.return_value = [ + { + "feature_name": "conv_rate", + "feature_type": "numeric", + "row_count": 5, + "null_count": 0, + "null_rate": 0.0, + "mean": 0.5, + "stddev": 0.2, + "min_val": 0.1, + "max_val": 0.9, + "p50": 0.5, + "p75": 0.7, + "p90": 0.9, + "p95": 0.9, + "p99": 0.9, + "histogram": None, + }, + ] + + svc = MonitoringService(store) + result = svc.auto_compute(project="test_project") + + assert result["status"] == "completed" + provider.offline_store.get_monitoring_max_timestamp.assert_called() + provider.offline_store.compute_monitoring_metrics.assert_called() + provider.offline_store.pull_all_from_table_or_query.assert_not_called() + + +# ------------------------------------------------------------------ # +# Test: Native storage dispatch +# ------------------------------------------------------------------ # + + +class TestNativeStorageDispatch: + """Verify that MonitoringService uses OfflineStore for all storage + operations (save, query, clear_baseline, ensure_tables).""" + + def test_save_goes_through_offline_store(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + svc.compute_metrics( + project="test_project", + granularity="daily", + ) + + provider = store._get_provider.return_value + provider.offline_store.ensure_monitoring_tables.assert_called() + provider.offline_store.save_monitoring_metrics.assert_called() + + save_calls = provider.offline_store.save_monitoring_metrics.call_args_list + metric_types_saved = {c[0][1] for c in save_calls} + assert "feature" in metric_types_saved + assert "feature_view" in metric_types_saved + + def test_query_goes_through_offline_store(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + svc.get_feature_metrics(project="test_project", granularity="daily") + + provider = store._get_provider.return_value + provider.offline_store.query_monitoring_metrics.assert_called() + call_args = provider.offline_store.query_monitoring_metrics.call_args + assert call_args[1]["metric_type"] == "feature" + + def test_baseline_clear_goes_through_offline_store(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + svc.compute_baseline(project="test_project") + + provider = store._get_provider.return_value + provider.offline_store.clear_monitoring_baseline.assert_called() + + def test_transient_does_not_save(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + store = _make_mock_store([fv]) + svc = MonitoringService(store) + + svc.compute_transient( + project="test_project", + feature_view_name="driver_stats", + ) + + provider = store._get_provider.return_value + provider.offline_store.save_monitoring_metrics.assert_not_called() + + +# ------------------------------------------------------------------ # +# Test: Log source monitoring +# ------------------------------------------------------------------ # + + +class TestLogSourceMonitoring: + """Verify that monitoring can compute metrics from feature serving logs.""" + + # Realistic log column names follow the {view}__{feature} convention + # produced by FeatureServiceLoggingSource.get_schema(). + _LOG_SCHEMA = pa.schema( + [ + ("driver_id", pa.int64()), + ("driver_stats__conv_rate", pa.float64()), + ("driver_stats__conv_rate__timestamp", pa.timestamp("us", tz="UTC")), + ("driver_stats__conv_rate__status", pa.int32()), + ("driver_stats__city", pa.utf8()), + ("driver_stats__city__timestamp", pa.timestamp("us", tz="UTC")), + ("driver_stats__city__status", pa.int32()), + ("__log_timestamp", pa.timestamp("us", tz="UTC")), + ("__log_date", pa.date32()), + ("__request_id", pa.utf8()), + ] + ) + + def _make_log_store(self): + """Create a mock store with a feature service that has logging configured.""" + fv = _make_feature_view( + "driver_stats", + [ + _make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64), + _make_feature_field("city", PrimitiveFeastType.STRING), + ], + ) + + logging_config, log_data_source = _make_logging_config_with_source( + self._LOG_SCHEMA + ) + + fs = _make_feature_service( + "driver_service", + ["driver_stats"], + logging_config=logging_config, + feature_map={"driver_stats": ["conv_rate", "city"]}, + ) + store = _make_mock_store([fv], feature_services=[fs]) + + log_arrow_table = pa.table( + { + "driver_stats__conv_rate": [0.1, 0.5, 0.9, 0.3, 0.7], + "driver_stats__city": ["NYC", "LA", "NYC", "SF", "LA"], + "__log_timestamp": [ + datetime(2025, 3, 25, tzinfo=timezone.utc), + datetime(2025, 3, 26, tzinfo=timezone.utc), + datetime(2025, 3, 26, tzinfo=timezone.utc), + datetime(2025, 3, 27, tzinfo=timezone.utc), + datetime(2025, 3, 27, tzinfo=timezone.utc), + ], + } + ) + + mock_log_retrieval = MagicMock() + mock_log_retrieval.to_arrow.return_value = log_arrow_table + + provider = store._get_provider.return_value + provider.offline_store.pull_all_from_table_or_query.return_value = ( + mock_log_retrieval + ) + + entity_col = MagicMock() + entity_col.name = "driver_id" + fv.entity_columns = [entity_col] + + return store, fs + + def test_compute_log_metrics(self): + store, fs = self._make_log_store() + svc = MonitoringService(store) + + with patch( + "feast.monitoring.monitoring_service.FeatureServiceLoggingSource" + ) as mock_cls: + mock_instance = MagicMock() + mock_instance.get_schema.return_value = self._LOG_SCHEMA + mock_cls.return_value = mock_instance + + result = svc.compute_log_metrics( + project="test_project", + feature_service_name="driver_service", + start_date=date(2025, 3, 25), + end_date=date(2025, 3, 27), + granularity="daily", + ) + + assert result["status"] == "completed" + assert result["data_source_type"] == "log" + assert result["computed_features"] == 2 + + provider = store._get_provider.return_value + provider.offline_store.save_monitoring_metrics.assert_called() + + save_calls = provider.offline_store.save_monitoring_metrics.call_args_list + feature_calls = [c for c in save_calls if c[0][1] == "feature"] + assert len(feature_calls) >= 1 + saved_metrics = feature_calls[0][0][2] + assert all(m["data_source_type"] == "log" for m in saved_metrics) + # Feature names normalized: driver_stats__conv_rate -> conv_rate + saved_names = {m["feature_name"] for m in saved_metrics} + assert saved_names == {"conv_rate", "city"} + # Feature view name is the actual view, not the service + assert all(m["feature_view_name"] == "driver_stats" for m in saved_metrics) + + # Feature service aggregate saved to the service table + svc_calls = [c for c in save_calls if c[0][1] == "feature_service"] + assert len(svc_calls) >= 1 + svc_metric = svc_calls[0][0][2][0] + assert svc_metric["feature_service_name"] == "driver_service" + assert svc_metric["data_source_type"] == "log" + assert svc_metric["total_features"] == 2 + + def test_compute_log_metrics_no_logging_config(self): + fv = _make_feature_view( + "driver_stats", + [_make_feature_field("conv_rate", PrimitiveFeastType.FLOAT64)], + ) + fs = _make_feature_service("no_log_service", ["driver_stats"]) + fs.logging_config = None + store = _make_mock_store([fv], feature_services=[fs]) + svc = MonitoringService(store) + + result = svc.compute_log_metrics( + project="test_project", + feature_service_name="no_log_service", + ) + + assert result["status"] == "skipped" + assert "no logging configured" in result["reason"] + + def test_auto_compute_log_metrics(self): + store, fs = self._make_log_store() + svc = MonitoringService(store) + + with patch( + "feast.monitoring.monitoring_service.FeatureServiceLoggingSource" + ) as mock_cls: + mock_instance = MagicMock() + mock_instance.get_schema.return_value = self._LOG_SCHEMA + mock_cls.return_value = mock_instance + + result = svc.auto_compute_log_metrics(project="test_project") + + assert result["status"] == "completed" + assert result["data_source_type"] == "log" + assert result["computed_feature_services"] == 1 + assert len(result["granularities"]) == len(VALID_GRANULARITIES) + + def test_log_metrics_tagged_differently_from_batch(self): + """Log metrics should have data_source_type='log', batch should have 'batch'.""" + store, fs = self._make_log_store() + svc = MonitoringService(store) + + with patch( + "feast.monitoring.monitoring_service.FeatureServiceLoggingSource" + ) as mock_cls: + mock_instance = MagicMock() + mock_instance.get_schema.return_value = self._LOG_SCHEMA + mock_cls.return_value = mock_instance + + svc.compute_log_metrics( + project="test_project", + feature_service_name="driver_service", + granularity="daily", + ) + + provider = store._get_provider.return_value + save_calls = provider.offline_store.save_monitoring_metrics.call_args_list + feature_calls = [c for c in save_calls if c[0][1] == "feature"] + for call in feature_calls: + for m in call[0][2]: + assert m["data_source_type"] == "log" + assert m["feature_view_name"] == "driver_stats" + assert m["feature_name"] in ("conv_rate", "city") diff --git a/sdk/python/tests/integration/offline_server/__init__.py b/sdk/python/tests/integration/offline_server/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/integration/offline_server/test_offline_server.py b/sdk/python/tests/integration/offline_server/test_offline_server.py new file mode 100644 index 00000000000..8069326bb43 --- /dev/null +++ b/sdk/python/tests/integration/offline_server/test_offline_server.py @@ -0,0 +1,375 @@ +import os +import tempfile +from datetime import datetime, timedelta +from unittest.mock import patch + +import assertpy +import pandas as pd +import pyarrow as pa +import pyarrow.flight as flight +import pytest + +from feast import FeatureStore, FeatureView, FileSource +from feast.errors import FeatureViewNotFoundException +from feast.feature_logging import FeatureServiceLoggingSource +from feast.infra.offline_stores.remote import ( + RemoteOfflineStore, + RemoteOfflineStoreConfig, +) +from feast.offline_server import OfflineServer, _init_auth_manager +from feast.repo_config import RepoConfig +from feast.torch_wrapper import get_torch +from tests.utils.cli_repo_creator import CliRunner + +pytestmark = pytest.mark.integration + +PROJECT_NAME = "test_remote_offline" + + +@pytest.fixture +def empty_offline_server(environment): + store = environment.feature_store + + location = "grpc+tcp://localhost:0" + _init_auth_manager(store=store) + return OfflineServer(store=store, location=location) + + +@pytest.fixture +def arrow_client(empty_offline_server): + return flight.FlightClient(f"grpc://localhost:{empty_offline_server.port}") + + +def test_offline_server_is_alive(environment, empty_offline_server, arrow_client): + server = empty_offline_server + client = arrow_client + + assertpy.assert_that(server).is_not_none() + assertpy.assert_that(server.port).is_not_equal_to(0) + + actions = list(client.list_actions()) + flights = list(client.list_flights()) + + assertpy.assert_that(actions).is_equal_to( + [ + ( + "offline_write_batch", + "Writes the specified arrow table to the data source underlying the specified feature view.", + ), + ( + "write_logged_features", + "Writes logged features to a specified destination in the offline store.", + ), + ( + "persist", + "Synchronously executes the underlying query and persists the result in the same offline store at the " + "specified destination.", + ), + ] + ) + assertpy.assert_that(flights).is_empty() + + +def default_store(temp_dir): + runner = CliRunner() + result = runner.run(["init", PROJECT_NAME], cwd=temp_dir) + repo_path = os.path.join(temp_dir, PROJECT_NAME, "feature_repo") + assert result.returncode == 0 + + result = runner.run(["--chdir", repo_path, "apply"], cwd=temp_dir) + assert result.returncode == 0 + + fs = FeatureStore(repo_path=repo_path) + return fs + + +def remote_feature_store(offline_server): + offline_config = RemoteOfflineStoreConfig( + type="remote", host="0.0.0.0", port=offline_server.port + ) + + registry_path = os.path.join( + str(offline_server.store.repo_path), + offline_server.store.config.registry.path, + ) + store = FeatureStore( + config=RepoConfig( + project=PROJECT_NAME, + registry=registry_path, + provider="local", + offline_store=offline_config, + entity_key_serialization_version=3, + # repo_config = + ) + ) + return store + + +def test_remote_offline_store_apis(): + with tempfile.TemporaryDirectory() as temp_dir: + store = default_store(str(temp_dir)) + location = "grpc+tcp://localhost:0" + + _init_auth_manager(store=store) + server = OfflineServer(store=store, location=location) + + assertpy.assert_that(server).is_not_none() + assertpy.assert_that(server.port).is_not_equal_to(0) + + fs = remote_feature_store(server) + + _test_get_historical_features_returns_data(fs) + _test_get_historical_features_to_tensor(fs) + _test_get_historical_features_returns_nan(fs) + _test_get_historical_features_to_tensor_with_nan(fs) + _test_offline_write_batch(str(temp_dir), fs) + _test_write_logged_features(str(temp_dir), fs) + _test_pull_latest_from_table_or_query(str(temp_dir), fs) + _test_pull_all_from_table_or_query(str(temp_dir), fs) + + +def test_remote_offline_store_exception_handling(): + with tempfile.TemporaryDirectory() as temp_dir: + store = default_store(str(temp_dir)) + location = "grpc+tcp://localhost:0" + + _init_auth_manager(store=store) + server = OfflineServer(store=store, location=location) + + assertpy.assert_that(server).is_not_none() + assertpy.assert_that(server.port).is_not_equal_to(0) + + fs = remote_feature_store(server) + data_file = os.path.join( + temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" + ) + data_df = pd.read_parquet(data_file) + + with pytest.raises( + FeatureViewNotFoundException, + match="Feature view test does not exist in project test_remote_offline", + ): + RemoteOfflineStore.offline_write_batch( + fs.config, + FeatureView(name="test", source=FileSource(path="test")), + pa.Table.from_pandas(data_df), + progress=None, + ) + + +def _test_get_historical_features_returns_data(fs: FeatureStore): + entity_df = pd.DataFrame.from_dict( + { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [ + datetime(2021, 4, 12, 10, 59, 42), + datetime(2021, 4, 12, 8, 12, 10), + datetime(2021, 4, 12, 16, 40, 26), + ], + "label_driver_reported_satisfaction": [1, 5, 3], + "val_to_add": [1, 2, 3], + "val_to_add_2": [10, 20, 30], + } + ) + + features = [ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + "transformed_conv_rate:conv_rate_plus_val1", + "transformed_conv_rate:conv_rate_plus_val2", + ] + + training_df = fs.get_historical_features(entity_df, features).to_df() + + assertpy.assert_that(training_df).is_not_none() + assertpy.assert_that(len(training_df)).is_equal_to(3) + + for index, driver_id in enumerate(entity_df["driver_id"]): + assertpy.assert_that(training_df["driver_id"][index]).is_equal_to(driver_id) + for feature in features: + column_id = feature.split(":")[1] + value = training_df[column_id][index] + assertpy.assert_that(value).is_not_nan() + + +def _test_get_historical_features_to_tensor(fs: FeatureStore): + entity_df = pd.DataFrame.from_dict( + { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [ + datetime(2021, 4, 12, 10, 59, 42), + datetime(2021, 4, 12, 8, 12, 10), + datetime(2021, 4, 12, 16, 40, 26), + ], + "label_driver_reported_satisfaction": [1, 5, 3], + "val_to_add": [1, 2, 3], + "val_to_add_2": [10, 20, 30], + } + ) + + features = [ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + "transformed_conv_rate:conv_rate_plus_val1", + "transformed_conv_rate:conv_rate_plus_val2", + ] + + job = fs.get_historical_features(entity_df, features) + tensor_data = job.to_tensor() + + assertpy.assert_that(tensor_data).is_not_none() + assertpy.assert_that(tensor_data["driver_id"].shape[0]).is_equal_to(3) + torch = get_torch() + for key, values in tensor_data.items(): + if isinstance(values, torch.Tensor): + assertpy.assert_that(values.shape[0]).is_equal_to(3) + for val in values: + val_float = val.item() + assertpy.assert_that(val_float).is_instance_of((float, int)) + assertpy.assert_that(val_float).is_not_nan() + + +def _test_get_historical_features_returns_nan(fs: FeatureStore): + entity_df = pd.DataFrame.from_dict( + { + "driver_id": [1, 2, 3], + "event_timestamp": [ + datetime(2021, 4, 12, 10, 59, 42), + datetime(2021, 4, 12, 8, 12, 10), + datetime(2021, 4, 12, 16, 40, 26), + ], + "label_driver_reported_satisfaction": [1, 5, 3], + "val_to_add": [1, 2, 3], + "val_to_add_2": [10, 20, 30], + } + ) + + features = [ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + "transformed_conv_rate:conv_rate_plus_val1", + "transformed_conv_rate:conv_rate_plus_val2", + ] + + training_df = fs.get_historical_features(entity_df, features).to_df() + + assertpy.assert_that(training_df).is_not_none() + assertpy.assert_that(len(training_df)).is_equal_to(3) + + for index, driver_id in enumerate(entity_df["driver_id"]): + assertpy.assert_that(training_df["driver_id"][index]).is_equal_to(driver_id) + for feature in features: + column_id = feature.split(":")[1] + value = training_df[column_id][index] + assertpy.assert_that(value).is_nan() + + +def _test_get_historical_features_to_tensor_with_nan(fs: FeatureStore): + entity_df = pd.DataFrame.from_dict( + { + "driver_id": [9991, 9992], # IDs with no matching features + "event_timestamp": [ + datetime(2021, 4, 12, 10, 59, 42), + datetime(2021, 4, 12, 10, 59, 42), + ], + } + ) + features = ["driver_hourly_stats:conv_rate"] + job = fs.get_historical_features(entity_df, features) + tensor_data = job.to_tensor() + assert "conv_rate" in tensor_data + values = tensor_data["conv_rate"] + # conv_rate is a float feature, missing values should be NaN + torch = get_torch() + for val in values: + assert isinstance(val, torch.Tensor) or torch.is_tensor(val) + assertpy.assert_that(torch.isnan(val).item()).is_true() + + +def _test_offline_write_batch(temp_dir, fs: FeatureStore): + data_file = os.path.join( + temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" + ) + data_df = pd.read_parquet(data_file) + feature_view = fs.get_feature_view("driver_hourly_stats") + + RemoteOfflineStore.offline_write_batch( + fs.config, feature_view, pa.Table.from_pandas(data_df), progress=None + ) + + +def _test_write_logged_features(temp_dir, fs: FeatureStore): + data_file = os.path.join( + temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" + ) + data_df = pd.read_parquet(data_file) + feature_service = fs.get_feature_service("driver_activity_v1") + + RemoteOfflineStore.write_logged_features( + config=fs.config, + data=pa.Table.from_pandas(data_df), + source=FeatureServiceLoggingSource(feature_service, fs.config.project), + logging_config=feature_service.logging_config, + registry=fs.registry, + ) + + +def _test_pull_latest_from_table_or_query(temp_dir, fs: FeatureStore): + data_source = fs.get_data_source("driver_hourly_stats_source") + + end_date = datetime.now().replace(microsecond=0, second=0, minute=0) + start_date = end_date - timedelta(days=15) + RemoteOfflineStore.pull_latest_from_table_or_query( + config=fs.config, + data_source=data_source, + join_key_columns=[], + feature_name_columns=[], + timestamp_field="event_timestamp", + created_timestamp_column="created", + start_date=start_date, + end_date=end_date, + ).to_df() + + +def _test_pull_all_from_table_or_query(temp_dir, fs: FeatureStore): + data_source = fs.get_data_source("driver_hourly_stats_source") + + end_date = datetime.now().replace(microsecond=0, second=0, minute=0) + start_date = end_date - timedelta(days=15) + RemoteOfflineStore.pull_all_from_table_or_query( + config=fs.config, + data_source=data_source, + join_key_columns=[], + feature_name_columns=[], + timestamp_field="event_timestamp", + start_date=start_date, + end_date=end_date, + ).to_df() + + +def test_get_feature_view_by_name_propagates_transient_errors(): + """Transient registry errors must not be swallowed and misreported as + FeatureViewNotFoundException.""" + with tempfile.TemporaryDirectory() as temp_dir: + store = default_store(str(temp_dir)) + location = "grpc+tcp://localhost:0" + + _init_auth_manager(store=store) + server = OfflineServer(store=store, location=location) + + transient_error = ConnectionError("registry temporarily unavailable") + + with patch.object( + server.store.registry, + "get_feature_view", + side_effect=transient_error, + ): + with pytest.raises(ConnectionError, match="registry temporarily"): + server.get_feature_view_by_name( + fv_name="driver_hourly_stats", + name_alias=None, + project=PROJECT_NAME, + ) diff --git a/sdk/python/tests/integration/offline_store/test_offline_write.py b/sdk/python/tests/integration/offline_store/test_offline_write.py index df60e40ed56..6ae8b68147a 100644 --- a/sdk/python/tests/integration/offline_store/test_offline_write.py +++ b/sdk/python/tests/integration/offline_store/test_offline_write.py @@ -135,6 +135,8 @@ def test_writing_consecutively_to_offline_store(environment, universal_data_sour ) store.apply([driver_entity, driver_stats]) + # Refresh registry after apply to ensure subsequent reads see the new feature view + store.refresh_registry() df = store.get_historical_features( entity_df=entity_df, features=[ diff --git a/sdk/python/tests/integration/offline_store/test_universal_historical_retrieval.py b/sdk/python/tests/integration/offline_store/test_universal_historical_retrieval.py index 757e0d72a6d..af0de479f3e 100644 --- a/sdk/python/tests/integration/offline_store/test_universal_historical_retrieval.py +++ b/sdk/python/tests/integration/offline_store/test_universal_historical_retrieval.py @@ -728,3 +728,214 @@ def test_historical_features_field_mapping( actual_df, sort_by=["driver_id"], ) + + +@pytest.mark.integration +@pytest.mark.universal_offline_stores(only=["file"]) +def test_historical_features_non_entity_retrieval(environment): + """Test get_historical_features with entity_df=None using start_date/end_date. + + This exercises the non-entity retrieval path where a synthetic entity_df is + generated internally. Regression test for the bug where start_date was used + instead of end_date for min_event_timestamp in the synthetic entity_df. + """ + store = environment.feature_store + + now = datetime.now().replace(microsecond=0, second=0, minute=0) + two_days_ago = now - timedelta(days=2) + one_day_ago = now - timedelta(days=1) + + driver_stats_df = pd.DataFrame( + data=[ + { + "driver_id": 1001, + "avg_daily_trips": 10, + "event_timestamp": two_days_ago, + "created": two_days_ago, + }, + { + "driver_id": 1001, + "avg_daily_trips": 20, + "event_timestamp": one_day_ago, + "created": one_day_ago, + }, + { + "driver_id": 1001, + "avg_daily_trips": 30, + "event_timestamp": now, + "created": now, + }, + { + "driver_id": 1002, + "avg_daily_trips": 100, + "event_timestamp": two_days_ago, + "created": two_days_ago, + }, + { + "driver_id": 1002, + "avg_daily_trips": 200, + "event_timestamp": one_day_ago, + "created": one_day_ago, + }, + { + "driver_id": 1002, + "avg_daily_trips": 300, + "event_timestamp": now, + "created": now, + }, + ] + ) + + start_date = now - timedelta(days=3) + end_date = now + timedelta(hours=1) + + driver_stats_data_source = environment.data_source_creator.create_data_source( + df=driver_stats_df, + destination_name=f"test_driver_stats_{int(time.time_ns())}_{random.randint(1000, 9999)}", + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + driver_entity = Entity(name="driver", join_keys=["driver_id"]) + driver_fv = FeatureView( + name="driver_stats", + entities=[driver_entity], + schema=[Field(name="avg_daily_trips", dtype=Int32)], + source=driver_stats_data_source, + ) + + store.apply([driver_entity, driver_fv]) + + offline_job = store.get_historical_features( + entity_df=None, + features=["driver_stats:avg_daily_trips"], + full_feature_names=False, + start_date=start_date, + end_date=end_date, + ) + + actual_df = offline_job.to_df() + + assert not actual_df.empty, "Result should not be empty" + assert "avg_daily_trips" in actual_df.columns + + actual_driver_ids = set(actual_df["driver_id"].tolist()) + assert 1001 in actual_driver_ids, "driver 1001 should be in results" + assert 1002 in actual_driver_ids, "driver 1002 should be in results" + + # Verify timestamps fall within the requested range. + # Strip tz info to avoid tz-naive vs tz-aware comparison issues. + ts_start = pd.Timestamp(start_date).tz_localize(None) + ts_end = pd.Timestamp(end_date).tz_localize(None) + for ts in actual_df["event_timestamp"]: + ts_val = pd.Timestamp(ts).tz_localize(None) + assert ts_val >= ts_start, f"Timestamp {ts_val} before start_date" + assert ts_val <= ts_end, f"Timestamp {ts_val} after end_date" + + # The latest features must be present -- this is the critical regression check. + # With the old bug (using start_date instead of end_date), the synthetic entity_df + # had wrong max_event_timestamp causing the latest rows to be missed. + actual_trips = set(actual_df["avg_daily_trips"].tolist()) + assert 30 in actual_trips, "Latest trip value 30 for driver 1001 should be present" + assert 300 in actual_trips, ( + "Latest trip value 300 for driver 1002 should be present" + ) + + +@pytest.mark.integration +@pytest.mark.universal_offline_stores +@pytest.mark.parametrize("full_feature_names", [True, False], ids=lambda v: f"full:{v}") +def test_odfv_projection(environment, universal_data_sources, full_feature_names): + """ + Test that requesting a subset of ODFV features only returns those features. + + Regression test for issue #6099: OnDemandFeatureViews should honor output + projection in offline retrieval, matching the behavior of online retrieval. + + Before the fix, offline retrieval would return ALL ODFV output features even + when only a subset was requested, while online retrieval correctly returned + only the requested features. + """ + store = environment.feature_store + + (entities, datasets, data_sources) = universal_data_sources + + feature_views = construct_universal_feature_views(data_sources) + + # Add request data needed for ODFV + entity_df_with_request_data = datasets.entity_df.copy(deep=True) + entity_df_with_request_data["val_to_add"] = [ + i for i in range(len(entity_df_with_request_data)) + ] + + store.apply([driver(), *feature_views.values()]) + + # The conv_rate_plus_100 ODFV has 3 output features: + # - conv_rate_plus_100 + # - conv_rate_plus_val_to_add + # - conv_rate_plus_100_rounded + + # Test 1: Request only ONE ODFV feature + job = store.get_historical_features( + entity_df=entity_df_with_request_data, + features=[ + "conv_rate_plus_100:conv_rate_plus_100", # Request only this one + ], + full_feature_names=full_feature_names, + ) + + actual_df = job.to_df() + + # Determine expected column names based on full_feature_names setting + expected_feature = ( + "conv_rate_plus_100__conv_rate_plus_100" + if full_feature_names + else "conv_rate_plus_100" + ) + unrequested_feature_1 = ( + "conv_rate_plus_100__conv_rate_plus_val_to_add" + if full_feature_names + else "conv_rate_plus_val_to_add" + ) + unrequested_feature_2 = ( + "conv_rate_plus_100__conv_rate_plus_100_rounded" + if full_feature_names + else "conv_rate_plus_100_rounded" + ) + + # Verify the requested feature is present + assert expected_feature in actual_df.columns, ( + f"Requested feature '{expected_feature}' should be in the result" + ) + + # Verify unrequested ODFV features are NOT present (this is the key fix) + assert unrequested_feature_1 not in actual_df.columns, ( + f"Unrequested ODFV feature '{unrequested_feature_1}' should NOT be in the result. " + f"This indicates the bug from issue #6099 still exists." + ) + assert unrequested_feature_2 not in actual_df.columns, ( + f"Unrequested ODFV feature '{unrequested_feature_2}' should NOT be in the result. " + f"This indicates the bug from issue #6099 still exists." + ) + + # Test 2: Request TWO out of THREE ODFV features + job2 = store.get_historical_features( + entity_df=entity_df_with_request_data, + features=[ + "conv_rate_plus_100:conv_rate_plus_100", + "conv_rate_plus_100:conv_rate_plus_val_to_add", + # Deliberately NOT requesting conv_rate_plus_100_rounded + ], + full_feature_names=full_feature_names, + ) + + actual_df2 = job2.to_df() + + # Verify the two requested features are present + assert expected_feature in actual_df2.columns + assert unrequested_feature_1 in actual_df2.columns + + # Verify the unrequested feature is NOT present + assert unrequested_feature_2 not in actual_df2.columns, ( + f"Unrequested ODFV feature '{unrequested_feature_2}' should NOT be in the result" + ) diff --git a/sdk/python/tests/integration/online_store/conftest.py b/sdk/python/tests/integration/online_store/conftest.py new file mode 100644 index 00000000000..42b507231dc --- /dev/null +++ b/sdk/python/tests/integration/online_store/conftest.py @@ -0,0 +1,173 @@ +""" +Fixtures for online-store integration tests. +""" + +from typing import Dict + +import pytest +from testcontainers.core.container import DockerContainer +from testcontainers.core.waiting_utils import wait_for_logs + +from tests.universal.feature_repos.universal.online_store_creator import ( + OnlineStoreCreator, +) + + +class _SharedDbDynamoDBOnlineStoreCreator(OnlineStoreCreator): + """DynamoDB Local container started with ``-sharedDb -inMemory``. + + Why ``-sharedDb`` + ----------------- + DynamoDB Local 2.x namespaces tables by the **access key ID** in the + request signature. In CI, the sync ``boto3`` client and the async + ``aiobotocore`` client can resolve credentials from *different* sources + (env vars, credential file, ``credential_process``, container IAM role, + etc.) even after ``monkeypatch.setenv`` has set fake keys—because the + credential chain is evaluated lazily and various caches may hold stale + values. + + When the two clients end up using *different* access keys, the sync + client creates tables in namespace A while the async client queries + namespace B, which is empty → ``ResourceNotFoundException``. + + ``-sharedDb`` collapses all namespaces into a single in-memory database, + making table visibility completely independent of which credentials each + client uses. This is the correct setting for integration tests that want + to verify async read/write behaviour without caring about credential + isolation. + """ + + def __init__(self, project_name: str, **kwargs): + super().__init__(project_name) + self.container = ( + DockerContainer("amazon/dynamodb-local:latest") + .with_exposed_ports("8000") + .with_command("-jar DynamoDBLocal.jar -sharedDb -inMemory") + ) + + def create_online_store(self) -> Dict[str, str]: + self.container.start() + wait_for_logs( + container=self.container, + predicate="Initializing DynamoDB Local with the following configuration:", + timeout=10, + ) + exposed_port = self.container.get_exposed_port("8000") + return { + "type": "dynamodb", + "endpoint_url": f"http://localhost:{exposed_port}", + "region": "us-west-2", + } + + def teardown(self): + self.container.stop() + + +@pytest.fixture +async def dynamodb_local_environment(monkeypatch, worker_id): + """Isolated, self-contained Environment for DynamoDB async tests. + + Root cause of the async credential failures + ------------------------------------------- + DynamoDB Local 2.x isolates tables **per access key ID**. In CI, + ``boto3`` (sync, used to provision tables via ``store.apply()``) and + ``aiobotocore`` (async, used for reads/writes in the test body) may + resolve credentials from *different* sources even when ``monkeypatch`` + has set fake static keys—the credential chain is evaluated lazily and + caches may hold stale values from a real AWS session configured in the + runner environment. + + When the two clients end up using different access key IDs they land in + different DynamoDB Local namespaces: + + * sync client → namespace ``KEY_A`` → tables exist ✓ + * async client → namespace ``KEY_B`` → tables not found → ``ResourceNotFoundException`` + + Fix: ``_SharedDbDynamoDBOnlineStoreCreator`` + -------------------------------------------- + The isolated container is started with ``-sharedDb -inMemory``. In + shared-DB mode DynamoDB Local stores *all* tables in a single namespace + regardless of the access key, so sync and async clients always see the + same tables. + + Why async + ``await fs.initialize()`` before yielding + ----------------------------------------------------- + Calling ``await fs.initialize()`` eagerly creates the ``aiobotocore`` + client inside this fixture's event loop (the *same* loop the test will + run in). This pre-caches: + + 1. ``FeatureStore._provider`` so the identical ``DynamoDBOnlineStore`` + instance is reused for the entire test. + 2. The aiobotocore client, which is now unambiguously pointed at our + isolated container's ``endpoint_url``. + + Yields + ------ + tuple[Environment, TestData] + ``(environment, (entities, datasets, data_sources))`` + """ + from feast.infra.online_stores.dynamodb import DynamoDBOnlineStore + from tests.universal.feature_repos.integration_test_repo_config import ( + IntegrationTestRepoConfig, + ) + from tests.universal.feature_repos.repo_configuration import ( + construct_test_environment, + construct_universal_test_data, + ) + from tests.universal.feature_repos.universal.data_sources.file import ( + FileDataSourceCreator, + ) + + # Set fake static credentials before any boto client is created. + # These are accepted by DynamoDB Local regardless of validity. + monkeypatch.setenv("AWS_ACCESS_KEY_ID", "fakeaccesskey000000") + monkeypatch.setenv( + "AWS_SECRET_ACCESS_KEY", "fakesecretkey0000000000000000000000000000" + ) + monkeypatch.delenv("AWS_SESSION_TOKEN", raising=False) + monkeypatch.delenv("AWS_SECURITY_TOKEN", raising=False) + # Prevent IMDS from injecting real session tokens on EC2-backed runners. + monkeypatch.setenv("AWS_EC2_METADATA_DISABLED", "true") + # Disable the container credentials provider (ECS/EKS IAM roles). + monkeypatch.delenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", raising=False) + monkeypatch.delenv("AWS_CONTAINER_CREDENTIALS_FULL_URI", raising=False) + # Ensure no profile redirects boto to a different credential source. + monkeypatch.delenv("AWS_PROFILE", raising=False) + monkeypatch.delenv("AWS_DEFAULT_PROFILE", raising=False) + + # Reset class-level boto3 client caches so that no stale client from a + # previous test in this worker bleeds into our isolated environment. + DynamoDBOnlineStore._dynamodb_client = None + DynamoDBOnlineStore._dynamodb_resource = None + + config = IntegrationTestRepoConfig( + provider="local", + offline_store_creator=FileDataSourceCreator, + online_store_creator=_SharedDbDynamoDBOnlineStoreCreator, + online_store=None, + ) + + environment = construct_test_environment( + config, + fixture_request=None, + worker_id=worker_id, + ) + environment.setup() + + # FileDataSourceCreator writes only local Parquet files — no AWS calls. + universal_test_data = construct_universal_test_data(environment) + + # Eagerly initialise the aiobotocore client in *this* event loop so it + # is guaranteed to point at our container and is reused throughout the + # test body without lazy-init surprises. + await environment.feature_store.initialize() + + yield environment, universal_test_data + + # Cleanly shut down the async client before the container disappears. + await environment.feature_store.close() + environment.teardown() + + # Flush class-level caches so the next test starts completely fresh. + DynamoDBOnlineStore._dynamodb_client = None + DynamoDBOnlineStore._dynamodb_resource = None diff --git a/sdk/python/tests/integration/online_store/test_dynamodb_versioning.py b/sdk/python/tests/integration/online_store/test_dynamodb_versioning.py new file mode 100644 index 00000000000..2575e1dbb19 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_dynamodb_versioning.py @@ -0,0 +1,194 @@ +"""Integration tests for DynamoDB online store feature view versioning. + +Run with: pytest --integration sdk/python/tests/integration/online_store/test_dynamodb_versioning.py + +Uses moto to mock the DynamoDB service (no Docker required). +""" + +import os +from datetime import datetime, timedelta, timezone + +import pytest + +from feast import Entity, FeatureView +from feast.field import Field +from feast.infra.online_stores.dynamodb import DynamoDBOnlineStore +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RegistryConfig, RepoConfig +from feast.types import Float32, Int64 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version="latest"): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + return FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + version=version, + ) + + +def _make_entity_key(driver_id: int) -> EntityKeyProto: + entity_key = EntityKeyProto() + entity_key.join_keys.append("driver_id") + val = ValueProto() + val.int64_val = driver_id + entity_key.entity_values.append(val) + return entity_key + + +def _write_and_read(store, config, fv, driver_id=1001, trips=42): + entity_key = _make_entity_key(driver_id) + val = ValueProto() + val.int64_val = trips + now = datetime.now(tz=timezone.utc) + store.online_write_batch( + config, fv, [(entity_key, {"trips_today": val}, now, now)], None + ) + return store.online_read(config, fv, [entity_key], ["trips_today"]) + + +def _make_config(enable_versioning=False): + from feast.infra.online_stores.dynamodb import DynamoDBOnlineStoreConfig + + return RepoConfig( + project="test_project", + provider="local", + online_store=DynamoDBOnlineStoreConfig( + type="dynamodb", + region="us-east-1", + ), + registry=RegistryConfig( + path="/tmp/test_dynamodb_registry.pb", + enable_online_feature_view_versioning=enable_versioning, + ), + entity_key_serialization_version=3, + ) + + +@pytest.mark.integration +class TestDynamoDBVersioningIntegration: + """Integration tests for DynamoDB versioning using moto mock.""" + + @pytest.fixture(autouse=True) + def setup_dynamodb(self): + try: + from moto import mock_dynamodb + except ImportError: + pytest.skip("moto not installed") + + # Set dummy AWS credentials for moto + os.environ["AWS_ACCESS_KEY_ID"] = "testing" + os.environ["AWS_SECRET_ACCESS_KEY"] = "testing" # noqa: S105 # pragma: allowlist secret + os.environ["AWS_SECURITY_TOKEN"] = "testing" # noqa: S105 # pragma: allowlist secret + os.environ["AWS_SESSION_TOKEN"] = "testing" # noqa: S105 # pragma: allowlist secret + os.environ["AWS_DEFAULT_REGION"] = "us-east-1" + + with mock_dynamodb(): + yield + + def test_write_read_without_versioning(self): + config = _make_config(enable_versioning=False) + store = DynamoDBOnlineStore() + fv = _make_feature_view() + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_write_read_with_versioning_v1(self): + config = _make_config(enable_versioning=True) + store = DynamoDBOnlineStore() + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_version_isolation(self): + """Data written to v1 is not visible from v2.""" + config = _make_config(enable_versioning=True) + store = DynamoDBOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=10) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_v2, [entity_key], ["trips_today"]) + assert result[0] == (None, None) + + result = store.online_read(config, fv_v1, [entity_key], ["trips_today"]) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 10 + + def test_projection_version_tag_routes_to_correct_table(self): + """projection.version_tag routes reads to the correct versioned DynamoDB table.""" + config = _make_config(enable_versioning=True) + store = DynamoDBOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=100) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + _write_and_read(store, config, fv_v2, driver_id=1001, trips=200) + + fv_read = _make_feature_view() + fv_read.projection.version_tag = 1 + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_read, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 100 + + fv_read2 = _make_feature_view() + fv_read2.projection.version_tag = 2 + result = store.online_read(config, fv_read2, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 200 + + def test_teardown_versioned_table(self): + """teardown() drops the versioned DynamoDB table without error.""" + config = _make_config(enable_versioning=True) + store = DynamoDBOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv) + + # Should not raise + store.teardown(config, [fv], []) + + def test_update_deletes_versioned_table(self): + """update() with tables_to_delete correctly drops versioned DynamoDB tables.""" + config = _make_config(enable_versioning=True) + store = DynamoDBOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv, driver_id=1001, trips=50) + + # Delete the versioned table + store.update(config, [fv], [], [], [], False) diff --git a/sdk/python/tests/integration/online_store/test_hybrid_online_store.py b/sdk/python/tests/integration/online_store/test_hybrid_online_store.py index 4b9dad05ff8..26f07c54b14 100644 --- a/sdk/python/tests/integration/online_store/test_hybrid_online_store.py +++ b/sdk/python/tests/integration/online_store/test_hybrid_online_store.py @@ -12,6 +12,8 @@ from feast.protos.feast.types.Value_pb2 import Value from feast.types import PrimitiveFeastType +pytestmark = pytest.mark.integration + @pytest.fixture def sample_entity(): diff --git a/sdk/python/tests/integration/online_store/test_mongodb_online_retrieval.py b/sdk/python/tests/integration/online_store/test_mongodb_online_retrieval.py new file mode 100644 index 00000000000..9c198d9a617 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_mongodb_online_retrieval.py @@ -0,0 +1,165 @@ +"""MongoDB online store integration tests.""" + +import pytest + +from feast.protos.feast.types.EntityKey_pb2 import ( + EntityKey as EntityKeyProto, +) +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.utils import _utc_now +from tests.universal.feature_repos.universal.feature_views import TAGS +from tests.utils.cli_repo_creator import CliRunner, get_example_repo + +pytestmark = pytest.mark.integration +pytest.importorskip("pymongo") + +docker_available = False +try: + import docker + from testcontainers.mongodb import MongoDbContainer + + try: + client = docker.from_env() + client.ping() + docker_available = True + except Exception: + pass +except ImportError: + pass + +_requires_docker = pytest.mark.skipif( + not docker_available, + reason="Docker is not available or not running. Start Docker daemon to run these tests.", +) + + +@pytest.fixture(scope="module") +def mongodb_container(): + container = MongoDbContainer( + "mongo:latest", + username="test", + password="test", # pragma: allowlist secret + ).with_exposed_ports(27017) + container.start() + yield container + container.stop() + + +@pytest.fixture +def mongodb_connection_string(mongodb_container): + exposed_port = mongodb_container.get_exposed_port(27017) + return f"mongodb://test:test@localhost:{exposed_port}" # pragma: allowlist secret + + +@_requires_docker +def test_mongodb_online_features(mongodb_connection_string): + runner = CliRunner() + with runner.local_repo( + get_example_repo("example_feature_repo_1.py"), + offline_store="file", + online_store="mongodb", + teardown=False, + ) as store: + store.config.online_store.connection_string = mongodb_connection_string + + driver_locations_fv = store.get_feature_view(name="driver_locations") + customer_profile_fv = store.get_feature_view(name="customer_profile") + customer_driver_combined_fv = store.get_feature_view( + name="customer_driver_combined" + ) + + provider = store._get_provider() + + driver_key = EntityKeyProto( + join_keys=["driver_id"], entity_values=[ValueProto(int64_val=1)] + ) + provider.online_write_batch( + config=store.config, + table=driver_locations_fv, + data=[ + ( + driver_key, + { + "lat": ValueProto(double_val=0.1), + "lon": ValueProto(string_val="1.0"), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id"], entity_values=[ValueProto(string_val="5")] + ) + provider.online_write_batch( + config=store.config, + table=customer_profile_fv, + data=[ + ( + customer_key, + { + "avg_orders_day": ValueProto(float_val=1.0), + "name": ValueProto(string_val="John"), + "age": ValueProto(int64_val=3), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id", "driver_id"], + entity_values=[ValueProto(string_val="5"), ValueProto(int64_val=1)], + ) + provider.online_write_batch( + config=store.config, + table=customer_driver_combined_fv, + data=[ + ( + customer_key, + {"trips": ValueProto(int64_val=7)}, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + assert len(store.list_entities()) == 3 + assert len(store.list_entities(tags=TAGS)) == 2 + + result = store.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[ + {"driver_id": 1, "customer_id": "5"}, + {"driver_id": 1, "customer_id": 5}, + ], + full_feature_names=False, + ).to_dict() + + assert "lon" in result + assert "avg_orders_day" in result + assert "name" in result + assert result["driver_id"] == [1, 1] + assert result["customer_id"] == ["5", "5"] + assert result["lon"] == ["1.0", "1.0"] + assert result["avg_orders_day"] == [1.0, 1.0] + assert result["name"] == ["John", "John"] + assert result["trips"] == [7, 7] + + result = store.get_online_features( + features=["customer_driver_combined:trips"], + entity_rows=[{"driver_id": 0, "customer_id": 0}], + full_feature_names=False, + ).to_dict() + + assert result["trips"] == [None] diff --git a/sdk/python/tests/integration/online_store/test_mongodb_vector_search.py b/sdk/python/tests/integration/online_store/test_mongodb_vector_search.py new file mode 100644 index 00000000000..1a0892aed99 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_mongodb_vector_search.py @@ -0,0 +1,280 @@ +"""Integration tests for MongoDB Atlas Vector Search in MongoDBOnlineStore. + +These tests require Docker and the ``mongodb/mongodb-atlas-local:8.0.4`` image. +They exercise: + - Vector index creation during ``update()`` + - Write + retrieve round-trip with known embeddings + - ``top_k`` limiting + - Index cleanup on teardown +""" + +from __future__ import annotations + +import time +from datetime import datetime, timedelta +from typing import Any, Dict, List + +import numpy as np +import pytest + +from feast import Entity, FeatureView, RepoConfig +from feast.field import Field +from feast.infra.offline_stores.file_source import FileSource +from feast.infra.online_stores.mongodb_online_store.mongodb import ( + MongoDBOnlineStore, +) +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.types import Array, Float32, Int64, String +from feast.value_type import ValueType +from tests.universal.feature_repos.universal.online_store.mongodb import ( + MongoDBAtlasOnlineStoreCreator, +) + +VECTOR_DIM = 3 +NUM_ROWS = 5 +INDEX_WAIT = 5 # seconds to wait for Atlas Search index eventual consistency + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _build_write_batch( + write_data: List[Dict[str, Any]], feature_view: FeatureView +) -> list: + """Build a list of (entity_key, features, event_ts, created_ts) tuples.""" + batch = [] + now = datetime.utcnow() + for row in write_data: + entity_key = EntityKeyProto( + join_keys=["item_id"], + entity_values=[ValueProto(int64_val=row["item_id"])], + ) + features: Dict[str, ValueProto] = { + "title": ValueProto(string_val=row["title"]), + } + emb_proto = ValueProto() + emb_proto.float_list_val.val.extend(row["embedding"]) + features["embedding"] = emb_proto + batch.append((entity_key, features, now, now)) + return batch + + +# --------------------------------------------------------------------------- +# Fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture(scope="module") +def atlas_creator(): + """Start an Atlas-local container for the whole module.""" + creator = MongoDBAtlasOnlineStoreCreator(project_name="test_vs") + online_store_dict = creator.create_online_store() + yield online_store_dict, creator + creator.teardown() + + +@pytest.fixture(scope="module") +def repo_config(atlas_creator) -> RepoConfig: + online_store_dict, _ = atlas_creator + return RepoConfig( + project="test_vs", + provider="local", + online_store=online_store_dict, + registry="memory://", + entity_key_serialization_version=3, + ) + + +@pytest.fixture(scope="module") +def item_entity() -> Entity: + return Entity(name="item_id", join_keys=["item_id"], value_type=ValueType.INT64) + + +@pytest.fixture(scope="module") +def feature_view() -> FeatureView: + data_source = FileSource( + path="dummy_path.parquet", timestamp_field="event_timestamp" + ) + return FeatureView( + name="item_embeddings", + entities=[ + Entity( + name="item_id", + join_keys=["item_id"], + value_type=ValueType.INT64, + ) + ], + schema=[ + Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=VECTOR_DIM, + vector_search_metric="cosine", + ), + Field(name="title", dtype=String), + Field(name="item_id", dtype=Int64), + ], + source=data_source, + ttl=timedelta(hours=24), + online=True, + ) + + +@pytest.fixture(scope="module") +def write_data() -> List[Dict[str, Any]]: + """Deterministic embeddings so we know the expected ordering.""" + np.random.seed(42) + rows = [] + for i in range(1, NUM_ROWS + 1): + rows.append( + { + "item_id": i, + "embedding": list(np.random.rand(VECTOR_DIM).astype(np.float32)), + "title": f"Document {i}", + } + ) + return rows + + +@pytest.fixture(scope="module") +def store() -> MongoDBOnlineStore: + """A single store instance shared across the module.""" + return MongoDBOnlineStore() + + +@pytest.fixture(scope="module") +def _setup_index_and_data(store, repo_config, feature_view, item_entity, write_data): + """One-time setup: create index, write data. Runs once for the module.""" + store.update( + config=repo_config, + tables_to_delete=[], + tables_to_keep=[feature_view], + entities_to_delete=[], + entities_to_keep=[item_entity], + partial=False, + ) + batch = _build_write_batch(write_data, feature_view) + store.online_write_batch( + config=repo_config, + table=feature_view, + data=batch, + progress=None, + ) + # Atlas Search indexes are eventually consistent — give the index time + # to pick up the newly written documents before running queries. + time.sleep(INDEX_WAIT) + + +# --------------------------------------------------------------------------- +# Tests +# --------------------------------------------------------------------------- + + +@pytest.mark.integration +class TestMongoDBVectorSearch: + """Tests for MongoDB Atlas Vector Search integration.""" + + def test_vector_index_created_on_update( + self, store, repo_config, feature_view, item_entity, _setup_index_and_data + ): + """Verify that update() creates an Atlas vector search index.""" + clxn = store._get_collection(repo_config) + indexes = list(clxn.list_search_indexes()) + vs_index_names = [idx["name"] for idx in indexes] + expected = "item_embeddings__embedding__vs_index" + assert expected in vs_index_names, ( + f"Expected index '{expected}' not found. Got: {vs_index_names}" + ) + + def test_write_and_retrieve_round_trip( + self, store, repo_config, feature_view, write_data, _setup_index_and_data + ): + """Write embeddings then retrieve via vector search.""" + query_embedding = write_data[0]["embedding"] + results = store.retrieve_online_documents_v2( + config=repo_config, + table=feature_view, + requested_features=["embedding", "title"], + embedding=query_embedding, + top_k=3, + ) + assert len(results) == 3 + # Each result is (event_ts, entity_key_proto, feature_dict) + for ts, ek, fdict in results: + assert fdict is not None + assert "distance" in fdict + assert "title" in fdict + assert fdict["distance"].float_val >= 0 + + # The closest match should be the document itself (highest score) + _, _, best = results[0] + assert best["title"].string_val == "Document 1" + + def test_top_k_limiting( + self, store, repo_config, feature_view, write_data, _setup_index_and_data + ): + """Verify that top_k correctly limits the number of results.""" + query_embedding = write_data[0]["embedding"] + + results_2 = store.retrieve_online_documents_v2( + config=repo_config, + table=feature_view, + requested_features=["embedding", "title"], + embedding=query_embedding, + top_k=2, + ) + assert len(results_2) == 2 + + results_all = store.retrieve_online_documents_v2( + config=repo_config, + table=feature_view, + requested_features=["embedding", "title"], + embedding=query_embedding, + top_k=100, + ) + assert len(results_all) == NUM_ROWS + + def test_update_idempotent( + self, store, repo_config, feature_view, item_entity, _setup_index_and_data + ): + """Calling update() a second time should not error (index already exists).""" + # _setup_index_and_data already called update() once. + # A second call must be a no-op for the existing index. + store.update( + config=repo_config, + tables_to_delete=[], + tables_to_keep=[feature_view], + entities_to_delete=[], + entities_to_keep=[item_entity], + partial=False, + ) + clxn = store._get_collection(repo_config) + indexes = list(clxn.list_search_indexes()) + vs_index_names = [idx["name"] for idx in indexes] + expected = "item_embeddings__embedding__vs_index" + assert vs_index_names.count(expected) == 1, ( + f"Expected exactly one '{expected}' index, got: {vs_index_names}" + ) + + def test_index_cleanup_on_teardown( + self, store, repo_config, feature_view, item_entity, _setup_index_and_data + ): + """Verify teardown drops the collection (and thus all indexes). + + This test must run last as it destroys the collection. + """ + store.teardown( + config=repo_config, + tables=[feature_view], + entities=[item_entity], + ) + # After teardown the collection should be dropped + client = store._get_client(repo_config) + online_config = repo_config.online_store + db = client[online_config.database_name] + clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" + assert clxn_name not in db.list_collection_names() diff --git a/sdk/python/tests/integration/online_store/test_mysql_versioning.py b/sdk/python/tests/integration/online_store/test_mysql_versioning.py new file mode 100644 index 00000000000..d7353cd4a08 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_mysql_versioning.py @@ -0,0 +1,188 @@ +"""Integration tests for MySQL online store feature view versioning. + +Run with: pytest --integration sdk/python/tests/integration/online_store/test_mysql_versioning.py +""" + +import shutil +from datetime import datetime, timedelta, timezone + +import pytest + +from feast import Entity, FeatureView +from feast.field import Field +from feast.infra.online_stores.mysql_online_store.mysql import MySQLOnlineStore +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RegistryConfig, RepoConfig +from feast.types import Float32, Int64 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version="latest"): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + return FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + version=version, + ) + + +def _make_entity_key(driver_id: int) -> EntityKeyProto: + entity_key = EntityKeyProto() + entity_key.join_keys.append("driver_id") + val = ValueProto() + val.int64_val = driver_id + entity_key.entity_values.append(val) + return entity_key + + +def _write_and_read(store, config, fv, driver_id=1001, trips=42): + entity_key = _make_entity_key(driver_id) + val = ValueProto() + val.int64_val = trips + now = datetime.now(tz=timezone.utc) + store.online_write_batch( + config, fv, [(entity_key, {"trips_today": val}, now, now)], None + ) + return store.online_read(config, fv, [entity_key], ["trips_today"]) + + +@pytest.mark.integration +@pytest.mark.skipif( + not shutil.which("docker"), + reason="Docker not available", +) +class TestMySQLVersioningIntegration: + """Integration tests for MySQL versioning with a real database.""" + + @pytest.fixture(autouse=True) + def setup_mysql(self): + try: + from testcontainers.mysql import MySqlContainer + except ImportError: + pytest.skip("testcontainers[mysql] not installed") + + self.container = MySqlContainer( + "mysql:8.0", + username="root", + password="testpass", # pragma: allowlist secret + dbname="feast", + dialect="pymysql", + ).with_exposed_ports(3306) + self.container.start() + self.port = self.container.get_exposed_port(3306) + yield + self.container.stop() + + def _make_config(self, enable_versioning=False): + from feast.infra.online_stores.mysql_online_store.mysql import ( + MySQLOnlineStoreConfig, + ) + + return RepoConfig( + project="test_project", + provider="local", + online_store=MySQLOnlineStoreConfig( + type="mysql", + host="localhost", + port=int(self.port), + user="root", + password="testpass", # pragma: allowlist secret + database="feast", + ), + registry=RegistryConfig( + path="/tmp/test_mysql_registry.pb", + enable_online_feature_view_versioning=enable_versioning, + ), + entity_key_serialization_version=3, + ) + + def test_write_read_without_versioning(self): + config = self._make_config(enable_versioning=False) + store = MySQLOnlineStore() + fv = _make_feature_view() + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_write_read_with_versioning_v1(self): + config = self._make_config(enable_versioning=True) + store = MySQLOnlineStore() + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_version_isolation(self): + """Data written to v1 is not visible from v2.""" + config = self._make_config(enable_versioning=True) + store = MySQLOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=10) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_v2, [entity_key], ["trips_today"]) + assert result[0] == (None, None) + + result = store.online_read(config, fv_v1, [entity_key], ["trips_today"]) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 10 + + def test_projection_version_tag_routes_to_correct_table(self): + """projection.version_tag routes reads to the correct versioned table.""" + config = self._make_config(enable_versioning=True) + store = MySQLOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=100) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + _write_and_read(store, config, fv_v2, driver_id=1001, trips=200) + + fv_read = _make_feature_view() + fv_read.projection.version_tag = 1 + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_read, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 100 + + fv_read2 = _make_feature_view() + fv_read2.projection.version_tag = 2 + result = store.online_read(config, fv_read2, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 200 + + def test_teardown_versioned_table(self): + config = self._make_config(enable_versioning=True) + store = MySQLOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv) + + store.teardown(config, [fv], []) diff --git a/sdk/python/tests/integration/online_store/test_postgres_versioning.py b/sdk/python/tests/integration/online_store/test_postgres_versioning.py new file mode 100644 index 00000000000..9816c2a43c2 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_postgres_versioning.py @@ -0,0 +1,205 @@ +"""Integration tests for PostgreSQL online store feature view versioning. + +Run with: pytest --integration sdk/python/tests/integration/online_store/test_postgres_versioning.py +""" + +import shutil +from datetime import datetime, timedelta, timezone + +import pytest + +from feast import Entity, FeatureView +from feast.field import Field +from feast.infra.online_stores.postgres_online_store.postgres import ( + PostgreSQLOnlineStore, +) +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RegistryConfig, RepoConfig +from feast.types import Float32, Int64 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version="latest"): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + return FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + version=version, + ) + + +def _make_entity_key(driver_id: int) -> EntityKeyProto: + entity_key = EntityKeyProto() + entity_key.join_keys.append("driver_id") + val = ValueProto() + val.int64_val = driver_id + entity_key.entity_values.append(val) + return entity_key + + +def _write_and_read(store, config, fv, driver_id=1001, trips=42): + entity_key = _make_entity_key(driver_id) + val = ValueProto() + val.int64_val = trips + now = datetime.now(tz=timezone.utc) + store.online_write_batch( + config, fv, [(entity_key, {"trips_today": val}, now, now)], None + ) + return store.online_read(config, fv, [entity_key], ["trips_today"]) + + +@pytest.mark.integration +@pytest.mark.skipif( + not shutil.which("docker"), + reason="Docker not available", +) +class TestPostgresVersioningIntegration: + """Integration tests for PostgreSQL versioning with a real database.""" + + @pytest.fixture(autouse=True) + def setup_postgres(self): + try: + from testcontainers.postgres import PostgresContainer + except ImportError: + pytest.skip("testcontainers[postgres] not installed") + + self.container = PostgresContainer( + "postgres:16", + username="root", + password="testpass", # pragma: allowlist secret + dbname="test", + ).with_exposed_ports(5432) + self.container.start() + self.port = self.container.get_exposed_port(5432) + yield + self.container.stop() + + def _make_config(self, enable_versioning=False): + from feast.infra.online_stores.postgres_online_store.postgres import ( + PostgreSQLOnlineStoreConfig, + ) + + return RepoConfig( + project="test_project", + provider="local", + online_store=PostgreSQLOnlineStoreConfig( + type="postgres", + host="localhost", + port=int(self.port), + user="root", + password="testpass", # pragma: allowlist secret + database="test", + sslmode="disable", + ), + registry=RegistryConfig( + path="/tmp/test_pg_registry.pb", + enable_online_feature_view_versioning=enable_versioning, + ), + entity_key_serialization_version=3, + ) + + def test_write_read_without_versioning(self): + config = self._make_config(enable_versioning=False) + store = PostgreSQLOnlineStore() + fv = _make_feature_view() + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_write_read_with_versioning_v1(self): + config = self._make_config(enable_versioning=True) + store = PostgreSQLOnlineStore() + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_version_isolation(self): + """Data written to v1 is not visible from v2.""" + config = self._make_config(enable_versioning=True) + store = PostgreSQLOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=10) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_v2, [entity_key], ["trips_today"]) + assert result[0] == (None, None) + + result = store.online_read(config, fv_v1, [entity_key], ["trips_today"]) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 10 + + def test_projection_version_tag_routes_to_correct_table(self): + """projection.version_tag routes reads to the correct versioned table.""" + config = self._make_config(enable_versioning=True) + store = PostgreSQLOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=100) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + _write_and_read(store, config, fv_v2, driver_id=1001, trips=200) + + fv_read = _make_feature_view() + fv_read.projection.version_tag = 1 + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_read, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 100 + + fv_read2 = _make_feature_view() + fv_read2.projection.version_tag = 2 + result = store.online_read(config, fv_read2, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 200 + + def test_teardown_versioned_table(self): + """teardown() drops the versioned table without error.""" + config = self._make_config(enable_versioning=True) + store = PostgreSQLOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv) + + # Should not raise + store.teardown(config, [fv], []) + + def test_update_deletes_versioned_table(self): + """update() with tables_to_delete correctly drops versioned tables.""" + config = self._make_config(enable_versioning=True) + store = PostgreSQLOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv, driver_id=1001, trips=50) + + # Delete the versioned table + store.update(config, [fv], [], [], [], False) diff --git a/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py b/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py index 536864ed97e..55a4eb12adc 100644 --- a/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py +++ b/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py @@ -47,7 +47,7 @@ def test_push_features_and_read(store): @pytest.mark.integration -@pytest.mark.universal_online_stores(only=["dynamodb", "mongodb"]) +@pytest.mark.universal_online_stores(only=["mongodb"]) async def test_push_features_and_read_async(store): await store.push_async("location_stats_push_source", _ingest_df()) @@ -56,3 +56,36 @@ async def test_push_features_and_read_async(store): entity_rows=[{"location_id": 1}], ) assert_response(online_resp) + + +@pytest.mark.asyncio +@pytest.mark.integration +@pytest.mark.universal_online_stores +async def test_push_features_and_read_async_dynamodb(dynamodb_local_environment): + """Async push + async read for DynamoDB with a credential-isolated environment. + + DynamoDB Local 2.x rejects requests that carry an expired AWS session + token. In CI, real (possibly expired) STS credentials exist in the + environment. The shared ``environment`` fixture resolves credentials + before the async client is created, so those bad credentials bleed in. + + This test uses ``dynamodb_local_environment``, which sets dummy + credentials *before* any boto client is instantiated, guaranteeing that + both the sync boto3 table-provisioning client and the async aiobotocore + client start with clean, token-free credentials. + """ + environment, universal_test_data = dynamodb_local_environment + store = environment.feature_store + _, _, data_sources = universal_test_data + + feature_views = construct_universal_feature_views(data_sources) + location_fv = feature_views.pushed_locations + store.apply([location(), location_fv]) + + await store.push_async("location_stats_push_source", _ingest_df()) + + online_resp = await store.get_online_features_async( + features=["pushable_location_stats:temperature"], + entity_rows=[{"location_id": 1}], + ) + assert_response(online_resp) diff --git a/sdk/python/tests/integration/online_store/test_redis_versioning.py b/sdk/python/tests/integration/online_store/test_redis_versioning.py new file mode 100644 index 00000000000..50ebe36b106 --- /dev/null +++ b/sdk/python/tests/integration/online_store/test_redis_versioning.py @@ -0,0 +1,207 @@ +"""Integration tests for Redis online store feature view versioning. + +Run with: pytest --integration sdk/python/tests/integration/online_store/test_redis_versioning.py +""" + +import shutil +from datetime import datetime, timedelta, timezone + +import pytest + +from feast import Entity, FeatureView +from feast.field import Field +from feast.infra.online_stores.redis import RedisOnlineStore +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RegistryConfig, RepoConfig +from feast.types import Float32, Int64 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version="latest"): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + return FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + version=version, + ) + + +def _make_entity_key(driver_id: int) -> EntityKeyProto: + entity_key = EntityKeyProto() + entity_key.join_keys.append("driver_id") + val = ValueProto() + val.int64_val = driver_id + entity_key.entity_values.append(val) + return entity_key + + +def _write_and_read(store, config, fv, driver_id=1001, trips=42): + entity_key = _make_entity_key(driver_id) + val = ValueProto() + val.int64_val = trips + now = datetime.now(tz=timezone.utc) + store.online_write_batch( + config, fv, [(entity_key, {"trips_today": val}, now, now)], None + ) + return store.online_read(config, fv, [entity_key], ["trips_today"]) + + +@pytest.mark.integration +@pytest.mark.skipif( + not shutil.which("docker"), + reason="Docker not available", +) +class TestRedisVersioningIntegration: + """Integration tests for Redis versioning with a real Redis instance.""" + + @pytest.fixture(autouse=True) + def setup_redis(self): + try: + from testcontainers.redis import RedisContainer + except ImportError: + pytest.skip("testcontainers[redis] not installed") + + self.container = RedisContainer("redis:7").with_exposed_ports(6379) + self.container.start() + self.port = self.container.get_exposed_port(6379) + yield + self.container.stop() + + def _make_config(self, enable_versioning=False): + from feast.infra.online_stores.redis import RedisOnlineStoreConfig + + return RepoConfig( + project="test_project", + provider="local", + online_store=RedisOnlineStoreConfig( + type="redis", + connection_string=f"localhost:{self.port}", + ), + registry=RegistryConfig( + path="/tmp/test_redis_registry.pb", + enable_online_feature_view_versioning=enable_versioning, + ), + entity_key_serialization_version=3, + ) + + def test_write_read_without_versioning(self): + config = self._make_config(enable_versioning=False) + store = RedisOnlineStore() + fv = _make_feature_view() + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_write_read_with_versioning_v1(self): + config = self._make_config(enable_versioning=True) + store = RedisOnlineStore() + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + + result = _write_and_read(store, config, fv) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 42 + + def test_version_isolation(self): + """Data written to v1 is not visible from v2.""" + config = self._make_config(enable_versioning=True) + store = RedisOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=10) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_v2, [entity_key], ["trips_today"]) + # In Redis, all versions share the same entity hash key. When v2 hash + # fields don't exist, hmget returns None values which become empty + # ValueProtos. The key assertion is that v1's actual data (10) does NOT + # leak through to v2. + ts_v2, feats_v2 = result[0] + assert feats_v2 is None or feats_v2["trips_today"].int64_val != 10 + + result = store.online_read(config, fv_v1, [entity_key], ["trips_today"]) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 10 + + def test_projection_version_tag_routes_to_correct_table(self): + """projection.version_tag routes reads to the correct versioned hash fields.""" + config = self._make_config(enable_versioning=True) + store = RedisOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=100) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + _write_and_read(store, config, fv_v2, driver_id=1001, trips=200) + + fv_read = _make_feature_view() + fv_read.projection.version_tag = 1 + entity_key = _make_entity_key(1001) + result = store.online_read(config, fv_read, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 100 + + fv_read2 = _make_feature_view() + fv_read2.projection.version_tag = 2 + result = store.online_read(config, fv_read2, [entity_key], ["trips_today"]) + assert result[0][1]["trips_today"].int64_val == 200 + + def test_teardown_cleans_up(self): + """teardown() removes entity keys without error.""" + config = self._make_config(enable_versioning=True) + store = RedisOnlineStore() + + fv = _make_feature_view() + fv.current_version_number = 1 + store.update(config, [], [fv], [], [], False) + _write_and_read(store, config, fv) + + # Should not raise + store.teardown(config, [fv], []) + + def test_delete_table_versioned(self): + """delete_table() removes only the versioned hash fields.""" + config = self._make_config(enable_versioning=True) + store = RedisOnlineStore() + + fv_v1 = _make_feature_view() + fv_v1.current_version_number = 1 + store.update(config, [], [fv_v1], [], [], False) + _write_and_read(store, config, fv_v1, driver_id=1001, trips=10) + + fv_v2 = _make_feature_view() + fv_v2.current_version_number = 2 + store.update(config, [], [fv_v2], [], [], False) + _write_and_read(store, config, fv_v2, driver_id=1001, trips=20) + + # Delete v1 via update + store.update(config, [fv_v1], [fv_v2], [], [], False) + + entity_key = _make_entity_key(1001) + # v2 should still be readable + result = store.online_read(config, fv_v2, [entity_key], ["trips_today"]) + assert result[0][1] is not None + assert result[0][1]["trips_today"].int64_val == 20 diff --git a/sdk/python/tests/integration/online_store/test_universal_online.py b/sdk/python/tests/integration/online_store/test_universal_online.py index c4b141700b5..109eea454c0 100644 --- a/sdk/python/tests/integration/online_store/test_universal_online.py +++ b/sdk/python/tests/integration/online_store/test_universal_online.py @@ -532,10 +532,19 @@ async def test_async_online_retrieval_with_event_timestamps( @pytest.mark.asyncio @pytest.mark.integration -@pytest.mark.universal_online_stores(only=["dynamodb"]) +@pytest.mark.universal_online_stores async def test_async_online_retrieval_with_event_timestamps_dynamo( - environment, universal_data_sources + dynamodb_local_environment, ): + """Async online retrieval for DynamoDB with a credential-isolated environment. + + Uses ``dynamodb_local_environment`` (its own DynamoDB Local container + + FileDataSourceCreator) so that dummy credentials are set before any boto + client is created. This avoids the expired-STS-token problem that + occurs when aiobotocore lazily resolves credentials from the shared + environment in CI. + """ + environment, universal_data_sources = dynamodb_local_environment await _do_async_retrieval_test(environment, universal_data_sources) @@ -921,13 +930,27 @@ def test_retrieve_online_milvus_documents(environment, fake_document_data): df, data_source = fake_document_data item_embeddings_feature_view = create_item_embeddings_feature_view(data_source) fs.apply([item_embeddings_feature_view, item()]) + + features = [ + "item_embeddings:embedding_float", + "item_embeddings:item_id", + "item_embeddings:string_feature", + ] + + # Empty-store query: collection exists but has no rows yet. + empty = fs.retrieve_online_documents_v2( + features=features, + query=[1.0, 2.0], + top_k=2, + distance_metric="L2", + ).to_dict() + assert len(empty["embedding_float"]) == 0 + assert len(empty["item_id"]) == 0 + fs.write_to_online_store("item_embeddings", df) + documents = fs.retrieve_online_documents_v2( - features=[ - "item_embeddings:embedding_float", - "item_embeddings:item_id", - "item_embeddings:string_feature", - ], + features=features, query=[1.0, 2.0], top_k=2, distance_metric="L2", @@ -948,6 +971,50 @@ def test_retrieve_online_milvus_documents(environment, fake_document_data): f"Integration test: embedding {i} has {len(embedding)} dimensions, expected {query_dim}" ) + # Oversized top_k: dataset has 3 rows, request 5 -> expect 3 back. + all_docs = fs.retrieve_online_documents_v2( + features=features, + query=[1.0, 2.0], + top_k=5, + distance_metric="L2", + ).to_dict() + assert len(all_docs["embedding_float"]) == 3 + assert sorted(all_docs["item_id"]) == [1, 2, 3] + + # Cosine-metric variant: separate FV so the Milvus collection is created + # with COSINE as its index metric. + cosine_fv = FeatureView( + name="item_embeddings_cosine", + entities=[item()], + schema=[ + Field( + name="embedding_float", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="string_feature", dtype=String), + Field(name="float_feature", dtype=Float32), + ], + source=data_source, + ttl=timedelta(hours=2), + ) + fs.apply([cosine_fv]) + fs.write_to_online_store("item_embeddings_cosine", df) + + cosine_docs = fs.retrieve_online_documents_v2( + features=[ + "item_embeddings_cosine:embedding_float", + "item_embeddings_cosine:item_id", + "item_embeddings_cosine:string_feature", + ], + query=[1.0, 2.0], + top_k=2, + distance_metric="COSINE", + ).to_dict() + assert len(cosine_docs["embedding_float"]) == 2 + assert len(cosine_docs["item_id"]) == 2 + @pytest.mark.integration @pytest.mark.universal_online_stores(only=["milvus"]) @@ -1159,6 +1226,12 @@ def test_retrieve_online_documents_v2(environment, fake_document_data): assert len(vector_results["text_field"]) == 5 assert len(vector_results["category"]) == 5 + assert all(isinstance(v, list) for v in vector_results["embedding"]) + assert all(isinstance(v, float) for v in vector_results["distance"]) + assert all(isinstance(v, str) for v in vector_results["text_field"]) + assert all(isinstance(v, str) for v in vector_results["category"]) + assert all(isinstance(v, int) for v in vector_results["item_id"]) + # Test 2: Vector similarity search with Cosine distance vector_results = fs.retrieve_online_documents_v2( features=[ @@ -1177,6 +1250,12 @@ def test_retrieve_online_documents_v2(environment, fake_document_data): assert len(vector_results["text_field"]) == 5 assert len(vector_results["category"]) == 5 + assert all(isinstance(v, list) for v in vector_results["embedding"]) + assert all(isinstance(v, float) for v in vector_results["distance"]) + assert all(isinstance(v, str) for v in vector_results["text_field"]) + assert all(isinstance(v, str) for v in vector_results["category"]) + assert all(isinstance(v, int) for v in vector_results["item_id"]) + # Test 3: Full text search text_results = fs.retrieve_online_documents_v2( features=[ @@ -1195,6 +1274,11 @@ def test_retrieve_online_documents_v2(environment, fake_document_data): assert len(text_results["category"]) == 5 assert len(text_results["item_id"]) == 5 + assert all(isinstance(v, str) for v in text_results["text_field"]) + assert all(isinstance(v, float) for v in text_results["text_rank"]) + assert all(isinstance(v, str) for v in text_results["category"]) + assert all(isinstance(v, int) for v in text_results["item_id"]) + # Verify text rank values are between 0 and 1 assert all(0 <= rank <= 1 for rank in text_results["text_rank"]) @@ -1224,22 +1308,12 @@ def test_retrieve_online_documents_v2(environment, fake_document_data): assert len(hybrid_results["category"]) == 5 assert len(hybrid_results["item_id"]) == 5 - # Test 5: Hybrid search with different text query - hybrid_results = fs.retrieve_online_documents_v2( - features=[ - "item_embeddings:embedding", - "item_embeddings:text_field", - "item_embeddings:category", - "item_embeddings:item_id", - ], - query=query_embedding, - query_string="Category-1", - top_k=5, - distance_metric="L2", - ).to_dict() - - # Verify results contain only documents from Category-1 - assert all(cat == "Category-1" for cat in hybrid_results["category"]) + assert all(isinstance(v, list) for v in hybrid_results["embedding"]) + assert all(isinstance(v, float) for v in hybrid_results["distance"]) + assert all(isinstance(v, str) for v in hybrid_results["text_field"]) + assert all(isinstance(v, float) for v in hybrid_results["text_rank"]) + assert all(isinstance(v, str) for v in hybrid_results["category"]) + assert all(isinstance(v, int) for v in hybrid_results["item_id"]) # Test 6: Full text search with no matches no_match_results = fs.retrieve_online_documents_v2( diff --git a/sdk/python/tests/integration/permissions/__init__.py b/sdk/python/tests/integration/permissions/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/integration/permissions/auth/__init__.py b/sdk/python/tests/integration/permissions/auth/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/integration/permissions/auth/conftest.py b/sdk/python/tests/integration/permissions/auth/conftest.py new file mode 100644 index 00000000000..81b4faa7af0 --- /dev/null +++ b/sdk/python/tests/integration/permissions/auth/conftest.py @@ -0,0 +1,30 @@ +import pytest + +from tests.unit.permissions.auth.server.test_utils import ( + invalid_list_entities_perm, + read_entities_perm, + read_fv_perm, + read_odfv_perm, + read_permissions_perm, + read_projects_perm, + read_sfv_perm, +) + + +@pytest.fixture( + scope="module", + params=[ + [], + [invalid_list_entities_perm], + [ + read_entities_perm, + read_permissions_perm, + read_fv_perm, + read_odfv_perm, + read_sfv_perm, + read_projects_perm, + ], + ], +) +def applied_permissions(request): + return request.param diff --git a/sdk/python/tests/integration/permissions/auth/server/__init__.py b/sdk/python/tests/integration/permissions/auth/server/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/unit/permissions/auth/server/test_auth_registry_server.py b/sdk/python/tests/integration/permissions/auth/server/test_auth_registry_server.py similarity index 96% rename from sdk/python/tests/unit/permissions/auth/server/test_auth_registry_server.py rename to sdk/python/tests/integration/permissions/auth/server/test_auth_registry_server.py index e0f75d1d3d8..40b506cd4db 100644 --- a/sdk/python/tests/unit/permissions/auth/server/test_auth_registry_server.py +++ b/sdk/python/tests/integration/permissions/auth/server/test_auth_registry_server.py @@ -11,7 +11,9 @@ FeastPermissionError, FeatureViewNotFoundException, ) +from feast.permissions.auth.auth_manager import AllowAll, set_auth_manager from feast.permissions.permission import Permission +from feast.permissions.security_manager import no_security_manager from feast.registry_server import start_server from feast.wait import wait_retry_backoff # noqa: E402 from tests.unit.permissions.auth.server import mock_utils @@ -27,6 +29,8 @@ from tests.utils.auth_permissions_util import get_remote_registry_store from tests.utils.http_server import check_port_open # noqa: E402 +pytestmark = [pytest.mark.integration, pytest.mark.rbac_remote_integration_test] + @pytest.fixture def start_registry_server( @@ -71,7 +75,11 @@ def start_registry_server( yield server print("Stopping server") - server.stop(grace=None) # Teardown server + try: + server.stop(grace=None) # Teardown server + finally: + no_security_manager() + set_auth_manager(AllowAll()) @pytest.mark.parametrize( diff --git a/sdk/python/tests/integration/registration/test_universal_registry.py b/sdk/python/tests/integration/registration/test_universal_registry.py index fb09395d789..735d714a1f3 100644 --- a/sdk/python/tests/integration/registration/test_universal_registry.py +++ b/sdk/python/tests/integration/registration/test_universal_registry.py @@ -43,6 +43,7 @@ from feast.infra.registry.base_registry import BaseRegistry from feast.infra.registry.registry import Registry from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig +from feast.infra.registry.snowflake import SnowflakeRegistry, SnowflakeRegistryConfig from feast.infra.registry.sql import SqlRegistry, SqlRegistryConfig from feast.on_demand_feature_view import on_demand_feature_view from feast.permissions.action import AuthzedAction @@ -272,16 +273,51 @@ def mysql_registry_async(mysql_server): yield SqlRegistry(registry_config, "project", None) -@pytest.fixture(scope="session") -def sqlite_registry(): +@pytest.fixture(scope="function") +def sqlite_registry(tmp_path): registry_config = SqlRegistryConfig( registry_type="sql", - path="sqlite://", + path=f"sqlite:///{tmp_path / 'registry.db'}", cache_ttl_seconds=2, cache_mode="sync", ) - yield SqlRegistry(registry_config, "project", None) + registry = SqlRegistry(registry_config, "project", None) + yield registry + registry.teardown() + + +@pytest.fixture(scope="function") +def snowflake_registry(): + account = os.getenv("SNOWFLAKE_CI_DEPLOYMENT", "") + if not account: + pytest.skip("SNOWFLAKE_CI_DEPLOYMENT not set") + + config_kwargs = dict( + registry_type="snowflake.registry", + account=account, + user=os.getenv("SNOWFLAKE_CI_USER", ""), + role=os.getenv("SNOWFLAKE_CI_ROLE", ""), + warehouse=os.getenv("SNOWFLAKE_CI_WAREHOUSE", ""), + database=os.getenv("SNOWFLAKE_CI_DATABASE", "FEAST"), + schema=os.getenv("SNOWFLAKE_CI_SCHEMA", "REGISTRY_TEST"), + cache_ttl_seconds=2, + purge_feast_metadata=False, + ) + + private_key = os.getenv("SNOWFLAKE_CI_PRIVATE_KEY_PATH", "") + if private_key: + config_kwargs["private_key"] = private_key + passphrase = os.getenv("SNOWFLAKE_CI_PRIVATE_KEY_PASSPHRASE", "") + if passphrase: + config_kwargs["private_key_passphrase"] = passphrase + else: + config_kwargs["password"] = os.getenv("SNOWFLAKE_CI_PASSWORD", "") + + registry_config = SnowflakeRegistryConfig(**config_kwargs) + registry = SnowflakeRegistry(registry_config, "project", None) + yield registry + registry.teardown() @pytest.fixture(scope="function") @@ -412,6 +448,10 @@ def mock_remote_registry(): lazy_fixture("hdfs_registry"), marks=pytest.mark.xdist_group(name="hdfs_registry"), ), + pytest.param( + lazy_fixture("snowflake_registry"), + marks=pytest.mark.xdist_group(name="snowflake_registry"), + ), ] ) else: @@ -899,6 +939,111 @@ def test_apply_data_source_with_timestamps(test_registry): test_registry.teardown() +@pytest.mark.integration +@pytest.mark.parametrize( + "test_registry", + [lazy_fixture("local_registry")], +) +def test_apply_data_source_cross_project_isolation(test_registry): + """Test that apply_data_source uses project-scoped filtering. + + Regression test for https://github.com/feast-dev/feast/issues/6206: + applying a data source to one project must not overwrite the data source + with the same name in a different project. + + See: feast-dev/feast#6298 + """ + project_a = "project_a" + project_b = "project_b" + + source_a = FileSource( + name="shared_source_name", + file_format=ParquetFormat(), + path="file://feast/project_a.parquet", + timestamp_field="ts_col", + ) + source_b = FileSource( + name="shared_source_name", + file_format=ParquetFormat(), + path="file://feast/project_b.parquet", + timestamp_field="ts_col", + ) + + test_registry.apply_data_source(source_a, project_a, commit=True) + test_registry.apply_data_source(source_b, project_b, commit=True) + + # Each project should have exactly its own source + sources_a = test_registry.list_data_sources(project_a) + sources_b = test_registry.list_data_sources(project_b) + assert len(sources_a) == 1 + assert len(sources_b) == 1 + + # Paths must be project-specific — not overwritten cross-project + assert sources_a[0].path == "file://feast/project_a.parquet" + assert sources_b[0].path == "file://feast/project_b.parquet" + + # Re-apply source_b with updated path: must not bleed into project_a + source_b_updated = FileSource( + name="shared_source_name", + file_format=ParquetFormat(), + path="file://feast/project_b_v2.parquet", + timestamp_field="ts_col", + ) + test_registry.apply_data_source(source_b_updated, project_b, commit=True) + + sources_a_after = test_registry.list_data_sources(project_a) + assert len(sources_a_after) == 1 + assert sources_a_after[0].path == "file://feast/project_a.parquet", ( + "apply_data_source for project_b must not overwrite project_a's source" + ) + + test_registry.teardown() + + +@pytest.mark.integration +@pytest.mark.parametrize( + "test_registry", + [lazy_fixture("local_registry")], +) +def test_delete_data_source_project_scoped(test_registry): + """Test that delete_data_source only removes the source from the given project. + + Regression test for https://github.com/feast-dev/feast/issues/6206: + deleting a data source from one project must not delete the data source + with the same name from another project. + """ + project_a = "project_a" + project_b = "project_b" + + source_a = FileSource( + name="shared_source_name", + file_format=ParquetFormat(), + path="file://feast/project_a.parquet", + timestamp_field="ts_col", + ) + source_b = FileSource( + name="shared_source_name", + file_format=ParquetFormat(), + path="file://feast/project_b.parquet", + timestamp_field="ts_col", + ) + + test_registry.apply_data_source(source_a, project_a, commit=True) + test_registry.apply_data_source(source_b, project_b, commit=True) + + # Delete the source from project_a only + test_registry.delete_data_source("shared_source_name", project_a, commit=True) + + # project_a should have no sources; project_b should be unaffected + sources_a = test_registry.list_data_sources(project_a) + sources_b = test_registry.list_data_sources(project_b) + assert len(sources_a) == 0, "Source should be deleted from project_a" + assert len(sources_b) == 1, "Source in project_b must not be deleted" + assert sources_b[0].path == "file://feast/project_b.parquet" + + test_registry.teardown() + + @pytest.mark.integration @pytest.mark.parametrize( "test_registry", diff --git a/sdk/python/tests/integration/registration/test_versioning.py b/sdk/python/tests/integration/registration/test_versioning.py new file mode 100644 index 00000000000..72289e72a4f --- /dev/null +++ b/sdk/python/tests/integration/registration/test_versioning.py @@ -0,0 +1,1418 @@ +"""Integration tests for feature view versioning.""" + +import os +import tempfile +from datetime import timedelta +from pathlib import Path + +import pytest + +from feast import FeatureStore +from feast.entity import Entity +from feast.errors import FeatureViewPinConflict, FeatureViewVersionNotFound +from feast.feature_service import FeatureService +from feast.feature_view import FeatureView +from feast.field import Field +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.infra.registry.registry import Registry +from feast.repo_config import RegistryConfig, RepoConfig +from feast.stream_feature_view import StreamFeatureView +from feast.types import Float32, Int64 +from feast.value_type import ValueType + + +@pytest.fixture +def registry(): + """Create a file-based Registry for testing. Version history is always-on.""" + with tempfile.TemporaryDirectory() as tmpdir: + registry_path = Path(tmpdir) / "registry.pb" + config = RegistryConfig(path=str(registry_path)) + reg = Registry("test_project", config, None) + yield reg + + +@pytest.fixture +def registry_no_online_versioning(): + """Create a file-based Registry without online versioning (default).""" + with tempfile.TemporaryDirectory() as tmpdir: + registry_path = Path(tmpdir) / "registry.pb" + config = RegistryConfig(path=str(registry_path)) + reg = Registry("test_project", config, None) + yield reg + + +@pytest.fixture +def entity(): + return Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + + +@pytest.fixture +def make_fv(entity): + def _make(description="test feature view", version="latest", **kwargs): + return FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + description=description, + version=version, + **kwargs, + ) + + return _make + + +@pytest.fixture +def make_sfv(entity): + def _make(description="test stream feature view", udf=None, **kwargs): + from feast.data_source import PushSource + from feast.infra.offline_stores.file_source import FileSource + + def default_udf(df): + return df + + # Create batch source + batch_source = FileSource(name="test_batch_source", path="test.parquet") + + # Create a simple push source for testing + source = PushSource(name="test_push_source", batch_source=batch_source) + + return StreamFeatureView( + name="driver_stats_stream", + entities=[entity], + ttl=timedelta(hours=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + description=description, + udf=udf or default_udf, + source=source, + **kwargs, + ) + + return _make + + +# OnDemandFeatureView tests removed due to transformation comparison issues + + +class TestFileRegistryVersioning: + def test_first_apply_creates_v0(self, registry, make_fv): + fv = make_fv() + registry.apply_feature_view(fv, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 + assert versions[0]["version"] == "v0" + assert versions[0]["version_number"] == 0 + + def test_modify_and_reapply_creates_new_version(self, registry, make_fv, entity): + fv1 = make_fv(description="version one") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create a schema change by adding a new feature + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_feature", dtype=Float32), # Schema change + ], + description="version two", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 2 + assert versions[0]["version"] == "v0" + assert versions[1]["version"] == "v1" + + def test_idempotent_apply_no_new_version(self, registry, make_fv): + fv = make_fv(description="same definition") + registry.apply_feature_view(fv, "test_project", commit=True) + + # Apply identical FV again + fv_same = make_fv(description="same definition") + registry.apply_feature_view(fv_same, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 # No new version created + + def test_pin_to_v0(self, registry, make_fv, entity): + # Create v0 + fv1 = make_fv(description="original") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), # Schema change + ], + description="updated", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Pin to v0 (definition must match active FV, only version changes) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), # Keep current schema + ], + description="updated", + version="v0", + ) + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + # Verify active entry has v0's content + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.description == "original" + assert active_fv.version == "v0" + + def test_explicit_version_creates_when_not_exists(self, registry, make_fv): + """Explicit version on a new FV creates that version (forward declaration).""" + fv = make_fv(description="forward declared v1", version="v1") + registry.apply_feature_view(fv, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 + assert versions[0]["version_number"] == 1 + + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.current_version_number == 1 + + def test_explicit_version_reverts_when_exists(self, registry, make_fv, entity): + """Explicit version on an existing FV reverts to that snapshot (pin/revert).""" + # Create v0 + fv1 = make_fv(description="original") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), + ], + description="updated", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Pin to v0 (definition must match active FV, only version changes) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), + ], + description="updated", + version="v0", + ) + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.description == "original" + assert active_fv.version == "v0" + + def test_forward_declare_nonexistent_version(self, registry, make_fv): + """Forward-declaring a version that doesn't exist creates it.""" + fv = make_fv() + registry.apply_feature_view(fv, "test_project", commit=True) + + # Forward-declare v5 — should create it, not raise + fv_v5 = make_fv(description="forward declared v5", version="v5") + registry.apply_feature_view(fv_v5, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + version_numbers = [v["version_number"] for v in versions] + assert 5 in version_numbers + + # The active FV should now be the forward-declared v5 + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.current_version_number == 5 + assert active_fv.description == "forward declared v5" + + def test_apply_after_pin_creates_new_version(self, registry, make_fv, entity): + # Create v0 + fv1 = make_fv(description="v0 desc") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="v1_field", dtype=Float32), # Schema change + ], + description="v1 desc", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Pin to v0 (definition must match active FV, only version changes) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="v1_field", dtype=Float32), # Keep current schema + ], + description="v1 desc", + version="v0", + ) + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + # Apply new content with another schema change (should create new version) + fv3 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="v1_field", dtype=Float32), + Field(name="v2_field", dtype=Float32), # Another schema change + ], + description="v2 desc after pin", + ) + registry.apply_feature_view(fv3, "test_project", commit=True) + + versions = registry.list_feature_view_versions("driver_stats", "test_project") + # Should have v0, v1, and potentially more versions + assert len(versions) >= 2 + + def test_pin_with_modified_definition_raises(self, registry, make_fv, entity): + # Create v0 + fv1 = make_fv(description="original") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), # Schema change + ], + description="updated", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Attempt to pin to v0 while also changing schema (sneaky change) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), + Field(name="sneaky_field", dtype=Float32), # Sneaky schema change + ], + description="updated", + version="v0", + ) + with pytest.raises(FeatureViewPinConflict): + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + def test_pin_without_modification_succeeds(self, registry, make_fv, entity): + # Create v0 + fv1 = make_fv(description="original") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), # Schema change + ], + description="updated", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Pin to v0 with same definition as active (only version changes) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), # Keep current schema + ], + description="updated", + version="v0", + ) + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + # Verify active entry has v0's content + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.description == "original" + assert active_fv.version == "v0" + + def test_get_feature_view_by_version(self, registry, make_fv, entity): + # Create v0 + fv1 = make_fv(description="version zero") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 with schema change and different description + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="v1_field", dtype=Float32), # Schema change + ], + description="version one", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Retrieve v0 snapshot + fv_v0 = registry.get_feature_view_by_version("driver_stats", "test_project", 0) + assert fv_v0.description == "version zero" + assert fv_v0.current_version_number == 0 + + # Retrieve v1 snapshot + fv_v1 = registry.get_feature_view_by_version("driver_stats", "test_project", 1) + assert fv_v1.description == "version one" + assert fv_v1.current_version_number == 1 + + def test_get_feature_view_by_version_not_found(self, registry, make_fv): + fv = make_fv() + registry.apply_feature_view(fv, "test_project", commit=True) + + with pytest.raises(FeatureViewVersionNotFound): + registry.get_feature_view_by_version("driver_stats", "test_project", 99) + + def test_version_in_proto_roundtrip(self, registry, make_fv): + fv = make_fv(version="v3") + # Manually set version number for testing + fv.current_version_number = 3 + + proto = fv.to_proto() + assert proto.spec.version == "v3" + assert proto.meta.current_version_number == 3 + + fv2 = FeatureView.from_proto(proto) + assert fv2.version == "v3" + assert fv2.current_version_number == 3 + + +class TestRefinedVersioningBehavior: + """Test that only schema and UDF changes create new versions.""" + + def test_metadata_changes_no_new_version(self, registry, make_fv): + """Verify metadata changes don't create new versions.""" + fv = make_fv(description="original description", tags={"team": "ml"}) + registry.apply_feature_view(fv, "test_project", commit=True) + + # Modify only metadata + fv_updated = make_fv( + description="updated description", + tags={"team": "ml", "env": "prod"}, + owner="new_owner@company.com", + ) + registry.apply_feature_view(fv_updated, "test_project", commit=True) + + # Should not create new version + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 # Still just v0 + assert versions[0]["version_number"] == 0 + + def test_schema_changes_create_new_version(self, registry, make_fv, entity): + """Verify schema changes create new versions.""" + fv = make_fv() + registry.apply_feature_view(fv, "test_project", commit=True) + + # Add a new feature (schema change) + fv_with_new_feature = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_feature", dtype=Float32), # New field + ], + description="same description", # Keep same metadata + ) + registry.apply_feature_view(fv_with_new_feature, "test_project", commit=True) + + # Should create new version + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 2 # v0 and v1 + assert versions[1]["version_number"] == 1 + + def test_configuration_changes_no_new_version(self, registry, make_fv): + """Verify configuration changes don't create new versions.""" + fv = make_fv(online=True, offline=True) + registry.apply_feature_view(fv, "test_project", commit=True) + + # Change configuration fields + fv_config_updated = make_fv( + online=False, # Configuration change + offline=False, # Configuration change + description="same description", # Keep same metadata + ) + registry.apply_feature_view(fv_config_updated, "test_project", commit=True) + + # Should not create new version + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 # Still just v0 + assert versions[0]["version_number"] == 0 + + def test_entity_changes_create_new_version(self, registry, make_fv): + """Verify entity changes create new versions.""" + fv = make_fv() + registry.apply_feature_view(fv, "test_project", commit=True) + + # Create new entity and add it (schema change) + new_entity = Entity( + name="vehicle_id", + join_keys=["vehicle_id"], + value_type=ValueType.INT64, # Match the field type + ) + + fv_with_new_entity = FeatureView( + name="driver_stats", + entities=[ + Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ), + new_entity, + ], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="vehicle_id", dtype=Int64), # New entity field + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + description="same description", + ) + registry.apply_feature_view(fv_with_new_entity, "test_project", commit=True) + + # Should create new version due to entity change + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 2 # v0 and v1 + assert versions[1]["version_number"] == 1 + + def test_stream_feature_view_udf_changes_create_new_version( + self, registry, make_sfv + ): + """Verify UDF changes create new versions (StreamFeatureView).""" + + def original_transform(df): + return df + + def updated_transform(df): + df["new_col"] = df["trips_today"] * 2 + return df + + sfv = make_sfv(udf=original_transform) + registry.apply_feature_view(sfv, "test_project", commit=True) + + sfv_updated = make_sfv( + udf=updated_transform, + description="same description", # Keep same metadata + ) + registry.apply_feature_view(sfv_updated, "test_project", commit=True) + + # Should create new version due to UDF change + versions = registry.list_feature_view_versions( + "driver_stats_stream", "test_project" + ) + assert len(versions) == 2 # v0 and v1 + + # TODO: Add tests for OnDemandFeatureView once transformation comparison issues are resolved + # The current issue is that PythonTransformation.__eq__ has strict type checking + # that prevents proper comparison between objects created at different times + + +class TestVersionMetadataIntegration: + """Integration tests for version metadata functionality in responses.""" + + def test_version_metadata_disabled_by_default(self, registry, make_fv): + """Test that version metadata is not included by default.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + # Create and register a versioned feature view + fv = make_fv(description="test version metadata") + registry.apply_feature_view(fv, "test_project", commit=True) + + # Get the feature view with version info + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert hasattr(active_fv, "current_version_number") + + # Mock response generation without version metadata + response = GetOnlineFeaturesResponse() + _populate_response_from_feature_data( + requested_features=["trips_today"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=True, + table=active_fv, + output_len=0, + include_feature_view_version_metadata=False, # Default behavior + ) + + # Verify no version metadata is included + assert len(response.metadata.feature_view_metadata) == 0 + # Feature names should still be populated + assert len(response.metadata.feature_names.val) == 1 + + def test_version_metadata_included_when_requested(self, registry, make_fv, entity): + """Test that version metadata is included when requested.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + # Create v0 + fv1 = make_fv(description="first version") + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create v1 by modifying schema + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="total_earnings", dtype=Float32), # New field + ], + description="second version", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Get v1 (latest version) + active_fv = registry.get_feature_view("driver_stats", "test_project") + assert active_fv.current_version_number == 1 + + # Mock response generation with version metadata + response = GetOnlineFeaturesResponse() + _populate_response_from_feature_data( + requested_features=["trips_today", "total_earnings"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, # Test without prefixes + table=active_fv, + output_len=0, + include_feature_view_version_metadata=True, # Enable metadata + ) + + # Verify version metadata is included + assert len(response.metadata.feature_view_metadata) == 1 + fv_metadata = response.metadata.feature_view_metadata[0] + assert fv_metadata.name == "driver_stats" + assert fv_metadata.version == 1 + + # Verify feature names are clean (no @v1 suffix) + feature_names = list(response.metadata.feature_names.val) + assert feature_names == ["trips_today", "total_earnings"] + assert all("@" not in name for name in feature_names) + + def test_version_metadata_clean_names_with_prefixes(self, registry, make_fv): + """Test that feature names are clean even with full_feature_names=True.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + # Create versioned feature view + fv = make_fv(description="test clean names") + registry.apply_feature_view(fv, "test_project", commit=True) + active_fv = registry.get_feature_view("driver_stats", "test_project") + + # Test with full feature names (prefixed) + response = GetOnlineFeaturesResponse() + _populate_response_from_feature_data( + requested_features=["trips_today"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=True, # Enable prefixes + table=active_fv, + output_len=0, + include_feature_view_version_metadata=True, + ) + + # Feature names should be prefixed but clean (no @v0) + feature_names = list(response.metadata.feature_names.val) + assert len(feature_names) == 1 + assert feature_names[0] == "driver_stats__trips_today" # Clean prefix + assert "@" not in feature_names[0] # No version in name + + # Version metadata should be separate + assert len(response.metadata.feature_view_metadata) == 1 + assert response.metadata.feature_view_metadata[0].name == "driver_stats" + assert response.metadata.feature_view_metadata[0].version == 0 + + def test_version_metadata_multiple_feature_views(self, registry, entity): + """Test version metadata with multiple feature views.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + # Create first feature view + fv1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + description="driver features", + ) + registry.apply_feature_view(fv1, "test_project", commit=True) + + # Create second feature view + fv2 = FeatureView( + name="user_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="total_bookings", dtype=Int64), + ], + description="user features", + ) + registry.apply_feature_view(fv2, "test_project", commit=True) + + # Modify user_stats to create v1 + fv2_v1 = FeatureView( + name="user_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="total_bookings", dtype=Int64), + Field(name="cancellation_rate", dtype=Float32), # New field + ], + description="user features v1", + ) + registry.apply_feature_view(fv2_v1, "test_project", commit=True) + + # Get feature views + driver_fv = registry.get_feature_view("driver_stats", "test_project") # v0 + user_fv = registry.get_feature_view("user_stats", "test_project") # v1 + + # Simulate processing multiple feature views in response + response = GetOnlineFeaturesResponse() + + # Process first feature view + _populate_response_from_feature_data( + requested_features=["trips_today"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, + table=driver_fv, + output_len=0, + include_feature_view_version_metadata=True, + ) + + # Process second feature view + _populate_response_from_feature_data( + requested_features=["total_bookings", "cancellation_rate"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, + table=user_fv, + output_len=0, + include_feature_view_version_metadata=True, + ) + + # Verify both feature views are in metadata + assert len(response.metadata.feature_view_metadata) == 2 + + fv_metadata_by_name = { + fvm.name: fvm for fvm in response.metadata.feature_view_metadata + } + assert "driver_stats" in fv_metadata_by_name + assert "user_stats" in fv_metadata_by_name + + # Check versions + assert fv_metadata_by_name["driver_stats"].version == 0 + assert fv_metadata_by_name["user_stats"].version == 1 + + # Verify feature names are clean + feature_names = list(response.metadata.feature_names.val) + assert feature_names == ["trips_today", "total_bookings", "cancellation_rate"] + assert all("@" not in name for name in feature_names) + + def test_version_metadata_prevents_duplicates(self, registry, make_fv): + """Test that duplicate feature view metadata is not added.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + fv = make_fv(description="test duplicates") + registry.apply_feature_view(fv, "test_project", commit=True) + active_fv = registry.get_feature_view("driver_stats", "test_project") + + response = GetOnlineFeaturesResponse() + + # Process same feature view twice (simulating multiple features from same view) + _populate_response_from_feature_data( + requested_features=["trips_today"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, + table=active_fv, + output_len=0, + include_feature_view_version_metadata=True, + ) + + _populate_response_from_feature_data( + requested_features=["avg_rating"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, + table=active_fv, + output_len=0, + include_feature_view_version_metadata=True, + ) + + # Should only have one metadata entry despite processing twice + assert len(response.metadata.feature_view_metadata) == 1 + assert response.metadata.feature_view_metadata[0].name == "driver_stats" + + # But should have both feature names + feature_names = list(response.metadata.feature_names.val) + assert len(feature_names) == 2 + assert "trips_today" in feature_names + assert "avg_rating" in feature_names + + def test_version_metadata_backward_compatibility(self, registry, make_fv): + """Test that existing code without version metadata still works.""" + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.utils import _populate_response_from_feature_data + + fv = make_fv(description="backward compatibility test") + registry.apply_feature_view(fv, "test_project", commit=True) + active_fv = registry.get_feature_view("driver_stats", "test_project") + + # Test calling without the new parameter (should default to False) + response = GetOnlineFeaturesResponse() + _populate_response_from_feature_data( + requested_features=["trips_today"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=True, + table=active_fv, + output_len=0, + # Note: include_feature_view_version_metadata parameter omitted + ) + + # Should work and not include version metadata + assert len(response.metadata.feature_view_metadata) == 0 + assert len(response.metadata.feature_names.val) == 1 + + +class TestOnlineVersioningDisabled: + """Tests that online versioning guard works for version-qualified refs.""" + + def test_version_qualified_ref_raises_when_online_versioning_disabled( + self, registry_no_online_versioning, make_fv, entity + ): + """Using @v2 refs raises ValueError when online versioning is disabled.""" + from feast.utils import _get_feature_views_to_use + + fv = make_fv(description="test fv") + registry_no_online_versioning.apply_feature_view( + fv, "test_project", commit=True + ) + + # Create v1 with schema change + fv2 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_field", dtype=Float32), + ], + description="version one", + ) + registry_no_online_versioning.apply_feature_view( + fv2, "test_project", commit=True + ) + + # Version-qualified ref should raise + with pytest.raises(ValueError, match="online versioning is disabled"): + _get_feature_views_to_use( + registry=registry_no_online_versioning, + project="test_project", + features=["driver_stats@v1:trips_today"], + allow_cache=False, + hide_dummy_entity=False, + ) + + +class TestFeatureServiceVersioningGates: + """Tests that feature services are gated when referencing versioned feature views.""" + + @pytest.fixture + def versioned_fv_and_entity(self): + """Create a versioned feature view (v1) and its entity.""" + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + # v0 definition + fv_v0 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + description="v0", + ) + # v1 definition (schema change) + fv_v1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + description="v1", + ) + return entity, fv_v0, fv_v1 + + @pytest.fixture + def unversioned_fv_and_entity(self): + """Create an unversioned feature view (v0 only) and its entity.""" + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + fv = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + description="only version", + ) + return entity, fv + + def _make_store(self, tmpdir, enable_versioning=False): + """Create a FeatureStore with optional online versioning.""" + registry_path = os.path.join(tmpdir, "registry.db") + online_path = os.path.join(tmpdir, "online.db") + return FeatureStore( + config=RepoConfig( + registry=RegistryConfig( + path=registry_path, + enable_online_feature_view_versioning=enable_versioning, + ), + project="test_project", + provider="local", + online_store=SqliteOnlineStoreConfig(path=online_path), + entity_key_serialization_version=3, + ) + ) + + def test_feature_service_apply_succeeds_with_versioned_fv_when_flag_off( + self, versioned_fv_and_entity + ): + """Apply a feature service referencing a versioned FV with flag off -> succeeds.""" + entity, fv_v0, fv_v1 = versioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=False) + + # Apply v0 first, then v1 to create version history + store.apply([entity, fv_v0]) + store.apply([entity, fv_v1]) + + # Now create a feature service referencing the versioned FV + fs = FeatureService( + name="driver_service", + features=[fv_v1], + ) + store.apply([fs]) # Should not raise + + def test_feature_service_apply_succeeds_with_versioned_fv_when_flag_on( + self, versioned_fv_and_entity + ): + """Apply a feature service referencing a versioned FV with flag on -> succeeds.""" + entity, fv_v0, fv_v1 = versioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=True) + + # Apply v0 first, then v1 to create version history + store.apply([entity, fv_v0]) + store.apply([entity, fv_v1]) + + # Feature service referencing versioned FV should succeed + fs = FeatureService( + name="driver_service", + features=[fv_v1], + ) + store.apply([fs]) # Should not raise + + def test_feature_service_retrieval_succeeds_with_versioned_fv_when_flag_off( + self, versioned_fv_and_entity + ): + """get_online_features with a feature service referencing a versioned FV, flag off -> succeeds.""" + entity, fv_v0, fv_v1 = versioned_fv_and_entity + from feast.utils import _get_feature_views_to_use + + with tempfile.TemporaryDirectory() as tmpdir: + # First apply with flag on so the feature service can be registered + store_on = self._make_store(tmpdir, enable_versioning=True) + store_on.apply([entity, fv_v0]) + store_on.apply([entity, fv_v1]) + fs = FeatureService( + name="driver_service", + features=[fv_v1], + ) + store_on.apply([fs]) + + # Now create a store with the flag off to test retrieval + store_off = self._make_store(tmpdir, enable_versioning=False) + registered_fs = store_off.registry.get_feature_service( + "driver_service", "test_project" + ) + + fvs, _ = _get_feature_views_to_use( + registry=store_off.registry, + project="test_project", + features=registered_fs, + allow_cache=False, + hide_dummy_entity=False, + ) + + assert len(fvs) == 1 + + def test_feature_service_with_unversioned_fv_succeeds( + self, unversioned_fv_and_entity + ): + """Feature service with v0 FV works fine regardless of flag.""" + entity, fv = unversioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=False) + + # Apply unversioned FV and feature service + fs = FeatureService( + name="driver_service", + features=[fv], + ) + store.apply([entity, fv, fs]) # Should not raise + + def test_feature_service_serves_versioned_fv_when_flag_on( + self, versioned_fv_and_entity + ): + """With online versioning on, FeatureService projections do not carry version_tag; + the FV in the registry carries current_version_number.""" + from feast.utils import _get_feature_views_to_use + + entity, fv_v0, fv_v1 = versioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=True) + + # Apply v0 then v1 to create version history + store.apply([entity, fv_v0]) + store.apply([entity, fv_v1]) + + # Create and apply a feature service referencing the versioned FV + fs = FeatureService( + name="driver_service", + features=[fv_v1], + ) + store.apply([fs]) + + # Retrieve the registered feature service + registered_fs = store.registry.get_feature_service( + "driver_service", "test_project" + ) + + fvs, _ = _get_feature_views_to_use( + registry=store.registry, + project="test_project", + features=registered_fs, + allow_cache=False, + hide_dummy_entity=False, + ) + + assert len(fvs) == 1 + assert fvs[0].projection.version_tag is None + assert fvs[0].projection.name_to_use() == "driver_stats" + + # Verify the FV in the registry has the correct version + fv_from_registry = store.registry.get_feature_view( + "driver_stats", "test_project" + ) + assert fv_from_registry.current_version_number == 1 + + def test_feature_service_feature_refs_are_plain_when_flag_on( + self, versioned_fv_and_entity + ): + """With online versioning on, _get_features() produces plain (non-versioned) refs for FeatureService.""" + from feast.utils import _get_features + + entity, fv_v0, fv_v1 = versioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=True) + + # Apply v0 then v1 to create version history + store.apply([entity, fv_v0]) + store.apply([entity, fv_v1]) + + # Create and apply a feature service referencing the versioned FV + fs = FeatureService( + name="driver_service", + features=[fv_v1], + ) + store.apply([fs]) + + # Retrieve the registered feature service + registered_fs = store.registry.get_feature_service( + "driver_service", "test_project" + ) + + refs = _get_features( + registry=store.registry, + project="test_project", + features=registered_fs, + allow_cache=False, + ) + + # Refs should be plain (no version qualifier) + for ref in refs: + assert "@v" not in ref, f"Expected plain ref, got: {ref}" + + # Check specific ref format + assert "driver_stats:trips_today" in refs + + def test_unpin_from_versioned_to_latest(self, versioned_fv_and_entity): + """Pin a FV to v1, then apply with version='latest' (no schema change) -> unpinned.""" + entity, fv_v0, fv_v1 = versioned_fv_and_entity + + with tempfile.TemporaryDirectory() as tmpdir: + store = self._make_store(tmpdir, enable_versioning=True) + + # Apply v0 then v1 to create version history (v1 has schema change) + store.apply([entity, fv_v0]) + store.apply([entity, fv_v1]) + + # Verify it's pinned to v1 + reloaded = store.registry.get_feature_view("driver_stats", "test_project") + assert reloaded.current_version_number == 1 + + # Now re-apply the same schema with version="latest" to unpin + fv_latest = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + version="latest", + description="v1", + ) + store.apply([entity, fv_latest]) + + # Reload and verify unpinned + reloaded = store.registry.get_feature_view("driver_stats", "test_project") + assert reloaded.current_version_number is None + assert reloaded.version == "latest" + + +class TestNoPromote: + """Tests for the no_promote flag on apply_feature_view.""" + + def test_no_promote_saves_version_without_updating_active( + self, registry, make_fv, entity + ): + """Apply v0, then schema change with no_promote=True. + Version record for v1 should exist, but active FV keeps v0's schema.""" + fv0 = make_fv(description="original v0") + registry.apply_feature_view(fv0, "test_project", commit=True) + + # Schema change with no_promote + fv1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="new_feature", dtype=Float32), # Schema change + ], + description="staged v1", + ) + registry.apply_feature_view(fv1, "test_project", commit=True, no_promote=True) + + # Version v1 should exist in history + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 2 + assert versions[0]["version_number"] == 0 + assert versions[1]["version_number"] == 1 + + # Active FV should still be v0 (initial apply with version="latest" + # has current_version_number=None since proto 0 maps to None for latest) + active = registry.get_feature_view("driver_stats", "test_project") + assert active.current_version_number is None + assert active.description == "original v0" + # v0 schema has 3 fields (driver_id, trips_today, avg_rating) + feature_names = {f.name for f in active.schema} + assert "new_feature" not in feature_names + + def test_no_promote_then_regular_apply_promotes(self, registry, make_fv, entity): + """Apply with no_promote, then re-apply the same schema change without + no_promote. The new version should now be promoted to active.""" + fv0 = make_fv(description="original") + registry.apply_feature_view(fv0, "test_project", commit=True) + + # Schema change with no_promote + fv1_schema = [ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="extra", dtype=Float32), + ] + fv1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=fv1_schema, + description="staged v1", + ) + registry.apply_feature_view(fv1, "test_project", commit=True, no_promote=True) + + # Now apply same schema change without no_promote + fv1_promote = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=fv1_schema, + description="promoted v1", + ) + registry.apply_feature_view( + fv1_promote, "test_project", commit=True, no_promote=False + ) + + # Active FV should now have the new schema + active = registry.get_feature_view("driver_stats", "test_project") + feature_names = {f.name for f in active.schema} + assert "extra" in feature_names + + def test_no_promote_then_explicit_pin_promotes(self, registry, make_fv, entity): + """Apply with no_promote, then pin to v1. Active should now be v1.""" + fv0 = make_fv(description="original") + registry.apply_feature_view(fv0, "test_project", commit=True) + + # Schema change with no_promote + fv1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="pinned_feature", dtype=Float32), + ], + description="staged v1", + ) + registry.apply_feature_view(fv1, "test_project", commit=True, no_promote=True) + + # Active is still v0 (initial apply with version="latest" + # has current_version_number=None since proto 0 maps to None for latest) + active = registry.get_feature_view("driver_stats", "test_project") + assert active.current_version_number is None + + # Pin to v1 (user's definition must match current active, only version changes) + fv_pin = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + ], + description="original", + version="v1", + ) + registry.apply_feature_view(fv_pin, "test_project", commit=True) + + # Active should now be v1's snapshot + active = registry.get_feature_view("driver_stats", "test_project") + assert active.current_version_number == 1 + feature_names = {f.name for f in active.schema} + assert "pinned_feature" in feature_names + + def test_no_promote_noop_without_schema_change(self, registry, make_fv): + """Apply with no_promote but no schema change — metadata-only update, + no new version should be created.""" + fv0 = make_fv(description="original") + registry.apply_feature_view(fv0, "test_project", commit=True) + + # Same schema, different description (metadata-only) + fv_same = make_fv(description="updated description only") + registry.apply_feature_view( + fv_same, "test_project", commit=True, no_promote=True + ) + + # Still only v0 + versions = registry.list_feature_view_versions("driver_stats", "test_project") + assert len(versions) == 1 + assert versions[0]["version_number"] == 0 + + def test_no_promote_version_accessible_by_explicit_ref( + self, registry, make_fv, entity + ): + """After no_promote apply, the new version should be accessible via + get_feature_view_by_version().""" + fv0 = make_fv(description="original") + registry.apply_feature_view(fv0, "test_project", commit=True) + + # Schema change with no_promote + fv1 = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + Field(name="avg_rating", dtype=Float32), + Field(name="explicit_feature", dtype=Float32), + ], + description="staged v1", + ) + registry.apply_feature_view(fv1, "test_project", commit=True, no_promote=True) + + # Should be accessible by explicit version ref + v1_fv = registry.get_feature_view_by_version("driver_stats", "test_project", 1) + assert v1_fv.current_version_number == 1 + feature_names = {f.name for f in v1_fv.schema} + assert "explicit_feature" in feature_names + + # v0 should also still be accessible + v0_fv = registry.get_feature_view_by_version("driver_stats", "test_project", 0) + assert v0_fv.current_version_number == 0 + feature_names_v0 = {f.name for f in v0_fv.schema} + assert "explicit_feature" not in feature_names_v0 + + +class TestFeatureViewNameValidation: + """Tests that feature view names with reserved characters are rejected on apply.""" + + def test_apply_feature_view_with_at_sign_raises(self, registry, entity): + """Applying a feature view with '@' in its name should raise ValueError.""" + fv = FeatureView( + name="my_weirdly_@_named_fv", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + ) + with pytest.raises(ValueError, match="must not contain '@'"): + registry.apply_feature_view(fv, "test_project", commit=True) + + def test_apply_feature_view_with_colon_raises(self, registry, entity): + """Applying a feature view with ':' in its name should raise ValueError.""" + fv = FeatureView( + name="my:weird:fv", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="trips_today", dtype=Int64), + ], + ) + with pytest.raises(ValueError, match="must not contain ':'"): + registry.apply_feature_view(fv, "test_project", commit=True) diff --git a/sdk/python/tests/integration/rest_api/conftest.py b/sdk/python/tests/integration/rest_api/conftest.py index 6e55d5825f2..d7aa0b4a3c5 100644 --- a/sdk/python/tests/integration/rest_api/conftest.py +++ b/sdk/python/tests/integration/rest_api/conftest.py @@ -37,7 +37,12 @@ def get(self, endpoint, params=None): return requests.get(url, params=params, verify=False) -def _wait_for_http_ready(route_url: str, timeout: int = 180, interval: int = 5) -> None: +def _wait_for_http_ready( + route_url: str, + timeout: int = 300, + interval: int = 5, + initial_delay: int = 30, +) -> None: """ Poll the HTTP endpoint until it returns a non-502 response. @@ -46,9 +51,15 @@ def _wait_for_http_ready(route_url: str, timeout: int = 180, interval: int = 5) start before the Feast server is ready, causing all requests to return 502. """ health_url = f"{route_url}/api/v1/projects" - deadline = time.time() + timeout last_status = None + if initial_delay > 0: + print( + f"\n Waiting {initial_delay}s for backend to start after apply/dataset creation..." + ) + time.sleep(initial_delay) + + deadline = time.time() + timeout print( f"\n Waiting for HTTP endpoint to become ready (timeout={timeout}s): {health_url}" ) diff --git a/sdk/python/tests/integration/rest_api/resource/postgres.yaml b/sdk/python/tests/integration/rest_api/resource/postgres.yaml index ca0de81d15c..34ac2eb620b 100644 --- a/sdk/python/tests/integration/rest_api/resource/postgres.yaml +++ b/sdk/python/tests/integration/rest_api/resource/postgres.yaml @@ -25,7 +25,7 @@ spec: spec: containers: - name: postgres - image: 'postgres:16-alpine' + image: 'quay.io/feastdev-ci/feast-test-images:postgres-17-alpine' ports: - containerPort: 5432 envFrom: diff --git a/sdk/python/tests/integration/rest_api/resource/redis.yaml b/sdk/python/tests/integration/rest_api/resource/redis.yaml index 297205b8a79..df8187daeec 100644 --- a/sdk/python/tests/integration/rest_api/resource/redis.yaml +++ b/sdk/python/tests/integration/rest_api/resource/redis.yaml @@ -15,7 +15,8 @@ spec: spec: containers: - name: redis - image: 'quay.io/sclorg/redis-7-c9s' + image: 'quay.io/feastdev-ci/feast-test-images:redis-7-alpine' + command: ["redis-server", "--save", ""] ports: - containerPort: 6379 env: diff --git a/sdk/python/tests/integration/test_mcp_feature_server.py b/sdk/python/tests/integration/test_mcp_feature_server.py index 6920c2e3f2a..61f45e37314 100644 --- a/sdk/python/tests/integration/test_mcp_feature_server.py +++ b/sdk/python/tests/integration/test_mcp_feature_server.py @@ -4,10 +4,13 @@ import pytest from fastapi import FastAPI from fastapi.testclient import TestClient +from pydantic import ValidationError from feast.feature_store import FeatureStore from feast.infra.mcp_servers.mcp_config import McpFeatureServerConfig +pytestmark = pytest.mark.integration + class TestMCPFeatureServerIntegration(unittest.TestCase): """Integration tests for MCP feature server functionality.""" @@ -49,7 +52,7 @@ def test_mcp_server_functionality_with_mock_store(self): mcp_server_version="1.0.0", ) - mock_mcp_instance = Mock() + mock_mcp_instance = Mock(spec_set=["mount_sse", "mount_http", "mount"]) mock_fast_api_mcp.return_value = mock_mcp_instance result = add_mcp_support_to_app(mock_app, mock_store, config) @@ -58,7 +61,7 @@ def test_mcp_server_functionality_with_mock_store(self): self.assertIsNotNone(result) self.assertEqual(result, mock_mcp_instance) mock_fast_api_mcp.assert_called_once() - mock_mcp_instance.mount.assert_called_once() + mock_mcp_instance.mount_sse.assert_called_once() @patch("feast.infra.mcp_servers.mcp_server.MCP_AVAILABLE", True) @patch("feast.infra.mcp_servers.mcp_server.FastApiMCP") @@ -77,7 +80,7 @@ def test_complete_mcp_setup_flow(self, mock_fast_api_mcp): transformation_service_endpoint="localhost:6566", ) - mock_mcp_instance = Mock() + mock_mcp_instance = Mock(spec_set=["mount_sse", "mount_http", "mount"]) mock_fast_api_mcp.return_value = mock_mcp_instance # Execute the flow @@ -90,7 +93,7 @@ def test_complete_mcp_setup_flow(self, mock_fast_api_mcp): name="e2e-test-server", description="Feast Feature Store MCP Server - Access feature store data and operations through MCP", ) - mock_mcp_instance.mount.assert_called_once() + mock_mcp_instance.mount_sse.assert_called_once() self.assertEqual(result, mock_mcp_instance) @pytest.mark.skipif( @@ -160,36 +163,29 @@ def test_feature_server_with_mcp_config(self): def test_mcp_server_configuration_validation(self): """Test comprehensive MCP server configuration validation.""" # Test various configuration combinations - test_configs = [ - { - "enabled": True, - "mcp_enabled": True, - "mcp_server_name": "test-server-1", - "mcp_server_version": "1.0.0", - "mcp_transport": "sse", - }, - { - "enabled": True, - "mcp_enabled": True, - "mcp_server_name": "test-server-2", - "mcp_server_version": "2.0.0", - "mcp_transport": "websocket", - }, - { - "enabled": False, - "mcp_enabled": False, - "mcp_server_name": "disabled-server", - "mcp_server_version": "1.0.0", - "mcp_transport": None, - }, - ] - - for config_dict in test_configs: - config = McpFeatureServerConfig(**config_dict) - self.assertEqual(config.enabled, config_dict["enabled"]) - self.assertEqual(config.mcp_enabled, config_dict["mcp_enabled"]) - self.assertEqual(config.mcp_server_name, config_dict["mcp_server_name"]) - self.assertEqual( - config.mcp_server_version, config_dict["mcp_server_version"] + for transport in ["sse", "http"]: + config = McpFeatureServerConfig( + enabled=True, + mcp_enabled=True, + mcp_server_name="test-server", + mcp_server_version="1.0.0", + mcp_transport=transport, + ) + self.assertEqual(config.mcp_transport, transport) + + config_default = McpFeatureServerConfig( + enabled=True, + mcp_enabled=True, + mcp_server_name="test-server-default", + mcp_server_version="1.0.0", + ) + self.assertEqual(config_default.mcp_transport, "sse") + + with self.assertRaises(ValidationError): + McpFeatureServerConfig( + enabled=True, + mcp_enabled=True, + mcp_server_name="bad-transport", + mcp_server_version="1.0.0", + mcp_transport="websocket", ) - self.assertEqual(config.mcp_transport, config_dict["mcp_transport"]) diff --git a/sdk/python/tests/integration/test_mlflow_integration.py b/sdk/python/tests/integration/test_mlflow_integration.py new file mode 100644 index 00000000000..c09e7d444f2 --- /dev/null +++ b/sdk/python/tests/integration/test_mlflow_integration.py @@ -0,0 +1,1116 @@ +# Copyright 2026 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +from datetime import datetime, timedelta + +import numpy as np +import pandas as pd +import pytest + +from feast import Entity, FeatureService, FeatureStore, FeatureView, Field, FileSource +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.repo_config import RepoConfig +from feast.types import Float32, Int64 + +mlflow = pytest.importorskip("mlflow", reason="mlflow is not installed") +from mlflow.tracking import MlflowClient # noqa: E402 + +import feast.mlflow # noqa: E402 +from feast.mlflow_integration import ( # noqa: E402 + FeastMlflowEntityDfError, + FeastMlflowModelResolutionError, + MlflowConfig, +) +from feast.mlflow_integration.config import ( # noqa: E402 + MLFLOW_TAG_TRUNCATION_LIMIT, + resolve_tracking_uri, +) + +# --------------------------------------------------------------------------- +# Fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture(autouse=True) +def _isolate_mlflow_globals(): + """Reset module-level mlflow caching between tests.""" + feast.mlflow._client = None + feast.mlflow._registered_store = None + yield + + +@pytest.fixture() +def tracking_uri(tmp_path): + uri = f"sqlite:///{tmp_path}/mlflow.db" + mlflow.set_tracking_uri(uri) + mlflow.set_experiment("test_mlflow") + yield uri + mlflow.set_tracking_uri("") + + +@pytest.fixture() +def driver_parquet(tmp_path): + data_dir = tmp_path / "data" + data_dir.mkdir() + + end = datetime.now().replace(microsecond=0, second=0, minute=0) + start = end - timedelta(days=7) + timestamps = pd.date_range(start, end, freq="h") + driver_ids = [1001, 1002, 1003] + + np.random.seed(42) + rows = [ + { + "driver_id": did, + "event_timestamp": ts, + "created": ts, + "conv_rate": float(np.random.uniform(0, 1)), + "acc_rate": float(np.random.uniform(0, 1)), + "avg_daily_trips": int(np.random.randint(1, 100)), + } + for ts in timestamps + for did in driver_ids + ] + df = pd.DataFrame(rows) + path = str(data_dir / "driver_stats.parquet") + df.to_parquet(path) + return tmp_path, path + + +@pytest.fixture() +def feast_objects(driver_parquet): + _, parquet_path = driver_parquet + + driver = Entity(name="driver", join_keys=["driver_id"]) + source = FileSource( + name="driver_stats_source", + path=parquet_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + fv = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=7), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + ], + online=True, + source=source, + ) + fs = FeatureService(name="driver_activity_v1", features=[fv]) + return driver, source, fv, fs + + +def _make_store( + tmp_path, + tracking_uri, + *, + enabled=True, + auto_log=True, + auto_log_entity_df=True, + entity_df_max_rows=100_000, +): + data_dir = tmp_path / "data" + data_dir.mkdir(exist_ok=True) + + config = RepoConfig( + project="test_mlflow", + provider="local", + registry=str(data_dir / "registry.db"), + online_store=SqliteOnlineStoreConfig(path=str(data_dir / "online.db")), + entity_key_serialization_version=3, + mlflow=MlflowConfig( + enabled=enabled, + tracking_uri=tracking_uri, + auto_log=auto_log, + auto_log_entity_df=auto_log_entity_df, + entity_df_max_rows=entity_df_max_rows, + ), + ) + return FeatureStore(config=config) + + +@pytest.fixture() +def store_enabled(driver_parquet, tracking_uri, feast_objects): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri) + store.apply(list(feast_objects)) + store.materialize( + start_date=datetime.now() - timedelta(days=7), + end_date=datetime.now(), + ) + return store + + +@pytest.fixture() +def entity_df(): + np.random.seed(42) + n = 50 + return pd.DataFrame( + { + "driver_id": np.random.choice([1001, 1002, 1003], n), + "event_timestamp": [ + datetime.now() - timedelta(hours=i % 48) for i in range(n) + ], + "label": np.random.randint(0, 2, n), + } + ) + + +class TestMlflowConfig: + @pytest.mark.integration + def test_defaults(self): + cfg = MlflowConfig() + assert cfg.enabled is False + assert cfg.auto_log is True + assert cfg.auto_log_entity_df is False + assert cfg.entity_df_max_rows == 100_000 + assert cfg.tracking_uri is None + + @pytest.mark.integration + def test_get_tracking_uri_explicit(self): + cfg = MlflowConfig(tracking_uri="http://example.com:5000") + assert cfg.get_tracking_uri() == "http://example.com:5000" + + @pytest.mark.integration + def test_get_tracking_uri_env_fallback(self, monkeypatch): + monkeypatch.setenv("MLFLOW_TRACKING_URI", "http://env-uri:5000") + cfg = MlflowConfig() + assert cfg.get_tracking_uri() == "http://env-uri:5000" + + @pytest.mark.integration + def test_get_tracking_uri_none_when_unset(self, monkeypatch): + monkeypatch.delenv("MLFLOW_TRACKING_URI", raising=False) + cfg = MlflowConfig() + assert cfg.get_tracking_uri() is None + + @pytest.mark.integration + def test_resolve_tracking_uri_priority(self, monkeypatch): + monkeypatch.setenv("MLFLOW_TRACKING_URI", "http://env:5000") + assert resolve_tracking_uri("http://explicit:5000") == "http://explicit:5000" + assert resolve_tracking_uri(None) == "http://env:5000" + monkeypatch.delenv("MLFLOW_TRACKING_URI") + assert resolve_tracking_uri(None) is None + + +class TestLogFeatureRetrieval: + @pytest.mark.integration + def test_logs_all_tags_and_metric(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + refs = [ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "transformed:conv_rate_plus_val1", + ] + + with mlflow.start_run(run_name="test_tags") as run: + result = store_enabled.mlflow.log_feature_retrieval( + feature_refs=refs, + entity_count=200, + duration_seconds=0.1234, + retrieval_type="historical", + feature_service_name="driver_activity_v1", + ) + + assert result is True + data = client.get_run(run.info.run_id) + tags = data.data.tags + + assert tags["feast.project"] == "test_mlflow" + assert tags["feast.retrieval_type"] == "historical" + assert tags["feast.feature_service"] == "driver_activity_v1" + assert tags["feast.entity_count"] == "200" + assert tags["feast.feature_count"] == "3" + assert "driver_hourly_stats" in tags["feast.feature_views"] + assert "transformed" in tags["feast.feature_views"] + assert "driver_hourly_stats:conv_rate" in tags["feast.feature_refs"] + assert data.data.metrics["feast.job_submission_sec"] == 0.1234 + + @pytest.mark.integration + def test_noop_without_active_run(self, store_enabled, tracking_uri): + result = store_enabled.mlflow.log_feature_retrieval( + feature_refs=["fv:feat"], + entity_count=1, + duration_seconds=0.01, + ) + assert result is False + + @pytest.mark.integration + def test_feature_views_sorted_and_deduped(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + refs = ["z_view:f1", "a_view:f2", "z_view:f3", "a_view:f4"] + + with mlflow.start_run() as run: + store_enabled.mlflow.log_feature_retrieval( + feature_refs=refs, + entity_count=1, + duration_seconds=0.01, + ) + + tags = client.get_run(run.info.run_id).data.tags + assert tags["feast.feature_views"] == "a_view,z_view" + + @pytest.mark.integration + def test_truncation_for_long_refs(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + refs = [f"fv:feature_{i:04d}" for i in range(500)] + + with mlflow.start_run() as run: + store_enabled.mlflow.log_feature_retrieval( + feature_refs=refs, + entity_count=1, + duration_seconds=0.01, + ) + + tags = client.get_run(run.info.run_id).data.tags + assert len(tags["feast.feature_refs"]) <= MLFLOW_TAG_TRUNCATION_LIMIT + assert tags["feast.feature_refs"].endswith("...") + + @pytest.mark.integration + def test_no_feature_service_tag_when_none(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run() as run: + store_enabled.mlflow.log_feature_retrieval( + feature_refs=["fv:f1"], + entity_count=1, + duration_seconds=0.01, + feature_service=None, + feature_service_name=None, + ) + + tags = client.get_run(run.info.run_id).data.tags + assert "feast.feature_service" not in tags + + +class TestLogTrainingDataset: + @pytest.mark.integration + def test_logs_dataset_input(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + df = pd.DataFrame({"a": [1, 2], "b": [3, 4]}) + + with mlflow.start_run() as run: + result = store_enabled.mlflow.log_training_dataset( + df, dataset_name="test_ds" + ) + + assert result is True + run_data = client.get_run(run.info.run_id) + assert len(run_data.inputs.dataset_inputs) > 0 + assert run_data.inputs.dataset_inputs[0].dataset.name == "test_ds" + + @pytest.mark.integration + def test_noop_without_active_run(self, store_enabled, tracking_uri): + df = pd.DataFrame({"a": [1]}) + assert store_enabled.mlflow.log_training_dataset(df) is False + + +class TestHistoricalAutoLog: + @pytest.mark.integration + def test_tags_logged_via_feature_service( + self, store_enabled, entity_df, tracking_uri + ): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run(run_name="hist_fs") as run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + data = client.get_run(run.info.run_id) + tags = data.data.tags + + assert tags["feast.project"] == "test_mlflow" + assert tags["feast.retrieval_type"] == "historical" + assert tags["feast.feature_service"] == "driver_activity_v1" + assert "driver_hourly_stats" in tags["feast.feature_views"] + assert tags["feast.entity_count"] == str(len(entity_df)) + assert int(tags["feast.feature_count"]) >= 3 + assert data.data.metrics["feast.job_submission_sec"] >= 0 + + @pytest.mark.integration + def test_tags_logged_via_feature_refs(self, store_enabled, entity_df, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run(run_name="hist_refs") as run: + store_enabled.get_historical_features( + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + ], + entity_df=entity_df, + ).to_df() + + tags = client.get_run(run.info.run_id).data.tags + assert tags["feast.retrieval_type"] == "historical" + assert tags["feast.feature_count"] == "2" + assert "driver_hourly_stats:conv_rate" in tags["feast.feature_refs"] + + @pytest.mark.integration + def test_entity_df_artifact_uploaded(self, store_enabled, entity_df, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run(run_name="hist_artifact") as run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + artifacts = [a.path for a in client.list_artifacts(run.info.run_id)] + assert "entity_df.parquet" in artifacts + + tags = client.get_run(run.info.run_id).data.tags + assert tags["feast.entity_df_rows"] == str(len(entity_df)) + assert "driver_id" in tags["feast.entity_df_columns"] + assert "event_timestamp" in tags["feast.entity_df_columns"] + assert tags["feast.entity_df_type"] == "dataframe" + + @pytest.mark.integration + def test_entity_df_skipped_when_exceeds_max_rows( + self, driver_parquet, tracking_uri, feast_objects + ): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri, entity_df_max_rows=5) + store.apply(list(feast_objects)) + + client = MlflowClient(tracking_uri=tracking_uri) + entity_df = pd.DataFrame( + { + "driver_id": [1001] * 10, + "event_timestamp": [ + datetime.now() - timedelta(hours=i) for i in range(10) + ], + } + ) + + with mlflow.start_run(run_name="hist_skip") as run: + store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + artifacts = [a.path for a in client.list_artifacts(run.info.run_id)] + assert "entity_df.parquet" not in artifacts + tags = client.get_run(run.info.run_id).data.tags + assert tags["feast.entity_df_rows"] == "10" + + @pytest.mark.integration + def test_no_tags_without_active_run(self, store_enabled, entity_df): + result = store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + assert len(result) == len(entity_df) + + +class TestOnlineAutoLog: + @pytest.mark.integration + def test_tags_logged_for_online_retrieval(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run(run_name="online") as run: + store_enabled.get_online_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_rows=[{"driver_id": 1001}, {"driver_id": 1002}], + ) + + data = client.get_run(run.info.run_id) + tags = data.data.tags + + assert tags["feast.retrieval_type"] == "online" + assert tags["feast.feature_service"] == "driver_activity_v1" + assert tags["feast.entity_count"] == "2" + assert int(tags["feast.feature_count"]) >= 3 + assert data.data.metrics["feast.job_submission_sec"] >= 0 + + @pytest.mark.integration + def test_entity_count_for_list_input(self, store_enabled, tracking_uri): + client = MlflowClient(tracking_uri=tracking_uri) + + with mlflow.start_run(run_name="online_list") as run: + store_enabled.get_online_features( + features=["driver_hourly_stats:conv_rate"], + entity_rows=[ + {"driver_id": 1001}, + {"driver_id": 1002}, + {"driver_id": 1003}, + ], + ) + + tags = client.get_run(run.info.run_id).data.tags + assert tags["feast.entity_count"] == "3" + + +class TestDisabledIntegration: + @pytest.mark.integration + def test_disabled_does_not_log( + self, driver_parquet, tracking_uri, feast_objects, entity_df + ): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri, enabled=False) + store.apply(list(feast_objects)) + + client = MlflowClient(tracking_uri=tracking_uri) + with mlflow.start_run(run_name="disabled") as run: + store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + tags = client.get_run(run.info.run_id).data.tags + assert "feast.project" not in tags + assert "feast.feature_service" not in tags + + @pytest.mark.integration + def test_auto_log_false_does_not_log( + self, driver_parquet, tracking_uri, feast_objects, entity_df + ): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri, enabled=True, auto_log=False) + store.apply(list(feast_objects)) + + client = MlflowClient(tracking_uri=tracking_uri) + with mlflow.start_run(run_name="no_auto_log") as run: + store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + tags = client.get_run(run.info.run_id).data.tags + assert "feast.project" not in tags + + @pytest.mark.integration + def test_auto_log_entity_df_false_skips_artifact( + self, driver_parquet, tracking_uri, feast_objects, entity_df + ): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri, auto_log_entity_df=False) + store.apply(list(feast_objects)) + + client = MlflowClient(tracking_uri=tracking_uri) + with mlflow.start_run(run_name="no_entity_df") as run: + store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + run_data = client.get_run(run.info.run_id).data + artifacts = [a.path for a in client.list_artifacts(run.info.run_id)] + assert "entity_df.parquet" not in artifacts + + assert "feast.entity_df_rows" in run_data.tags + assert run_data.tags["feast.entity_df_type"] == "dataframe" + assert run_data.tags["feast.feature_service"] == "driver_activity_v1" + + +class TestEntityDfBuilder: + @pytest.mark.integration + def test_roundtrip_parquet(self, store_enabled, entity_df, tracking_uri): + with mlflow.start_run(run_name="roundtrip") as run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + recovered = store_enabled.mlflow.get_training_entity_df( + run_id=run.info.run_id, + ) + + assert recovered.shape == entity_df.shape + assert set(recovered.columns) == set(entity_df.columns) + assert "event_timestamp" in recovered.columns + + @pytest.mark.integration + def test_max_rows_limits_output(self, store_enabled, entity_df, tracking_uri): + with mlflow.start_run(run_name="max_rows") as run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + recovered = store_enabled.mlflow.get_training_entity_df( + run_id=run.info.run_id, + max_rows=5, + ) + assert len(recovered) == 5 + + @pytest.mark.integration + def test_missing_artifact_raises(self, store_enabled, tracking_uri): + with mlflow.start_run(run_name="empty") as run: + mlflow.log_param("dummy", "value") + + with pytest.raises(FeastMlflowEntityDfError, match="No entity data found"): + store_enabled.mlflow.get_training_entity_df( + run_id=run.info.run_id, + ) + + @pytest.mark.integration + def test_nonexistent_run_raises(self, store_enabled, tracking_uri): + with pytest.raises(FeastMlflowEntityDfError, match="not found"): + store_enabled.mlflow.get_training_entity_df( + run_id="0000000000000000deadbeef00000000", + ) + + @pytest.mark.integration + def test_missing_timestamp_column_raises(self, store_enabled, tracking_uri): + df = pd.DataFrame({"driver_id": [1001], "value": [0.5]}) + with mlflow.start_run(run_name="bad_cols") as run: + import tempfile + + with tempfile.TemporaryDirectory() as tmp_dir: + path = os.path.join(tmp_dir, "entity_df.parquet") + df.to_parquet(path, index=False) + mlflow.log_artifact(path) + + with pytest.raises( + FeastMlflowEntityDfError, match="missing required timestamp" + ): + store_enabled.mlflow.get_training_entity_df( + run_id=run.info.run_id, + ) + + @pytest.mark.integration + def test_custom_timestamp_column(self, store_enabled, tracking_uri): + df = pd.DataFrame( + { + "driver_id": [1001], + "ts": [datetime.now()], + } + ) + with mlflow.start_run(run_name="custom_ts") as run: + import tempfile + + with tempfile.TemporaryDirectory() as tmp_dir: + path = os.path.join(tmp_dir, "entity_df.parquet") + df.to_parquet(path, index=False) + mlflow.log_artifact(path) + + recovered = store_enabled.mlflow.get_training_entity_df( + run_id=run.info.run_id, + timestamp_column="ts", + ) + assert len(recovered) == 1 + assert "ts" in recovered.columns + + +class TestModelResolver: + def _train_and_register(self, store, entity_df, tracking_uri, model_name): + """Train inside an mlflow run, log a model, register it.""" + from sklearn.linear_model import LogisticRegression + + with mlflow.start_run(run_name=f"train_{model_name}") as run: + store.get_historical_features( + features=store.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + model = LogisticRegression() + model.fit([[0, 0], [1, 1]], [0, 1]) + mlflow.sklearn.log_model(model, "model") + + mlflow.register_model(f"runs:/{run.info.run_id}/model", model_name) + return run.info.run_id + + @pytest.mark.integration + def test_resolve_from_run_tags(self, store_enabled, entity_df, tracking_uri): + self._train_and_register( + store_enabled, entity_df, tracking_uri, "test_resolve_run_tags" + ) + + fs_name = store_enabled.mlflow.resolve_features( + model_uri="models:/test_resolve_run_tags/1", + ) + assert fs_name == "driver_activity_v1" + + @pytest.mark.integration + def test_resolve_from_model_version_tag( + self, store_enabled, entity_df, tracking_uri, feast_objects + ): + self._train_and_register( + store_enabled, entity_df, tracking_uri, "test_resolve_mv_tag" + ) + + _, _, fv, _ = feast_objects + override_fs = FeatureService(name="overridden_service", features=[fv]) + store_enabled.apply([override_fs]) + + client = MlflowClient(tracking_uri=tracking_uri) + client.set_model_version_tag( + "test_resolve_mv_tag", "1", "feast.feature_service", "overridden_service" + ) + + fs_name = store_enabled.mlflow.resolve_features( + model_uri="models:/test_resolve_mv_tag/1", + ) + assert fs_name == "overridden_service" + + @pytest.mark.integration + def test_model_version_tag_takes_priority_over_run_tag( + self, store_enabled, entity_df, tracking_uri, feast_objects + ): + self._train_and_register( + store_enabled, entity_df, tracking_uri, "test_priority" + ) + + _, _, fv, _ = feast_objects + override_fs = FeatureService(name="explicit_override", features=[fv]) + store_enabled.apply([override_fs]) + + client = MlflowClient(tracking_uri=tracking_uri) + client.set_model_version_tag( + "test_priority", "1", "feast.feature_service", "explicit_override" + ) + + fs_name = store_enabled.mlflow.resolve_features( + model_uri="models:/test_priority/1", + ) + assert fs_name == "explicit_override" + + @pytest.mark.integration + def test_validates_feature_service_exists( + self, store_enabled, entity_df, tracking_uri + ): + self._train_and_register( + store_enabled, entity_df, tracking_uri, "test_validate_exists" + ) + + client = MlflowClient(tracking_uri=tracking_uri) + client.set_model_version_tag( + "test_validate_exists", + "1", + "feast.feature_service", + "nonexistent_service", + ) + + with pytest.raises( + FeastMlflowModelResolutionError, match="not found in the Feast registry" + ): + store_enabled.mlflow.resolve_features( + model_uri="models:/test_validate_exists/1", + ) + + @pytest.mark.integration + def test_invalid_uri_raises(self, store_enabled, tracking_uri): + with pytest.raises(FeastMlflowModelResolutionError, match="Invalid model_uri"): + store_enabled.mlflow.resolve_features( + model_uri="not-a-valid-uri", + ) + + @pytest.mark.integration + def test_nonexistent_model_raises(self, store_enabled, tracking_uri): + with pytest.raises(FeastMlflowModelResolutionError, match="Could not resolve"): + store_enabled.mlflow.resolve_features( + model_uri="models:/does_not_exist/1", + ) + + @pytest.mark.integration + def test_no_feast_tag_anywhere_raises(self, store_enabled, tracking_uri): + from sklearn.linear_model import LogisticRegression + + mlflow.set_experiment("test_mlflow") + with mlflow.start_run(run_name="no_feast_tags") as run: + model = LogisticRegression() + model.fit([[0], [1]], [0, 1]) + mlflow.sklearn.log_model(model, "model") + + mlflow.register_model(f"runs:/{run.info.run_id}/model", "test_no_feast_tag") + + with pytest.raises( + FeastMlflowModelResolutionError, + match="Could not determine feature service", + ): + store_enabled.mlflow.resolve_features( + model_uri="models:/test_no_feast_tag/1", + ) + + @pytest.mark.integration + def test_feature_mismatch_with_required_features_artifact( + self, store_enabled, entity_df, tracking_uri + ): + from sklearn.linear_model import LogisticRegression + + with mlflow.start_run(run_name="mismatch") as run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + model = LogisticRegression() + model.fit([[0], [1]], [0, 1]) + mlflow.sklearn.log_model(model, "model") + + import tempfile + + with tempfile.TemporaryDirectory() as tmp_dir: + path = os.path.join(tmp_dir, "feast_features.json") + with open(path, "w") as f: + json.dump(["driver_hourly_stats:nonexistent_feature"], f) + mlflow.log_artifact(path) + + mlflow.register_model(f"runs:/{run.info.run_id}/model", "test_mismatch") + + with pytest.raises(FeastMlflowModelResolutionError, match="Feature mismatch"): + store_enabled.mlflow.resolve_features( + model_uri="models:/test_mismatch/1", + ) + + +class TestEndToEnd: + @pytest.mark.integration + def test_full_lifecycle(self, store_enabled, entity_df, tracking_uri): + from sklearn.linear_model import LogisticRegression + + with store_enabled.mlflow.start_run(run_name="e2e_train") as train_run: + training_df = store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + X = training_df[["conv_rate", "acc_rate", "avg_daily_trips"]].fillna(0) + y = entity_df["label"].values[: len(X)] + model = LogisticRegression().fit(X, y) + store_enabled.mlflow.log_model(model, "model") + + store_enabled.mlflow.register_model( + f"runs:/{train_run.info.run_id}/model", "e2e_model" + ) + + fs_name = store_enabled.mlflow.resolve_features( + model_uri="models:/e2e_model/1", + ) + assert fs_name == "driver_activity_v1" + + with store_enabled.mlflow.start_run(run_name="e2e_serve") as serve_run: + store_enabled.get_online_features( + features=store_enabled.get_feature_service(fs_name), + entity_rows=[{"driver_id": 1001}], + ) + + serve_tags = ( + MlflowClient(tracking_uri=tracking_uri) + .get_run(serve_run.info.run_id) + .data.tags + ) + assert serve_tags["feast.retrieval_type"] == "online" + assert serve_tags["feast.feature_service"] == "driver_activity_v1" + + recovered_df = store_enabled.mlflow.get_training_entity_df( + run_id=train_run.info.run_id, + ) + assert recovered_df.shape == entity_df.shape + + with store_enabled.mlflow.start_run(run_name="e2e_reproduce") as repro_run: + store_enabled.get_historical_features( + features=store_enabled.get_feature_service(fs_name), + entity_df=recovered_df, + ).to_df() + + repro_tags = ( + MlflowClient(tracking_uri=tracking_uri) + .get_run(repro_run.info.run_id) + .data.tags + ) + assert repro_tags["feast.feature_service"] == "driver_activity_v1" + assert repro_tags["feast.entity_count"] == str(len(entity_df)) + + +class TestLogApplyTransitionTypes: + """Tests for per-object transition type tags via store.mlflow.""" + + @pytest.mark.integration + def test_transition_tags_created(self, store_enabled, tracking_uri, feast_objects): + driver, source, fv, fs = feast_objects + transition_types = { + fv.name: "CREATE", + fs.name: "CREATE", + driver.name: "CREATE", + } + store_enabled.mlflow.log_apply( + changed_objects=[fv, fs, driver], + transition_types=transition_types, + ) + + client = MlflowClient(tracking_uri=tracking_uri) + exp = client.get_experiment_by_name("test_mlflow-feast-ops") + assert exp is not None + runs = client.search_runs(experiment_ids=[exp.experiment_id]) + assert len(runs) == 1 + + tags = runs[0].data.tags + assert tags["feast.operation"] == "apply" + assert tags["feast.feature_views_created"] == fv.name + assert tags["feast.feature_services_created"] == fs.name + assert tags["feast.entities_created"] == driver.name + assert "feast.feature_views_updated" not in tags + assert "feast.feature_views_deleted" not in tags + + @pytest.mark.integration + def test_transition_tags_mixed(self, store_enabled, tracking_uri, feast_objects): + driver, source, fv, fs = feast_objects + + fv2 = FeatureView( + name="driver_daily_stats", + entities=[driver], + ttl=timedelta(days=1), + schema=[Field(name="conv_rate", dtype=Float32)], + online=True, + source=source, + ) + + transition_types = { + fv.name: "UPDATE", + fv2.name: "CREATE", + fs.name: "DELETE", + } + store_enabled.mlflow.log_apply( + changed_objects=[fv, fv2, fs], + transition_types=transition_types, + ) + + client = MlflowClient(tracking_uri=tracking_uri) + exp = client.get_experiment_by_name("test_mlflow-feast-ops") + runs = client.search_runs(experiment_ids=[exp.experiment_id]) + assert len(runs) == 1 + + tags = runs[0].data.tags + assert fv.name in tags["feast.feature_views_updated"] + assert fv2.name in tags["feast.feature_views_created"] + assert fs.name in tags["feast.feature_services_deleted"] + + @pytest.mark.integration + def test_no_transition_tags_when_none( + self, store_enabled, tracking_uri, feast_objects + ): + _, _, fv, fs = feast_objects + store_enabled.mlflow.log_apply( + changed_objects=[fv, fs], + transition_types=None, + ) + + client = MlflowClient(tracking_uri=tracking_uri) + exp = client.get_experiment_by_name("test_mlflow-feast-ops") + runs = client.search_runs(experiment_ids=[exp.experiment_id]) + assert len(runs) == 1 + + tags = runs[0].data.tags + assert tags["feast.feature_views_changed"] == fv.name + assert "feast.feature_views_created" not in tags + assert "feast.feature_views_updated" not in tags + + @pytest.mark.integration + def test_backward_compatible_changed_tags_still_present( + self, store_enabled, tracking_uri, feast_objects + ): + """Transition tags are additive — the aggregate *_changed tags still appear.""" + driver, _, fv, fs = feast_objects + transition_types = { + fv.name: "CREATE", + fs.name: "UPDATE", + driver.name: "CREATE", + } + store_enabled.mlflow.log_apply( + changed_objects=[fv, fs, driver], + transition_types=transition_types, + ) + + client = MlflowClient(tracking_uri=tracking_uri) + exp = client.get_experiment_by_name("test_mlflow-feast-ops") + runs = client.search_runs(experiment_ids=[exp.experiment_id]) + tags = runs[0].data.tags + + assert tags["feast.feature_views_changed"] == fv.name + assert tags["feast.feature_services_changed"] == fs.name + assert tags["feast.entities_changed"] == driver.name + assert tags["feast.feature_views_created"] == fv.name + assert tags["feast.feature_services_updated"] == fs.name + assert tags["feast.entities_created"] == driver.name + + +class TestFeastMlflowModuleAPI: + """Tests for the ``store.mlflow`` and ``feast.mlflow`` module-level API.""" + + @pytest.mark.integration + def test_store_mlflow_property(self, store_enabled, tracking_uri): + """store.mlflow returns a FeastMlflowClient instance.""" + assert store_enabled.mlflow is not None + assert hasattr(store_enabled.mlflow, "start_run") + assert hasattr(store_enabled.mlflow, "log_model") + assert hasattr(store_enabled.mlflow, "resolve_features") + + @pytest.mark.integration + def test_store_mlflow_none_when_disabled(self, driver_parquet, tracking_uri): + tmp_path, _ = driver_parquet + store = _make_store(tmp_path, tracking_uri, enabled=False) + assert store.mlflow is None + + @pytest.mark.integration + def test_auto_registration_via_feature_store(self, store_enabled, tracking_uri): + """FeatureStore auto-registers with feast.mlflow — no init() needed.""" + client = MlflowClient(tracking_uri=tracking_uri) + + with store_enabled.mlflow.start_run(run_name="auto_reg") as run: + feast.mlflow.log_params({"lr": "0.01"}) + feast.mlflow.log_metrics({"acc": 0.95}) + feast.mlflow.log_metric("loss", 0.05) + assert store_enabled.mlflow.active_run_id == run.info.run_id + + data = client.get_run(run.info.run_id) + assert data.data.params["lr"] == "0.01" + assert data.data.metrics["acc"] == 0.95 + assert data.data.metrics["loss"] == 0.05 + assert data.data.tags.get("feast.project") == "test_mlflow" + + @pytest.mark.integration + def test_explicit_init_overrides_auto_registration( + self, store_enabled, tracking_uri + ): + feast.mlflow.init(store_enabled) + with store_enabled.mlflow.start_run(run_name="explicit_init") as run: + feast.mlflow.log_metric("x", 1.0) + + client = MlflowClient(tracking_uri=tracking_uri) + data = client.get_run(run.info.run_id) + assert data.data.tags.get("feast.project") == "test_mlflow" + + @pytest.mark.integration + def test_getattr_delegates_all_methods(self, store_enabled, tracking_uri): + """All FeastMlflowClient public methods are accessible via store.mlflow.""" + for method_name in [ + "start_run", + "log_model", + "register_model", + "load_model", + "resolve_features", + "get_training_entity_df", + "log_feature_retrieval", + "log_training_dataset", + "log_apply", + "log_materialize", + ]: + attr = getattr(store_enabled.mlflow, method_name) + assert callable(attr), f"{method_name} should be callable" + + @pytest.mark.integration + def test_active_run_id_property(self, store_enabled): + assert store_enabled.mlflow.active_run_id is None + with store_enabled.mlflow.start_run(run_name="prop_test"): + assert store_enabled.mlflow.active_run_id is not None + + @pytest.mark.integration + def test_mlflow_escape_hatch(self, store_enabled): + raw = store_enabled.mlflow.mlflow + assert hasattr(raw, "start_run") + + @pytest.mark.integration + def test_unknown_attr_raises(self, store_enabled): + with pytest.raises(AttributeError): + feast.mlflow.nonexistent_method + + @pytest.mark.integration + def test_log_model_and_register(self, store_enabled, entity_df, tracking_uri): + from sklearn.linear_model import LogisticRegression + + with store_enabled.mlflow.start_run(run_name="mod_train"): + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + + model = LogisticRegression().fit([[0, 0], [1, 1]], [0, 1]) + store_enabled.mlflow.log_model(model, "model") + train_run_id = store_enabled.mlflow.active_run_id + + mv = store_enabled.mlflow.register_model( + f"runs:/{train_run_id}/model", "mod_test_model" + ) + assert mv.version is not None + + client = MlflowClient(tracking_uri=tracking_uri) + mv_info = client.get_model_version("mod_test_model", mv.version) + assert mv_info.tags.get("feast.feature_service") == "driver_activity_v1" + + @pytest.mark.integration + def test_load_model_tags_prediction_run( + self, store_enabled, entity_df, tracking_uri + ): + from sklearn.linear_model import LogisticRegression + + with store_enabled.mlflow.start_run(run_name="mod_train_load"): + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + model = LogisticRegression().fit([[0, 0], [1, 1]], [0, 1]) + store_enabled.mlflow.log_model(model, "model") + train_run_id = store_enabled.mlflow.active_run_id + + store_enabled.mlflow.register_model( + f"runs:/{train_run_id}/model", "mod_load_test" + ) + + with store_enabled.mlflow.start_run(run_name="mod_predict") as pred_run: + store_enabled.mlflow.load_model("models:/mod_load_test/1") + + client = MlflowClient(tracking_uri=tracking_uri) + tags = client.get_run(pred_run.info.run_id).data.tags + assert tags.get("feast.training_run_id") == train_run_id + assert tags.get("feast.model_name") == "mod_load_test" + + @pytest.mark.integration + def test_resolve_features_and_get_training_entity_df( + self, store_enabled, entity_df, tracking_uri + ): + from sklearn.linear_model import LogisticRegression + + with store_enabled.mlflow.start_run(run_name="mod_resolve"): + store_enabled.get_historical_features( + features=store_enabled.get_feature_service("driver_activity_v1"), + entity_df=entity_df, + ).to_df() + model = LogisticRegression().fit([[0, 0], [1, 1]], [0, 1]) + store_enabled.mlflow.log_model(model, "model") + train_run_id = store_enabled.mlflow.active_run_id + + store_enabled.mlflow.register_model( + f"runs:/{train_run_id}/model", "mod_resolve_model" + ) + + fs_name = store_enabled.mlflow.resolve_features("models:/mod_resolve_model/1") + assert fs_name == "driver_activity_v1" + + recovered = store_enabled.mlflow.get_training_entity_df(train_run_id) + assert recovered.shape == entity_df.shape + + @pytest.mark.integration + def test_no_active_run_returns_none(self, store_enabled): + assert store_enabled.mlflow.active_run_id is None + + @pytest.mark.integration + def test_error_when_mlflow_disabled(self, driver_parquet, tracking_uri): + """feast.mlflow raises RuntimeError when mlflow is not enabled.""" + tmp_path, _ = driver_parquet + feast.mlflow._client = None + feast.mlflow._registered_store = None + + disabled_store = _make_store(tmp_path, tracking_uri, enabled=False) + feast.mlflow.init(disabled_store) + + with pytest.raises(RuntimeError, match="not enabled"): + feast.mlflow.start_run(run_name="should_fail") diff --git a/sdk/python/tests/unit/api/test_api_rest_registry.py b/sdk/python/tests/unit/api/test_api_rest_registry.py index afba602ddac..b87f0476e15 100644 --- a/sdk/python/tests/unit/api/test_api_rest_registry.py +++ b/sdk/python/tests/unit/api/test_api_rest_registry.py @@ -1503,11 +1503,50 @@ def test_metrics_resource_counts_via_rest(fastapi_test_app): assert "featureViews" in counts assert "featureServices" in counts - # Verify counts are integers for key, value in counts.items(): assert isinstance(value, int) assert value >= 0 + # Verify feature services summaries + assert "featureServices" in data + assert isinstance(data["featureServices"], list) + assert len(data["featureServices"]) == counts["featureServices"] + for fs in data["featureServices"]: + assert "name" in fs + assert "project" in fs + assert fs["project"] == "demo_project" + service_names = [fs["name"] for fs in data["featureServices"]] + assert "user_service" in service_names + + # Verify feature views summaries with detail + assert "featureViews" in data + assert isinstance(data["featureViews"], list) + assert len(data["featureViews"]) == counts["featureViews"] + for fv in data["featureViews"]: + assert "name" in fv + assert "project" in fv + assert "type" in fv + assert "featureCount" in fv + assert isinstance(fv["featureCount"], int) + assert fv["featureCount"] >= 0 + assert fv["project"] == "demo_project" + fv_names = [fv["name"] for fv in data["featureViews"]] + assert "user_profile" in fv_names + user_profile_fv = next( + fv for fv in data["featureViews"] if fv["name"] == "user_profile" + ) + assert user_profile_fv["featureCount"] == 2 + + # Verify projects list + assert "projects" in data + assert isinstance(data["projects"], list) + assert len(data["projects"]) == 1 + assert data["projects"][0]["name"] == "demo_project" + + # Verify registry last updated + assert "registryLastUpdated" in data + assert data["registryLastUpdated"] is not None + # Test without project parameter (should return all projects) response = fastapi_test_app.get("/metrics/resource_counts") assert response.status_code == 200 @@ -1527,6 +1566,116 @@ def test_metrics_resource_counts_via_rest(fastapi_test_app): assert "demo_project" in per_project assert isinstance(per_project["demo_project"], dict) + # Verify metadata in all-projects mode + assert "featureServices" in data + assert isinstance(data["featureServices"], list) + + assert "featureViews" in data + assert isinstance(data["featureViews"], list) + for fv in data["featureViews"]: + assert "name" in fv + assert "project" in fv + assert "type" in fv + assert "featureCount" in fv + + assert "projects" in data + assert isinstance(data["projects"], list) + assert len(data["projects"]) >= 1 + for proj in data["projects"]: + assert "name" in proj + assert "description" in proj + + assert "registryLastUpdated" in data + assert data["registryLastUpdated"] is not None + + +def test_metrics_resource_counts_with_permission_errors(fastapi_test_app): + """ + Test that /metrics/resource_counts returns 200 with zero counts for + resource types that raise FeastPermissionError, instead of failing + the entire request. This simulates the scenario where access is + restricted for some resource types via GroupBasedPolicy, + NamespaceBasedPolicy, or CombinedGroupNamespacePolicy. + """ + from unittest.mock import patch + + from feast.errors import FeastPermissionError + + original_get = fastapi_test_app.get + + # First, get the baseline counts to know which resources have data + baseline = original_get("/metrics/resource_counts?project=demo_project").json() + baseline_counts = baseline["counts"] + + # Patch grpc_call to raise FeastPermissionError for entities and data sources + # while allowing other resource types to succeed + original_grpc_call = None + + def grpc_call_entities_denied(handler_fn, request): + handler_name = getattr(handler_fn, "__name__", "") + if handler_name in ("ListEntities", "ListDataSources"): + raise FeastPermissionError(f"Permission denied for {handler_name}") + return original_grpc_call(handler_fn, request) + + with patch("feast.api.registry.rest.metrics.grpc_call") as mock_grpc_call: + import feast.api.registry.rest.metrics as metrics_module + + original_grpc_call = metrics_module.__dict__.get("grpc_call") + # Restore actual import since patch replaces it + from feast.api.registry.rest.rest_utils import grpc_call as real_grpc_call + + original_grpc_call = real_grpc_call + mock_grpc_call.side_effect = grpc_call_entities_denied + + response = fastapi_test_app.get("/metrics/resource_counts?project=demo_project") + + assert response.status_code == 200, ( + f"Expected 200 but got {response.status_code}: {response.text}" + ) + data = response.json() + assert "counts" in data + counts = data["counts"] + + # Denied resource types should have 0 counts + assert counts["entities"] == 0 + assert counts["dataSources"] == 0 + + # Permitted resource types should still have their original counts + assert counts["featureViews"] == baseline_counts["featureViews"] + assert counts["featureServices"] == baseline_counts["featureServices"] + assert counts["features"] == baseline_counts["features"] + assert counts["savedDatasets"] == baseline_counts["savedDatasets"] + + # Permitted metadata summaries should still be populated + assert len(data["featureViews"]) == baseline_counts["featureViews"] + assert len(data["featureServices"]) == baseline_counts["featureServices"] + + # Now test with ALL resource types denied + def grpc_call_all_denied(handler_fn, request): + handler_name = getattr(handler_fn, "__name__", "") + if handler_name.startswith("List") and handler_name != "ListProjects": + raise FeastPermissionError(f"Permission denied for {handler_name}") + return real_grpc_call(handler_fn, request) + + with patch("feast.api.registry.rest.metrics.grpc_call") as mock_grpc_call: + mock_grpc_call.side_effect = grpc_call_all_denied + + response = fastapi_test_app.get("/metrics/resource_counts?project=demo_project") + + assert response.status_code == 200 + data = response.json() + counts = data["counts"] + + # All counts should be 0 when all resource types are denied + for resource_type, count in counts.items(): + assert count == 0, ( + f"Expected 0 for {resource_type} when permission denied, got {count}" + ) + + # Metadata summaries should be empty when all permissions are denied + assert data["featureViews"] == [] + assert data["featureServices"] == [] + def test_feature_views_all_types_and_resource_counts_match(fastapi_test_app): """ @@ -1851,3 +2000,151 @@ def test_all_endpoints_return_404_for_invalid_objects(fastapi_test_app): data = response.json() assert data["status_code"] == 404 assert data["error_type"] == "FeastObjectNotFoundException" + + +def test_apply_and_delete_entity_via_rest(fastapi_test_app): + """Test POST /entities and DELETE /entities/{name} endpoints.""" + # Apply a new entity + response = fastapi_test_app.post( + "/entities", + json={ + "name": "driver_id", + "project": "demo_project", + "join_key": "driver_id", + "value_type": 2, + "description": "Driver entity", + "owner": "ml-team", + }, + ) + assert response.status_code == 201 + data = response.json() + assert data["name"] == "driver_id" + assert data["status"] == "applied" + + # Verify it exists + response = fastapi_test_app.get("/entities/driver_id?project=demo_project") + assert response.status_code == 200 + assert response.json()["spec"]["name"] == "driver_id" + + # Delete it + response = fastapi_test_app.delete("/entities/driver_id?project=demo_project") + assert response.status_code == 200 + data = response.json() + assert data["name"] == "driver_id" + assert data["status"] == "deleted" + + # Verify it's gone + response = fastapi_test_app.get("/entities/driver_id?project=demo_project") + assert response.status_code == 404 + + +def test_apply_and_delete_data_source_via_rest(fastapi_test_app): + """Test POST /data_sources and DELETE /data_sources/{name} endpoints.""" + # Apply a new file data source + response = fastapi_test_app.post( + "/data_sources", + json={ + "name": "test_file_source", + "project": "demo_project", + "type": 1, + "timestamp_field": "event_timestamp", + "description": "Test file source", + "file_options": {"uri": "s3://bucket/path/data.parquet"}, + }, + ) + assert response.status_code == 201 + data = response.json() + assert data["name"] == "test_file_source" + assert data["status"] == "applied" + + # Verify it exists + response = fastapi_test_app.get( + "/data_sources/test_file_source?project=demo_project" + ) + assert response.status_code == 200 + assert response.json()["name"] == "test_file_source" + + # Delete it + response = fastapi_test_app.delete( + "/data_sources/test_file_source?project=demo_project" + ) + assert response.status_code == 200 + data = response.json() + assert data["name"] == "test_file_source" + assert data["status"] == "deleted" + + # Verify it's gone + response = fastapi_test_app.get( + "/data_sources/test_file_source?project=demo_project" + ) + assert response.status_code == 404 + + +def test_apply_and_delete_feature_view_via_rest(fastapi_test_app): + """Test POST /feature_views and DELETE /feature_views/{name} endpoints.""" + # Apply a new feature view (no batch_source: a bare DataSourceProto with only a + # name but no type is rejected by the registry's source-type validation) + response = fastapi_test_app.post( + "/feature_views", + json={ + "name": "driver_stats", + "project": "demo_project", + "entities": ["user_id"], + "features": [ + { + "name": "trip_count", + "value_type": 2, + "description": "Number of completed trips", + }, + { + "name": "avg_rating", + "value_type": 4, + "description": "Average driver rating", + }, + ], + "ttl_seconds": 86400, + "online": True, + "description": "Driver statistics feature view", + }, + ) + assert response.status_code == 201 + data = response.json() + assert data["name"] == "driver_stats" + assert data["status"] == "applied" + + # Verify it exists + response = fastapi_test_app.get("/feature_views/driver_stats?project=demo_project") + assert response.status_code == 200 + spec = response.json()["spec"] + assert spec["name"] == "driver_stats" + assert spec["features"][0]["description"] == "Number of completed trips" + assert spec["features"][1]["description"] == "Average driver rating" + + # Delete it + response = fastapi_test_app.delete( + "/feature_views/driver_stats?project=demo_project" + ) + assert response.status_code == 200 + data = response.json() + assert data["name"] == "driver_stats" + assert data["status"] == "deleted" + + # Verify it's gone + response = fastapi_test_app.get("/feature_views/driver_stats?project=demo_project") + assert response.status_code == 404 + + +def test_metrics_resource_counts_nonexistent_project(fastapi_test_app): + """Test /metrics/resource_counts with a non-existent project returns empty data.""" + response = fastapi_test_app.get( + "/metrics/resource_counts?project=nonexistent_project" + ) + assert response.status_code == 200 + data = response.json() + + counts = data["counts"] + for value in counts.values(): + assert value == 0 + assert data["featureServices"] == [] + assert data["featureViews"] == [] + assert "registryLastUpdated" in data diff --git a/sdk/python/tests/unit/api/test_api_rest_registry_server.py b/sdk/python/tests/unit/api/test_api_rest_registry_server.py index 2abfa3ac462..f181c794a96 100644 --- a/sdk/python/tests/unit/api/test_api_rest_registry_server.py +++ b/sdk/python/tests/unit/api/test_api_rest_registry_server.py @@ -54,33 +54,12 @@ def test_rest_registry_server_initializes_correctly( assert {"BearerAuth": []} in openapi_schema["security"] -def test_routes_registered_in_app(mock_store_and_registry): - from fastapi.routing import APIRoute +def test_routes_registered_in_app(): + from feast.api.registry.rest import register_all_routes - store, _ = mock_store_and_registry + app = MagicMock() + grpc_handler = MagicMock() + server = MagicMock() + register_all_routes(app, grpc_handler, server) - server = RestRegistryServer(store) - route_paths = [ - route.path for route in server.app.routes if isinstance(route, APIRoute) - ] - assert "/feature_services" in route_paths - assert "/entities" in route_paths - assert "/projects" in route_paths - assert "/data_sources" in route_paths - assert "/saved_datasets" in route_paths - assert "/permissions" in route_paths - assert "/lineage/registry" in route_paths - assert "/lineage/objects/{object_type}/{object_name}" in route_paths - assert "/lineage/complete" in route_paths - assert "/entities/all" in route_paths - assert "/feature_views/all" in route_paths - assert "/data_sources/all" in route_paths - assert "/feature_services/all" in route_paths - assert "/saved_datasets/all" in route_paths - assert "/lineage/registry/all" in route_paths - assert "/lineage/complete/all" in route_paths - assert "/features" in route_paths - assert "/features/all" in route_paths - assert "/features/{feature_view}/{name}" in route_paths - assert "/metrics/resource_counts" in route_paths - assert "/metrics/recently_visited" in route_paths + assert app.include_router.call_count == 13 diff --git a/sdk/python/tests/unit/infra/compute_engines/flink/__init__.py b/sdk/python/tests/unit/infra/compute_engines/flink/__init__.py new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/flink/__init__.py @@ -0,0 +1 @@ + diff --git a/sdk/python/tests/unit/infra/compute_engines/flink/test_flink_compute_engine.py b/sdk/python/tests/unit/infra/compute_engines/flink/test_flink_compute_engine.py new file mode 100644 index 00000000000..7941c8ae405 --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/flink/test_flink_compute_engine.py @@ -0,0 +1,1213 @@ +from __future__ import annotations + +import re +import sys +import types +from datetime import datetime, timedelta +from pathlib import Path +from typing import Any, List, Optional +from unittest.mock import MagicMock + +import pandas as pd +import pyarrow as pa +import pytest +import toml # type: ignore[import-untyped] + +from feast import BatchFeatureView, Entity, Field, FileSource +from feast.aggregation import Aggregation +from feast.infra.common.materialization_job import ( + MaterializationJobStatus, + MaterializationTask, +) +from feast.infra.common.retrieval_task import HistoricalRetrievalTask +from feast.infra.compute_engines.dag.context import ColumnInfo, ExecutionContext +from feast.infra.compute_engines.dag.model import DAGFormat +from feast.infra.compute_engines.dag.node import DAGNode +from feast.infra.compute_engines.dag.value import DAGValue +from feast.infra.compute_engines.flink.compute import ( + FlinkComputeEngine, + FlinkComputeEngineConfig, +) +from feast.infra.compute_engines.flink.nodes import ( + ENTITY_ROW_ID, + ENTITY_TS_ALIAS, + FlinkAggregationNode, + FlinkDedupNode, + FlinkFilterNode, + FlinkJoinNode, + FlinkOutputNode, + FlinkSourceReadNode, + FlinkTransformationNode, + FlinkValidationNode, + _subtract_flink_intervals, +) +from feast.infra.compute_engines.flink.utils import pandas_to_flink_table +from feast.infra.offline_stores.offline_store import RetrievalJob, RetrievalMetadata +from feast.on_demand_feature_view import OnDemandFeatureView +from feast.repo_config import RepoConfig +from feast.saved_dataset import SavedDatasetStorage +from feast.types import Float32 +from feast.value_type import ValueType + + +def test_flink_extra_does_not_downgrade_default_pyarrow_dependency() -> None: + pyproject_path = Path(__file__).resolve().parents[7] / "pyproject.toml" + pyproject = toml.loads(pyproject_path.read_text()) + + dependencies = pyproject["project"]["dependencies"] + assert "pyarrow>=21.0.0; extra != 'flink'" in dependencies + assert "pyarrow>=16.1.0,<21.0.0; extra == 'flink'" in dependencies + assert "pyarrow>=16.1.0" not in dependencies + assert ( + "apache-flink>=2.2.1,<3" + in pyproject["project"]["optional-dependencies"]["flink"] + ) + + +class FakeFlinkTable: + def __init__(self, df: pd.DataFrame, fail_on_to_pandas: bool = False) -> None: + self._df = df.copy() + self.fail_on_to_pandas = fail_on_to_pandas + + def to_pandas(self) -> pd.DataFrame: + if self.fail_on_to_pandas: + raise AssertionError("FlinkOutputNode should not collect via to_pandas()") + return self._df.copy() + + def get_schema(self) -> FakeFlinkSchema: + return FakeFlinkSchema(list(self._df.columns)) + + def execute(self) -> FakeTableResult: + return FakeTableResult(self._df) + + +class FakeTableResult: + def __init__(self, df: pd.DataFrame) -> None: + self._df = df.copy() + + def collect(self) -> FakeCloseableIterator: + return FakeCloseableIterator(self._df) + + +class FakeCloseableIterator: + def __init__(self, df: pd.DataFrame) -> None: + self._rows = iter(df.itertuples(index=False, name=None)) + self.closed = False + + def __iter__(self) -> FakeCloseableIterator: + return self + + def __next__(self) -> tuple[Any, ...]: + return next(self._rows) + + def close(self) -> None: + self.closed = True + + +class FakeTableEnvironment: + def __init__(self) -> None: + self.created_tables: List[pd.DataFrame] = [] + self.schemas: List[object] = [] + self.split_nums: List[int] = [] + self.views: dict[str, object] = {} + self.dropped_views: List[str] = [] + self.queries: List[str] = [] + + def from_pandas( + self, + df: pd.DataFrame, + schema: object = None, + splits_num: int = 1, + split_num: Optional[int] = None, + ) -> FakeFlinkTable: + self.created_tables.append(df.copy()) + self.schemas.append(schema) + self.split_nums.append(split_num if split_num is not None else splits_num) + return FakeFlinkTable(df) + + def create_temporary_view( + self, view_path: str, table_or_data_stream: object, *args: object + ) -> None: + self.views[view_path] = table_or_data_stream + + def drop_temporary_view(self, view_path: str) -> None: + self.dropped_views.append(view_path) + self.views.pop(view_path, None) + + def sql_query(self, query: str) -> Any: + self.queries.append(query) + return FakeFlinkTable(self._evaluate_sql(query)) + + def _view_df(self, view_name: str) -> pd.DataFrame: + table = self.views[view_name] + if isinstance(table, FakeFlinkTable): + return table.to_pandas() + if isinstance(table, FakeNativeFlinkTable): + return pd.DataFrame(columns=table.get_schema().get_field_names()) + raise TypeError(f"Unsupported fake Flink table type: {type(table)}") + + def _evaluate_sql(self, query: str) -> pd.DataFrame: + if "ROW_NUMBER() OVER" in query: + return self._evaluate_row_number_query(query) + if " GROUP BY " in query: + return self._evaluate_group_by_query(query) + if " JOIN " in query: + return self._evaluate_join_query(query) + if " WHERE " in query: + return self._evaluate_where_query(query) + return self._evaluate_select_query(query) + + def _extract_views(self, query: str) -> List[str]: + return re.findall(r"(?:FROM|JOIN)\s+`([^`]+)`", query) + + def _evaluate_select_query(self, query: str) -> pd.DataFrame: + views = self._extract_views(query) + if not views: + if "FROM entities" in query: + return self._view_df("entities")[["driver_id", "event_timestamp"]] + raise ValueError(f"Could not infer source view from query: {query}") + source_df = self._view_df(views[-1]) + select_clause = query.split(" FROM ", 1)[0].removeprefix("SELECT ") + if select_clause == "*": + return source_df + result = pd.DataFrame() + for column_expr in select_clause.split(", "): + parts = re.findall(r"`([^`]+)`", column_expr) + if not parts: + continue + source_column = parts[0] + output_column = parts[-1] + result[output_column] = source_df[source_column] + return result + + def _evaluate_where_query(self, query: str) -> pd.DataFrame: + view_name = self._extract_views(query)[0] + df = self._view_df(view_name) + if "`event_timestamp` <= `__entity_event_timestamp`" in query: + df = df[df["event_timestamp"] <= df[ENTITY_TS_ALIAS]] + if "conv_rate > 0.15" in query: + df = df[df["conv_rate"] > 0.15] + return df.reset_index(drop=True) + + def _evaluate_group_by_query(self, query: str) -> pd.DataFrame: + view_name = self._extract_views(query)[0] + df = self._view_df(view_name) + return ( + df.groupby("driver_id") + .agg(sum_conv_rate=pd.NamedAgg(column="conv_rate", aggfunc="sum")) + .reset_index() + ) + + def _evaluate_row_number_query(self, query: str) -> pd.DataFrame: + view_name = self._extract_views(query)[-1] + df = self._view_df(view_name) + if " - 1 AS " in query: + df = df.copy() + df[ENTITY_ROW_ID] = range(len(df)) + if " AS `__entity_event_timestamp`" in query: + df = df.rename(columns={"event_timestamp": ENTITY_TS_ALIAS}) + return df.reset_index(drop=True) + + dedup_keys = [ENTITY_ROW_ID] if ENTITY_ROW_ID in df.columns else ["driver_id"] + sort_keys = [ + column for column in ["event_timestamp", "created"] if column in df + ] + return ( + df.sort_values(by=sort_keys, ascending=False) + .drop_duplicates(subset=dedup_keys) + .reset_index(drop=True) + ) + + def _evaluate_join_query(self, query: str) -> pd.DataFrame: + views = self._extract_views(query) + if " AS e LEFT JOIN " in query: + entity_df = self._view_df(views[-2]) + feature_df = self._view_df(views[-1]) + feature_columns = [ + column + for column in feature_df.columns + if column not in entity_df.columns and column != "driver_id" + ] + return entity_df.merge( + feature_df[["driver_id", *feature_columns]], + on="driver_id", + how="left", + ) + + joined_df = self._view_df(views[0]) + for view_name in views[1:]: + joined_df = joined_df.merge( + self._view_df(view_name), on="driver_id", how="left" + ) + return joined_df + + +class FakeFlinkSchema: + def __init__(self, columns: List[str]) -> None: + self._columns = columns + + def get_field_names(self) -> List[str]: + return list(self._columns) + + +class FakeNativeFlinkTable: + def __init__(self, columns: List[str]) -> None: + self._columns = columns + + def get_schema(self) -> FakeFlinkSchema: + return FakeFlinkSchema(self._columns) + + +class RecordingTableEnvironment(FakeTableEnvironment): + def __init__(self) -> None: + super().__init__() + + def create_temporary_view( + self, view_path: str, table_or_data_stream: object, *args: object + ) -> None: + self.views[view_path] = table_or_data_stream + + def sql_query(self, query: str) -> FakeNativeFlinkTable: + self.queries.append(query) + return FakeNativeFlinkTable([]) + + +class InputNode(DAGNode): + def execute(self, context: ExecutionContext) -> DAGValue: + return context.node_outputs[self.name] + + +class FakeRetrievalJob(RetrievalJob): + def __init__(self, table: pa.Table) -> None: + self._table = table + + def _to_df_internal(self, timeout: Optional[int] = None) -> pd.DataFrame: + return self._table.to_pandas() + + def _to_arrow_internal(self, timeout: Optional[int] = None) -> pa.Table: + return self._table + + @property + def full_feature_names(self) -> bool: + return False + + @property + def on_demand_feature_views(self) -> List[OnDemandFeatureView]: + return [] + + @property + def metadata(self) -> Optional[RetrievalMetadata]: + return None + + def persist( + self, + storage: SavedDatasetStorage, + allow_overwrite: bool = False, + timeout: Optional[int] = None, + ) -> None: + raise NotImplementedError + + def to_remote_storage(self) -> List[str]: + raise NotImplementedError + + def to_sql(self) -> str: + raise NotImplementedError + + +class FakeFlinkRetrievalJob: + def __init__(self, df: pd.DataFrame) -> None: + self._table = FakeFlinkTable(df) + + def to_flink_table(self, table_env: object) -> FakeFlinkTable: + return self._table + + +def _repo_config(tmp_path: Path, batch_engine: dict[str, object]) -> RepoConfig: + return RepoConfig( + project="test_project", + registry=str(tmp_path / "registry.db"), + provider="local", + offline_store={"type": "file"}, + online_store={"type": "sqlite", "path": str(tmp_path / "online.db")}, + batch_engine=batch_engine, + ) + + +def _driver() -> Entity: + return Entity(name="driver_id", value_type=ValueType.INT64) + + +def _source() -> FileSource: + return FileSource( + name="driver_stats_source", + path="unused.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + +def _feature_view(source: FileSource, **kwargs: Any) -> BatchFeatureView: + return BatchFeatureView( + name="driver_stats", + entities=[_driver()], + ttl=timedelta(days=2), + schema=[Field(name="conv_rate", dtype=Float32)], + source=source, + **kwargs, + ) + + +def _feature_data() -> pd.DataFrame: + return pd.DataFrame( + { + "driver_id": [1, 1, 2], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 0, 0), + datetime(2024, 1, 1, 10, 0, 0), + datetime(2024, 1, 1, 10, 0, 0), + ], + "created": [ + datetime(2024, 1, 1, 9, 1, 0), + datetime(2024, 1, 1, 10, 1, 0), + datetime(2024, 1, 1, 10, 1, 0), + ], + "conv_rate": [0.1, 0.2, 0.3], + } + ) + + +def _offline_store(df: pd.DataFrame) -> MagicMock: + store = MagicMock() + store.pull_all_from_table_or_query.return_value = FakeFlinkRetrievalJob(df) + store.pull_latest_from_table_or_query.return_value = FakeFlinkRetrievalJob(df) + return store + + +def _registry(entity: Entity) -> MagicMock: + registry = MagicMock() + registry.get_entity.return_value = entity + return registry + + +def _column_info() -> ColumnInfo: + return ColumnInfo( + join_keys=["driver_id"], + feature_cols=["conv_rate"], + ts_col="event_timestamp", + created_ts_col="created", + ) + + +def _execution_context( + tmp_path: Path, node_outputs: dict[str, DAGValue] +) -> ExecutionContext: + return ExecutionContext( + project="test_project", + repo_config=_repo_config(tmp_path, {"type": "flink.engine"}), + offline_store=MagicMock(), + online_store=MagicMock(), + entity_defs=[_driver()], + node_outputs=node_outputs, + ) + + +def _flink_value(df: pd.DataFrame) -> DAGValue: + return DAGValue( + data=FakeFlinkTable(df), + format=DAGFormat.FLINK, + metadata={"columns": list(df.columns)}, + ) + + +def test_pandas_to_flink_table_builds_typed_schema( + monkeypatch: pytest.MonkeyPatch, +) -> None: + class FakeSchemaBuilder: + def __init__(self) -> None: + self.columns: List[tuple[str, str]] = [] + + def column(self, name: str, dtype: str) -> FakeSchemaBuilder: + self.columns.append((name, dtype)) + return self + + def build(self) -> List[tuple[str, str]]: + return self.columns + + class FakeSchema: + @staticmethod + def new_builder() -> FakeSchemaBuilder: + return FakeSchemaBuilder() + + class FakeDataTypes: + @staticmethod + def BOOLEAN() -> str: + return "BOOLEAN" + + @staticmethod + def TINYINT() -> str: + return "TINYINT" + + @staticmethod + def SMALLINT() -> str: + return "SMALLINT" + + @staticmethod + def INT() -> str: + return "INT" + + @staticmethod + def BIGINT() -> str: + return "BIGINT" + + @staticmethod + def FLOAT() -> str: + return "FLOAT" + + @staticmethod + def DOUBLE() -> str: + return "DOUBLE" + + @staticmethod + def TIMESTAMP(precision: int) -> str: + return f"TIMESTAMP({precision})" + + @staticmethod + def TIMESTAMP_LTZ(precision: int) -> str: + return f"TIMESTAMP_LTZ({precision})" + + @staticmethod + def BYTES() -> str: + return "BYTES" + + @staticmethod + def DATE() -> str: + return "DATE" + + @staticmethod + def DECIMAL(precision: int, scale: int) -> str: + return f"DECIMAL({precision},{scale})" + + @staticmethod + def STRING() -> str: + return "STRING" + + pyflink_module = types.ModuleType("pyflink") + table_module = types.ModuleType("pyflink.table") + setattr(table_module, "Schema", FakeSchema) + setattr(table_module, "DataTypes", FakeDataTypes) + monkeypatch.setitem(sys.modules, "pyflink", pyflink_module) + monkeypatch.setitem(sys.modules, "pyflink.table", table_module) + + table_env = FakeTableEnvironment() + df = pd.DataFrame( + { + "driver_id": pd.Series([1, 2], dtype="int64"), + "conv_rate": pd.Series([0.1, 0.2], dtype="float64"), + "event_timestamp": pd.to_datetime( + ["2024-01-01 00:00:00", "2024-01-02 00:00:00"] + ), + "active": pd.Series([True, False], dtype="bool"), + } + ) + + pandas_to_flink_table(table_env, df, split_num=4) + + assert table_env.schemas[-1] == [ + ("driver_id", "BIGINT"), + ("conv_rate", "DOUBLE"), + ("event_timestamp", "TIMESTAMP(3)"), + ("active", "BOOLEAN"), + ] + assert table_env.schemas[-1] != list(df.columns) + assert table_env.split_nums == [4] + + +def _native_flink_value(columns: List[str]) -> DAGValue: + return DAGValue( + data=FakeNativeFlinkTable(columns), + format=DAGFormat.FLINK, + metadata={"columns": columns}, + ) + + +def test_repo_config_loads_flink_batch_engine_config(tmp_path: Path) -> None: + config = _repo_config( + tmp_path, + { + "type": "flink.engine", + "execution_mode": "streaming", + "parallelism": 3, + "table_config": {"pipeline.name": "feast-flink-test"}, + "pandas_split_num": 2, + }, + ) + + assert isinstance(config.batch_engine, FlinkComputeEngineConfig) + assert config.batch_engine.execution_mode == "streaming" + assert config.batch_engine.parallelism == 3 + assert config.batch_engine.table_config == {"pipeline.name": "feast-flink-test"} + assert config.batch_engine.pandas_split_num == 2 + + +def test_flink_source_read_node_converts_arrow_retrieval_jobs( + tmp_path: Path, +) -> None: + offline_store = MagicMock() + offline_store.pull_all_from_table_or_query.return_value = FakeRetrievalJob( + pa.Table.from_pandas(_feature_data()) + ) + context = _execution_context(tmp_path, {}) + context.offline_store = offline_store + node = FlinkSourceReadNode( + "source", + _source(), + _column_info(), + FakeTableEnvironment(), + split_num=1, + ) + + result = node.execute(context) + + assert result.format == DAGFormat.FLINK + assert result.metadata["columns"] == list(_feature_data().columns) + assert result.data.to_pandas().equals(_feature_data()) + + +def test_flink_historical_retrieval_executes_dag_with_transformation( + tmp_path: Path, +) -> None: + entity = _driver() + source = _source() + + def double_conv_rate(table: FakeFlinkTable) -> FakeFlinkTable: + df = table.to_pandas() + df["conv_rate"] = df["conv_rate"] * 2 + return FakeFlinkTable(df) + + feature_view = _feature_view( + source, + mode="flink", + udf=double_conv_rate, + udf_string="double_conv_rate", + online=False, + offline=False, + ) + config = _repo_config( + tmp_path, + {"type": "flink.engine", "pandas_split_num": 4}, + ) + table_env = FakeTableEnvironment() + engine = FlinkComputeEngine( + repo_config=config, + offline_store=_offline_store(_feature_data()), + online_store=MagicMock(), + table_environment=table_env, + ) + task = HistoricalRetrievalTask( + project=config.project, + entity_df=None, + feature_view=feature_view, + full_feature_name=False, + registry=_registry(entity), + ) + + job = engine.get_historical_features(_registry(entity), task) + result = job.to_df().sort_values("driver_id").reset_index(drop=True) + + assert job.error() is None + assert result["driver_id"].tolist() == [1, 2] + assert result["conv_rate"].tolist() == [0.4, 0.6] + assert table_env.dropped_views + assert table_env.views == {} + + +def test_flink_historical_retrieval_with_empty_entity_df_returns_empty_result( + tmp_path: Path, +) -> None: + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=False, offline=False) + config = _repo_config(tmp_path, {"type": "flink.engine", "pandas_split_num": 4}) + table_env = FakeTableEnvironment() + engine = FlinkComputeEngine( + repo_config=config, + offline_store=_offline_store(_feature_data()), + online_store=MagicMock(), + table_environment=table_env, + ) + task = HistoricalRetrievalTask( + project=config.project, + entity_df=pd.DataFrame( + { + "driver_id": pd.Series(dtype="int64"), + "event_timestamp": pd.Series(dtype="datetime64[ns]"), + } + ), + feature_view=feature_view, + full_feature_name=False, + registry=_registry(entity), + ) + + job = engine.get_historical_features(_registry(entity), task) + result = job.to_df() + + assert job.error() is None + assert result.empty + assert "conv_rate" in result.columns + assert table_env.created_tables[-1].empty + + +def test_flink_historical_retrieval_is_read_only_and_dedupes_per_entity_row( + tmp_path: Path, +) -> None: + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=True, offline=True) + config = _repo_config(tmp_path, {"type": "flink.engine", "pandas_split_num": 4}) + feature_data = pd.DataFrame( + { + "driver_id": [1, 1], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 0, 0), + datetime(2024, 1, 1, 10, 0, 0), + ], + "created": [ + datetime(2024, 1, 1, 9, 1, 0), + datetime(2024, 1, 1, 10, 1, 0), + ], + "conv_rate": [0.1, 0.2], + } + ) + offline_store = _offline_store(feature_data) + online_store = MagicMock() + table_env = FakeTableEnvironment() + engine = FlinkComputeEngine( + repo_config=config, + offline_store=offline_store, + online_store=online_store, + table_environment=table_env, + ) + task = HistoricalRetrievalTask( + project=config.project, + entity_df=pd.DataFrame( + { + "driver_id": [1, 1], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 30, 0), + datetime(2024, 1, 1, 10, 30, 0), + ], + } + ), + feature_view=feature_view, + full_feature_name=False, + registry=_registry(entity), + ) + + result = engine.get_historical_features(_registry(entity), task).to_df() + result = result.sort_values(ENTITY_TS_ALIAS).reset_index(drop=True) + + assert result["conv_rate"].tolist() == [0.1, 0.2] + assert table_env.split_nums == [4] + assert ENTITY_ROW_ID not in result.columns + online_store.online_write_batch.assert_not_called() + offline_store.offline_write_batch.assert_not_called() + + +def test_flink_historical_retrieval_supports_sql_entity_df(tmp_path: Path) -> None: + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=False, offline=False) + config = _repo_config(tmp_path, {"type": "flink.engine"}) + table_env = FakeTableEnvironment() + table_env.create_temporary_view( + "entities", + FakeFlinkTable( + pd.DataFrame( + { + "driver_id": [1, 1], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 30, 0), + datetime(2024, 1, 1, 10, 30, 0), + ], + } + ) + ), + ) + engine = FlinkComputeEngine( + repo_config=config, + offline_store=_offline_store(_feature_data()), + online_store=MagicMock(), + table_environment=table_env, + ) + task = HistoricalRetrievalTask( + project=config.project, + entity_df="SELECT driver_id, event_timestamp FROM entities", + feature_view=feature_view, + full_feature_name=False, + registry=_registry(entity), + ) + + job = engine.get_historical_features(_registry(entity), task) + result = job.to_df().sort_values(ENTITY_TS_ALIAS).reset_index(drop=True) + + assert job.error() is None + assert result["conv_rate"].tolist() == [0.1, 0.2] + assert any( + "SELECT driver_id, event_timestamp FROM entities" in query + for query in table_env.queries + ) + assert set(table_env.views) == {"entities"} + + +def test_flink_materialize_writes_online_and_offline(tmp_path: Path) -> None: + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=True, offline=True) + config = _repo_config(tmp_path, {"type": "flink.engine"}) + offline_store = _offline_store(_feature_data().head(1)) + online_store = MagicMock() + table_env = FakeTableEnvironment() + engine = FlinkComputeEngine( + repo_config=config, + offline_store=offline_store, + online_store=online_store, + table_environment=table_env, + ) + task = MaterializationTask( + project=config.project, + feature_view=feature_view, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + + jobs = engine.materialize(_registry(entity), task) + + assert len(jobs) == 1 + assert jobs[0].status() == MaterializationJobStatus.SUCCEEDED + assert jobs[0].error() is None + online_store.online_write_batch.assert_called_once() + offline_store.offline_write_batch.assert_called_once() + assert table_env.dropped_views + assert table_env.views == {} + + +def test_flink_output_node_streams_batches_without_full_pandas_collect( + tmp_path: Path, +) -> None: + source = _source() + feature_view = _feature_view(source, online=True, offline=True) + input_node = InputNode("input") + node = FlinkOutputNode( + "output", + feature_view, + FakeTableEnvironment(), + split_num=1, + write_output=True, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": DAGValue( + data=FakeFlinkTable(_feature_data().head(2), fail_on_to_pandas=True), + format=DAGFormat.FLINK, + metadata={"columns": list(_feature_data().columns)}, + ) + }, + ) + context.repo_config.materialization_config.online_write_batch_size = 1 + context.online_store = MagicMock() + context.offline_store = MagicMock() + + node.execute(context) + + assert context.online_store.online_write_batch.call_count == 2 + assert context.offline_store.offline_write_batch.call_count == 2 + + +def test_flink_engine_reports_materialization_errors(tmp_path: Path) -> None: + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=False, offline=False) + offline_store = MagicMock() + offline_store.pull_all_from_table_or_query.side_effect = RuntimeError("boom") + config = _repo_config(tmp_path, {"type": "flink.engine"}) + engine = FlinkComputeEngine( + repo_config=config, + offline_store=offline_store, + online_store=MagicMock(), + table_environment=FakeTableEnvironment(), + ) + task = MaterializationTask( + project=config.project, + feature_view=feature_view, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + + jobs = engine.materialize(_registry(entity), task) + + assert jobs[0].status() == MaterializationJobStatus.ERROR + assert isinstance(jobs[0].error(), RuntimeError) + + +def test_flink_join_node_merges_input_tables(tmp_path: Path) -> None: + left = InputNode("left") + right = InputNode("right") + node = FlinkJoinNode( + "join", + _column_info(), + FakeTableEnvironment(), + split_num=1, + inputs=[left, right], + ) + context = _execution_context( + tmp_path, + { + "left": _flink_value( + pd.DataFrame({"driver_id": [1, 2], "conv_rate": [0.1, 0.2]}) + ), + "right": _flink_value( + pd.DataFrame({"driver_id": [1, 2], "acc_rate": [0.3, 0.4]}) + ), + }, + ) + + result = node.execute(context).data.to_pandas().sort_values("driver_id") + + assert result["conv_rate"].tolist() == [0.1, 0.2] + assert result["acc_rate"].tolist() == [0.3, 0.4] + + +def test_flink_join_node_uses_native_sql_when_available(tmp_path: Path) -> None: + left = InputNode("left") + right = InputNode("right") + table_env = RecordingTableEnvironment() + node = FlinkJoinNode( + "join", + _column_info(), + table_env, + split_num=1, + inputs=[left, right], + ) + context = _execution_context( + tmp_path, + { + "left": _native_flink_value(["driver_id", "conv_rate"]), + "right": _native_flink_value(["driver_id", "acc_rate"]), + }, + ) + + result = node.execute(context) + + assert result.format == DAGFormat.FLINK + assert result.metadata["columns"] == ["driver_id", "conv_rate", "acc_rate"] + assert any("JOIN" in query for query in table_env.queries) + + +def test_flink_filter_node_applies_filter_expression(tmp_path: Path) -> None: + input_node = InputNode("input") + node = FlinkFilterNode( + "filter", + _column_info(), + FakeTableEnvironment(), + split_num=1, + filter_expr="conv_rate > 0.15", + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": _flink_value( + pd.DataFrame({"driver_id": [1, 2], "conv_rate": [0.1, 0.2]}) + ) + }, + ) + + result = node.execute(context).data.to_pandas() + + assert result["driver_id"].tolist() == [2] + + +def test_flink_filter_node_uses_native_sql_when_available(tmp_path: Path) -> None: + input_node = InputNode("input") + table_env = RecordingTableEnvironment() + node = FlinkFilterNode( + "filter", + _column_info(), + table_env, + split_num=1, + filter_expr="conv_rate > 0.15", + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + {"input": _native_flink_value(["driver_id", "conv_rate"])}, + ) + + result = node.execute(context) + + assert result.format == DAGFormat.FLINK + assert any( + "WHERE" in query and "conv_rate > 0.15" in query for query in table_env.queries + ) + + +def test_flink_filter_node_renders_ttl_as_valid_flink_interval( + tmp_path: Path, +) -> None: + input_node = InputNode("input") + table_env = RecordingTableEnvironment() + node = FlinkFilterNode( + "filter", + _column_info(), + table_env, + split_num=1, + ttl=timedelta(days=2, hours=3, minutes=4, seconds=5), + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": _native_flink_value( + ["driver_id", "conv_rate", "event_timestamp", ENTITY_TS_ALIAS] + ) + }, + ) + + node.execute(context) + + assert _subtract_flink_intervals( + "`__entity_event_timestamp`", timedelta(days=2, hours=3, minutes=4, seconds=5) + ) == ( + "`__entity_event_timestamp` - INTERVAL '2' DAY - INTERVAL '3' HOUR " + "- INTERVAL '4' MINUTE - INTERVAL '5' SECOND" + ) + assert any( + "`event_timestamp` >= `__entity_event_timestamp` - INTERVAL '2' DAY " + "- INTERVAL '3' HOUR - INTERVAL '4' MINUTE - INTERVAL '5' SECOND" in query + for query in table_env.queries + ) + assert all("+ INTERVAL" not in query for query in table_env.queries) + + +def test_flink_aggregation_node_groups_features(tmp_path: Path) -> None: + input_node = InputNode("input") + node = FlinkAggregationNode( + "agg", + ["driver_id"], + aggregations=[Aggregation(column="conv_rate", function="sum")], + table_env=FakeTableEnvironment(), + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": _flink_value( + pd.DataFrame({"driver_id": [1, 1, 2], "conv_rate": [0.1, 0.2, 0.3]}) + ) + }, + ) + + result = node.execute(context).data.to_pandas().sort_values("driver_id") + + assert result["sum_conv_rate"].tolist() == pytest.approx([0.3, 0.3]) + + +def test_flink_aggregation_node_uses_native_sql_when_available(tmp_path: Path) -> None: + input_node = InputNode("input") + table_env = RecordingTableEnvironment() + node = FlinkAggregationNode( + "agg", + ["driver_id"], + aggregations=[Aggregation(column="conv_rate", function="sum")], + table_env=table_env, + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + {"input": _native_flink_value(["driver_id", "conv_rate"])}, + ) + + result = node.execute(context) + + assert result.format == DAGFormat.FLINK + assert result.metadata["columns"] == ["driver_id", "sum_conv_rate"] + assert any("GROUP BY" in query and "SUM" in query for query in table_env.queries) + + +def test_flink_dedup_node_uses_entity_row_id_for_historical_retrieval( + tmp_path: Path, +) -> None: + input_node = InputNode("input") + node = FlinkDedupNode( + "dedup", + _column_info(), + FakeTableEnvironment(), + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": _flink_value( + pd.DataFrame( + { + ENTITY_ROW_ID: [0, 0, 1], + "driver_id": [1, 1, 1], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 0, 0), + datetime(2024, 1, 1, 10, 0, 0), + datetime(2024, 1, 1, 10, 0, 0), + ], + "created": [ + datetime(2024, 1, 1, 9, 1, 0), + datetime(2024, 1, 1, 10, 1, 0), + datetime(2024, 1, 1, 10, 1, 0), + ], + "conv_rate": [0.1, 0.2, 0.3], + } + ) + ) + }, + ) + + result = node.execute(context).data.to_pandas().sort_values(ENTITY_ROW_ID) + + assert result["conv_rate"].tolist() == [0.2, 0.3] + + +def test_flink_dedup_node_uses_native_row_number_when_available( + tmp_path: Path, +) -> None: + input_node = InputNode("input") + table_env = RecordingTableEnvironment() + node = FlinkDedupNode( + "dedup", + _column_info(), + table_env, + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + { + "input": _native_flink_value( + [ENTITY_ROW_ID, "driver_id", "event_timestamp", "created", "conv_rate"] + ) + }, + ) + + result = node.execute(context) + + assert result.format == DAGFormat.FLINK + assert any("ROW_NUMBER() OVER" in query for query in table_env.queries) + assert ENTITY_ROW_ID in result.metadata["columns"] + + +def test_flink_transformation_node_keeps_native_flink_table(tmp_path: Path) -> None: + input_node = InputNode("input") + native_result = FakeNativeFlinkTable(["driver_id", "conv_rate"]) + + def native_udf(table: object) -> FakeNativeFlinkTable: + return native_result + + node = FlinkTransformationNode( + "transform", + native_udf, + RecordingTableEnvironment(), + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + {"input": _native_flink_value(["driver_id", "conv_rate"])}, + ) + + result = node.execute(context) + + assert result.data is native_result + assert result.metadata["columns"] == ["driver_id", "conv_rate"] + + +def test_flink_validation_node_raises_for_missing_columns(tmp_path: Path) -> None: + input_node = InputNode("input") + node = FlinkValidationNode( + "validate", + expected_columns={"missing_feature": pa.float32()}, + json_columns=set(), + table_env=FakeTableEnvironment(), + split_num=1, + inputs=[input_node], + ) + context = _execution_context( + tmp_path, + {"input": _flink_value(pd.DataFrame({"driver_id": [1]}))}, + ) + + with pytest.raises(ValueError, match="Missing expected columns"): + node.execute(context) + + +@pytest.mark.integration +@pytest.mark.slow +def test_flink_compute_engine_executes_with_real_pyflink_when_installed( + tmp_path: Path, +) -> None: + pyflink_table = pytest.importorskip( + "pyflink.table", reason="PyFlink is required for this runtime smoke test" + ) + entity = _driver() + source = _source() + feature_view = _feature_view(source, online=True, offline=True) + config = _repo_config(tmp_path, {"type": "flink.engine"}) + offline_store = _offline_store(_feature_data()) + online_store = MagicMock() + table_env = pyflink_table.TableEnvironment.create( + pyflink_table.EnvironmentSettings.new_instance().in_batch_mode().build() + ) + engine = FlinkComputeEngine( + repo_config=config, + offline_store=offline_store, + online_store=online_store, + table_environment=table_env, + ) + task = HistoricalRetrievalTask( + project=config.project, + entity_df=pd.DataFrame( + { + "driver_id": [1, 1, 2], + "event_timestamp": [ + datetime(2024, 1, 1, 9, 30, 0), + datetime(2024, 1, 1, 10, 30, 0), + datetime(2024, 1, 1, 10, 30, 0), + ], + } + ), + feature_view=feature_view, + full_feature_name=False, + registry=_registry(entity), + ) + + result = engine.get_historical_features(_registry(entity), task).to_df() + result = result.sort_values(["driver_id", ENTITY_TS_ALIAS]).reset_index(drop=True) + + assert result["conv_rate"].tolist() == [0.1, 0.2, 0.3] + assert ENTITY_ROW_ID not in result.columns + online_store.online_write_batch.assert_not_called() + + materialization_task = MaterializationTask( + project=config.project, + feature_view=feature_view, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + + jobs = engine.materialize(_registry(entity), materialization_task) + + assert jobs[0].status() == MaterializationJobStatus.SUCCEEDED + assert jobs[0].error() is None + online_store.online_write_batch.assert_called_once() + offline_store.offline_write_batch.assert_called_once() diff --git a/sdk/python/tests/unit/infra/compute_engines/local/test_nodes.py b/sdk/python/tests/unit/infra/compute_engines/local/test_nodes.py index 905ea65ae42..872dd978c9e 100644 --- a/sdk/python/tests/unit/infra/compute_engines/local/test_nodes.py +++ b/sdk/python/tests/unit/infra/compute_engines/local/test_nodes.py @@ -15,6 +15,7 @@ LocalOutputNode, LocalTransformationNode, ) +from feast.repo_config import MaterializationConfig backend = PandasBackend() now = pd.Timestamp.utcnow() @@ -37,9 +38,11 @@ def create_context(node_outputs): # Setup execution context + repo_config = MagicMock() + repo_config.materialization_config = MaterializationConfig() return ExecutionContext( project="test_proj", - repo_config=MagicMock(), + repo_config=repo_config, offline_store=MagicMock(), online_store=MagicMock(), entity_defs=MagicMock(), @@ -183,6 +186,122 @@ def test_local_dedup_node(): assert set(df_result["entity_id"]) == {1, 2} +def test_local_dedup_node_with_field_mapping_on_join_key(): + """Regression test for materialization failure when a join key has a field mapping. + + The source-read node renames columns via field_mapping (e.g. ``USERID`` -> ``user_id``) + before passing the table to downstream nodes. Without mapping ``column_info.join_keys`` + the dedup node would look up the pre-mapping name and raise ``KeyError(['USERID'])``. + + See https://github.com/feast-dev/feast/issues/5942. + """ + # Simulate a source-read node output: columns already renamed to the mapped names. + df = pd.DataFrame( + { + "user_id": [1, 1, 2], + "value": [100, 200, 300], + "event_timestamp": [ + now - timedelta(seconds=1), + now, + now, + ], + } + ) + + context = create_context( + node_outputs={"source": ArrowTableValue(pa.Table.from_pandas(df))} + ) + + node = LocalDedupNode( + name="dedup", + backend=backend, + column_info=ColumnInfo( + # The raw join key matches the source column name; field_mapping maps + # it to the user-facing name that the source-read node has already + # renamed the column to. + join_keys=["USERID"], + feature_cols=["value"], + ts_col="EVENT_TIMESTAMP", + created_ts_col=None, + field_mapping={"USERID": "user_id", "EVENT_TIMESTAMP": "event_timestamp"}, + ), + ) + node.add_input(MagicMock()) + node.inputs[0].name = "source" + + result = node.execute(context) + + df_result = result.data.to_pandas() + assert df_result.shape[0] == 2 + assert set(df_result["user_id"]) == {1, 2} + + +def test_local_join_node_with_field_mapping_on_join_key(): + """Regression test for materialization failure when a join key has a field mapping. + + The source-read node renames columns via field_mapping (e.g. ``USERID`` -> ``user_id``) + before passing the table to downstream nodes. Without mapping ``column_info.join_keys`` + the join node would call ``backend.join(..., on=["USERID"], ...)`` and raise + ``KeyError(['USERID'])`` because the columns have already been renamed. + + See https://github.com/feast-dev/feast/issues/5942. + """ + # Simulate two source-read node outputs: columns already renamed to the mapped names. + left_df = pd.DataFrame( + { + "user_id": [1, 2], + "value": [10, 20], + "event_timestamp": [now, now], + } + ) + right_df = pd.DataFrame( + { + "user_id": [1, 2], + "other_value": [100, 200], + "event_timestamp": [now, now], + } + ) + + context = create_context( + node_outputs={ + "left": ArrowTableValue(pa.Table.from_pandas(left_df)), + "right": ArrowTableValue(pa.Table.from_pandas(right_df)), + } + ) + # Bypass the trailing entity_df join — this test exercises the input-table + # join path that consumed the raw (unmapped) join keys before the fix. + context.entity_df = None + + join_node = LocalJoinNode( + name="join", + backend=backend, + column_info=ColumnInfo( + # Raw join key matches the source column name; field_mapping maps it + # to the user-facing name that the source-read node has already + # renamed the column to. + join_keys=["USERID"], + feature_cols=["value", "other_value"], + ts_col="EVENT_TIMESTAMP", + created_ts_col=None, + field_mapping={"USERID": "user_id", "EVENT_TIMESTAMP": "event_timestamp"}, + ), + ) + left_input = MagicMock() + left_input.name = "left" + right_input = MagicMock() + right_input.name = "right" + join_node.add_input(left_input) + join_node.add_input(right_input) + + result = join_node.execute(context) + + df_result = result.data.to_pandas() + assert df_result.shape[0] == 2 + assert set(df_result["user_id"]) == {1, 2} + assert "value" in df_result.columns + assert "other_value" in df_result.columns + + def test_local_transformation_node(): context = create_context( node_outputs={"source": ArrowTableValue(pa.Table.from_pandas(sample_df))} @@ -213,4 +332,54 @@ def test_local_output_node(): node.add_input(MagicMock()) node.inputs[0].name = "source" result = node.execute(context) - assert result.num_rows == 4 + assert isinstance(result, ArrowTableValue) + assert result.data.num_rows == 4 + + +def test_local_output_node_online_write_default_batch(): + """Test that online_write_batch is called once when batch_size is None (default).""" + # Create a feature view with online=True + feature_view = MagicMock() + feature_view.online = True + feature_view.offline = False + feature_view.entity_columns = [] + + # Create context with default materialization config (batch_size=None) + context = create_context( + node_outputs={"source": ArrowTableValue(pa.Table.from_pandas(sample_df))} + ) + + node = LocalOutputNode("output", feature_view) + node.add_input(MagicMock()) + node.inputs[0].name = "source" + + node.execute(context) + + # Verify online_write_batch was called exactly once (all rows in single batch) + assert context.online_store.online_write_batch.call_count == 1 + + +def test_local_output_node_online_write_batched(): + """Test that online_write_batch is called multiple times when batch_size is configured.""" + # Create a feature view with online=True + feature_view = MagicMock() + feature_view.online = True + feature_view.offline = False + feature_view.entity_columns = [] + + # Create context with batch_size=2 (sample_df has 4 rows, so expect 2 batches) + context = create_context( + node_outputs={"source": ArrowTableValue(pa.Table.from_pandas(sample_df))} + ) + context.repo_config.materialization_config = MaterializationConfig( + online_write_batch_size=2 + ) + + node = LocalOutputNode("output", feature_view) + node.add_input(MagicMock()) + node.inputs[0].name = "source" + + node.execute(context) + + # Verify online_write_batch was called twice (4 rows / batch_size 2 = 2 batches) + assert context.online_store.online_write_batch.call_count == 2 diff --git a/sdk/python/tests/unit/infra/compute_engines/test_backend_factory.py b/sdk/python/tests/unit/infra/compute_engines/test_backend_factory.py new file mode 100644 index 00000000000..ee0ebf1e8ec --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/test_backend_factory.py @@ -0,0 +1,55 @@ +from unittest.mock import MagicMock, patch + +import pandas as pd +import pyarrow +import pytest + +from feast.infra.compute_engines.backends.factory import BackendFactory +from feast.infra.compute_engines.backends.pandas_backend import PandasBackend + + +class TestBackendFactoryFromName: + def test_pandas_backend(self): + backend = BackendFactory.from_name("pandas") + assert isinstance(backend, PandasBackend) + + @patch( + "feast.infra.compute_engines.backends.factory.BackendFactory._get_polars_backend" + ) + def test_polars_backend(self, mock_get_polars): + mock_backend = MagicMock() + mock_get_polars.return_value = mock_backend + + result = BackendFactory.from_name("polars") + assert result is mock_backend + + def test_unsupported_name_raises(self): + with pytest.raises(ValueError, match="Unsupported backend name"): + BackendFactory.from_name("dask") + + +class TestBackendFactoryInferFromEntityDf: + def test_pandas_dataframe_returns_pandas_backend(self): + """A non-empty pandas DataFrame is detected via isinstance check.""" + df = pd.DataFrame({"a": [1, 2]}) + backend = BackendFactory.infer_from_entity_df(df) + assert isinstance(backend, PandasBackend) + + def test_empty_pandas_dataframe_returns_pandas_backend(self): + """An empty pandas DataFrame returns PandasBackend.""" + df = pd.DataFrame() + backend = BackendFactory.infer_from_entity_df(df) + assert isinstance(backend, PandasBackend) + + def test_pyarrow_table(self): + table = pyarrow.table({"a": [1, 2]}) + backend = BackendFactory.infer_from_entity_df(table) + assert isinstance(backend, PandasBackend) + + def test_none_input(self): + backend = BackendFactory.infer_from_entity_df(None) + assert isinstance(backend, PandasBackend) + + def test_empty_string_input(self): + backend = BackendFactory.infer_from_entity_df("") + assert isinstance(backend, PandasBackend) diff --git a/sdk/python/tests/unit/infra/compute_engines/test_feature_builder.py b/sdk/python/tests/unit/infra/compute_engines/test_feature_builder.py index b78ef15299c..8ad19d02290 100644 --- a/sdk/python/tests/unit/infra/compute_engines/test_feature_builder.py +++ b/sdk/python/tests/unit/infra/compute_engines/test_feature_builder.py @@ -1,4 +1,6 @@ -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch + +import pytest from feast.data_source import DataSource from feast.infra.compute_engines.dag.context import ExecutionContext @@ -7,6 +9,7 @@ from feast.infra.compute_engines.dag.plan import ExecutionPlan from feast.infra.compute_engines.dag.value import DAGValue from feast.infra.compute_engines.feature_builder import FeatureBuilder +from feast.transformation.mode import TransformationMode # --------------------------- # Minimal Mock DAGNode for testing @@ -143,3 +146,144 @@ def test_recursive_featureview_build(): - Source(hourly_driver_stats)""" assert execution_plan.to_dag() == expected_output + + +# --------------------------------------------------------------------------- +# Helpers for get_column_info tests +# --------------------------------------------------------------------------- + +# Stable return value for _get_column_names: (join_keys, feature_cols, ts_col, created_ts_col) +_MOCK_COLUMN_NAMES = ( + ["user_id"], + ["user_avg_rating", "user_review_count"], + "event_timestamp", + None, +) + + +def _make_transformation(mode): + """Return a minimal transformation stub with the given mode.""" + t = MagicMock() + t.mode = mode + return t + + +def _make_builder_for_column_info(transformation): + """ + Build a MockFeatureBuilder whose task.feature_view carries the given + transformation. registry.get_entity is stubbed out per entity name. + """ + view = MagicMock() + view.entities = ["user"] + view.feature_transformation = transformation + view.batch_source = MagicMock() + view.batch_source.field_mapping = {} + view.stream_source = None + + task = MagicMock() + task.project = "test_project" + task.feature_view = view + task.only_latest = False + + registry = MagicMock() + registry.get_entity.return_value = MagicMock(join_key="user_id") + + builder = MockFeatureBuilder.__new__(MockFeatureBuilder) + builder.registry = registry + builder.task = task + builder.nodes = [] + return builder, view + + +# --------------------------------------------------------------------------- +# Bug fix: TransformationMode.PYTHON must set feature_cols=[] +# +# Previously only "ray" and "pandas" were handled. "python" (the default mode +# for @batch_feature_view) was missing, causing get_column_info to forward +# the BFV *output* feature names (e.g. user_avg_rating) to the offline store +# read step — columns that don't exist in raw source data — resulting in +# UNRESOLVED_COLUMN errors at Spark analysis time. +# --------------------------------------------------------------------------- + + +@pytest.mark.parametrize( + "mode", + [ + TransformationMode.PYTHON, + TransformationMode.PANDAS, + TransformationMode.RAY, + # String forms (getattr(mode, "value", None) path) + "python", + "pandas", + "ray", + ], +) +def test_get_column_info_clears_feature_cols_for_udf_modes(mode): + """ + For transformation modes that compute output features from raw input + (python, pandas, ray), get_column_info must set feature_cols=[] so the + offline store read step issues SELECT * instead of projecting the output + feature names that don't exist in the raw source schema. + """ + builder, view = _make_builder_for_column_info(_make_transformation(mode)) + + with patch( + "feast.infra.compute_engines.feature_builder._get_column_names", + return_value=_MOCK_COLUMN_NAMES, + ): + col_info = builder.get_column_info(view) + + assert col_info.feature_cols == [], ( + f"Expected feature_cols=[] for TransformationMode {mode!r}, " + f"got {col_info.feature_cols!r}. " + "The offline store read step must not project output feature names " + "that don't exist in the raw source schema." + ) + assert col_info.join_keys == ["user_id"] + assert col_info.ts_col == "event_timestamp" + + +@pytest.mark.parametrize( + "mode", + [ + TransformationMode.SPARK_SQL, + TransformationMode.SQL, + TransformationMode.SPARK, + "spark_sql", + "sql", + ], +) +def test_get_column_info_preserves_feature_cols_for_non_udf_modes(mode): + """ + SQL/Spark-SQL transformations operate on already-projected columns and + should NOT get feature_cols cleared — the source read must still select + the named feature columns explicitly. + """ + builder, view = _make_builder_for_column_info(_make_transformation(mode)) + + with patch( + "feast.infra.compute_engines.feature_builder._get_column_names", + return_value=_MOCK_COLUMN_NAMES, + ): + col_info = builder.get_column_info(view) + + assert col_info.feature_cols == ["user_avg_rating", "user_review_count"], ( + f"Expected feature_cols to be preserved for mode {mode!r}, " + f"got {col_info.feature_cols!r}." + ) + + +def test_get_column_info_preserves_feature_cols_with_no_transformation(): + """ + A plain FeatureView (no transformation) must retain its feature column + names so the offline store read step selects only the required columns. + """ + builder, view = _make_builder_for_column_info(None) + + with patch( + "feast.infra.compute_engines.feature_builder._get_column_names", + return_value=_MOCK_COLUMN_NAMES, + ): + col_info = builder.get_column_info(view) + + assert col_info.feature_cols == ["user_avg_rating", "user_review_count"] diff --git a/sdk/python/tests/unit/infra/compute_engines/test_local_compute_engine.py b/sdk/python/tests/unit/infra/compute_engines/test_local_compute_engine.py new file mode 100644 index 00000000000..3396a45c995 --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/test_local_compute_engine.py @@ -0,0 +1,67 @@ +from unittest.mock import MagicMock + +from feast.infra.compute_engines.base import ComputeEngine +from feast.infra.compute_engines.local.compute import ( + LocalComputeEngine, + LocalComputeEngineConfig, +) + + +class TestLocalComputeEngineConfig: + def test_default_type(self): + config = LocalComputeEngineConfig() + assert config.type == "local" + + def test_default_backend_none(self): + config = LocalComputeEngineConfig() + assert config.backend is None + + def test_custom_backend(self): + config = LocalComputeEngineConfig(backend="polars") + assert config.backend == "polars" + + +class TestLocalComputeEngine: + def _make_engine(self): + return LocalComputeEngine( + repo_config=MagicMock(), + offline_store=MagicMock(), + online_store=MagicMock(), + ) + + def test_is_compute_engine(self): + engine = self._make_engine() + assert isinstance(engine, ComputeEngine) + + def test_update_is_noop(self): + engine = self._make_engine() + # Should not raise + engine.update( + project="test", + views_to_delete=[], + views_to_keep=[], + entities_to_delete=[], + entities_to_keep=[], + ) + + def test_teardown_is_noop(self): + engine = self._make_engine() + # Should not raise + engine.teardown_infra( + project="test", + fvs=[], + entities=[], + ) + + def test_stores_config(self): + repo_config = MagicMock() + offline = MagicMock() + online = MagicMock() + engine = LocalComputeEngine( + repo_config=repo_config, + offline_store=offline, + online_store=online, + ) + assert engine.repo_config is repo_config + assert engine.offline_store is offline + assert engine.online_store is online diff --git a/sdk/python/tests/unit/infra/compute_engines/test_local_job.py b/sdk/python/tests/unit/infra/compute_engines/test_local_job.py new file mode 100644 index 00000000000..2f4a1ac48fd --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/test_local_job.py @@ -0,0 +1,100 @@ +from unittest.mock import MagicMock + +import pytest + +from feast.infra.common.materialization_job import MaterializationJobStatus +from feast.infra.compute_engines.local.job import ( + LocalMaterializationJob, + LocalRetrievalJob, +) + + +class TestLocalMaterializationJob: + def test_status(self): + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.SUCCEEDED, + ) + assert job.status() == MaterializationJobStatus.SUCCEEDED + + def test_job_id(self): + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.RUNNING, + ) + assert job.job_id() == "test-job-1" + + def test_error_none_by_default(self): + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.SUCCEEDED, + ) + assert job.error() is None + + def test_error_stored(self): + err = RuntimeError("something failed") + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.ERROR, + error=err, + ) + assert job.error() is err + + def test_should_not_be_retried(self): + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.ERROR, + ) + assert job.should_be_retried() is False + + def test_url_is_none(self): + job = LocalMaterializationJob( + job_id="test-job-1", + status=MaterializationJobStatus.SUCCEEDED, + ) + assert job.url() is None + + +class TestLocalRetrievalJob: + def test_full_feature_names(self): + job = LocalRetrievalJob( + plan=None, + context=MagicMock(), + full_feature_names=True, + ) + assert job.full_feature_names is True + + def test_full_feature_names_false(self): + job = LocalRetrievalJob( + plan=None, + context=MagicMock(), + full_feature_names=False, + ) + assert job.full_feature_names is False + + def test_error_none_by_default(self): + job = LocalRetrievalJob(plan=None, context=MagicMock()) + assert job.error() is None + + def test_error_stored(self): + err = ValueError("bad data") + job = LocalRetrievalJob(plan=None, context=MagicMock(), error=err) + assert job.error() is err + + def test_on_demand_feature_views_default_empty(self): + job = LocalRetrievalJob(plan=None, context=MagicMock()) + assert job.on_demand_feature_views == [] + + def test_metadata_default_none(self): + job = LocalRetrievalJob(plan=None, context=MagicMock()) + assert job.metadata is None + + def test_to_remote_storage_raises(self): + job = LocalRetrievalJob(plan=None, context=MagicMock()) + with pytest.raises(NotImplementedError, match="Remote storage"): + job.to_remote_storage() + + def test_to_sql_raises(self): + job = LocalRetrievalJob(plan=None, context=MagicMock()) + with pytest.raises(NotImplementedError, match="SQL generation"): + job.to_sql() diff --git a/sdk/python/tests/unit/infra/compute_engines/test_materialization_job.py b/sdk/python/tests/unit/infra/compute_engines/test_materialization_job.py new file mode 100644 index 00000000000..8d6ab4f2288 --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/test_materialization_job.py @@ -0,0 +1,59 @@ +from datetime import datetime +from unittest.mock import MagicMock + +from feast.infra.common.materialization_job import ( + MaterializationJobStatus, + MaterializationTask, +) + + +class TestMaterializationJobStatus: + def test_all_statuses_defined(self): + expected = { + "WAITING", + "RUNNING", + "AVAILABLE", + "ERROR", + "CANCELLING", + "CANCELLED", + "SUCCEEDED", + "PAUSED", + "RETRYING", + } + actual = {s.name for s in MaterializationJobStatus} + assert actual == expected + + +class TestMaterializationTask: + def test_creation(self): + mock_fv = MagicMock() + task = MaterializationTask( + project="my_project", + feature_view=mock_fv, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + assert task.project == "my_project" + assert task.feature_view is mock_fv + assert task.start_time == datetime(2024, 1, 1) + assert task.end_time == datetime(2024, 1, 2) + + def test_default_only_latest(self): + mock_fv = MagicMock() + task = MaterializationTask( + project="p", + feature_view=mock_fv, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + assert task.only_latest is True + + def test_default_disable_event_timestamp(self): + mock_fv = MagicMock() + task = MaterializationTask( + project="p", + feature_view=mock_fv, + start_time=datetime(2024, 1, 1), + end_time=datetime(2024, 1, 2), + ) + assert task.disable_event_timestamp is False diff --git a/sdk/python/tests/unit/infra/compute_engines/test_topo_sort.py b/sdk/python/tests/unit/infra/compute_engines/test_topo_sort.py new file mode 100644 index 00000000000..5bec3f63734 --- /dev/null +++ b/sdk/python/tests/unit/infra/compute_engines/test_topo_sort.py @@ -0,0 +1,90 @@ +from unittest.mock import MagicMock + +from feast.infra.compute_engines.algorithms.topo import ( + topological_sort, + topological_sort_multiple, +) +from feast.infra.compute_engines.dag.node import DAGNode + + +def _make_node(name, inputs=None): + """Create a mock DAGNode.""" + node = MagicMock(spec=DAGNode) + node.name = name + node.inputs = inputs or [] + return node + + +class TestTopologicalSort: + def test_single_node(self): + root = _make_node("root") + result = topological_sort(root) + assert len(result) == 1 + assert result[0] is root + + def test_linear_chain(self): + """A -> B -> C should produce [A, B, C].""" + a = _make_node("A") + b = _make_node("B", inputs=[a]) + c = _make_node("C", inputs=[b]) + + result = topological_sort(c) + assert len(result) == 3 + # Dependencies must come before dependents + assert result.index(a) < result.index(b) + assert result.index(b) < result.index(c) + + def test_diamond_dependency(self): + """ + A → B + A → C + B,C → D + Should visit A before B and C, and B/C before D. + """ + a = _make_node("A") + b = _make_node("B", inputs=[a]) + c = _make_node("C", inputs=[a]) + d = _make_node("D", inputs=[b, c]) + + result = topological_sort(d) + assert len(result) == 4 + assert result.index(a) < result.index(b) + assert result.index(a) < result.index(c) + assert result.index(b) < result.index(d) + assert result.index(c) < result.index(d) + + def test_no_duplicates(self): + """Shared dependencies should appear only once.""" + shared = _make_node("shared") + b = _make_node("B", inputs=[shared]) + c = _make_node("C", inputs=[shared]) + root = _make_node("root", inputs=[b, c]) + + result = topological_sort(root) + assert result.count(shared) == 1 + + +class TestTopologicalSortMultiple: + def test_multiple_roots_no_overlap(self): + r1 = _make_node("root1") + r2 = _make_node("root2") + + result = topological_sort_multiple([r1, r2]) + assert len(result) == 2 + assert r1 in result + assert r2 in result + + def test_multiple_roots_with_shared_dep(self): + shared = _make_node("shared") + r1 = _make_node("root1", inputs=[shared]) + r2 = _make_node("root2", inputs=[shared]) + + result = topological_sort_multiple([r1, r2]) + assert len(result) == 3 + assert result.count(shared) == 1 + assert result.index(shared) < result.index(r1) + assert result.index(shared) < result.index(r2) + + def test_empty_roots(self): + result = topological_sort_multiple([]) + assert result == [] diff --git a/sdk/python/tests/unit/infra/feature_servers/test_mcp_server.py b/sdk/python/tests/unit/infra/feature_servers/test_mcp_server.py index f5748be1acc..7fe0fa3d99a 100644 --- a/sdk/python/tests/unit/infra/feature_servers/test_mcp_server.py +++ b/sdk/python/tests/unit/infra/feature_servers/test_mcp_server.py @@ -1,6 +1,9 @@ import unittest +from types import SimpleNamespace from unittest.mock import Mock, patch +from pydantic import ValidationError + from feast.feature_store import FeatureStore from feast.infra.mcp_servers.mcp_config import McpFeatureServerConfig @@ -17,7 +20,7 @@ def test_default_config(self): self.assertFalse(config.mcp_enabled) self.assertEqual(config.mcp_server_name, "feast-mcp-server") self.assertEqual(config.mcp_server_version, "1.0.0") - self.assertIsNone(config.mcp_transport) + self.assertEqual(config.mcp_transport, "sse") self.assertEqual(config.transformation_service_endpoint, "localhost:6566") def test_custom_config(self): @@ -41,11 +44,11 @@ def test_custom_config(self): def test_config_validation(self): """Test configuration validation.""" - # Test valid transport options - valid_transports = ["sse", "websocket", None] - for transport in valid_transports: + for transport in ["sse", "http"]: config = McpFeatureServerConfig(mcp_transport=transport) self.assertEqual(config.mcp_transport, transport) + with self.assertRaises(ValidationError): + McpFeatureServerConfig(mcp_transport="websocket") def test_config_inheritance(self): """Test that McpFeatureServerConfig properly inherits from BaseFeatureServerConfig.""" @@ -66,12 +69,13 @@ def test_add_mcp_support_success(self, mock_fast_api_mcp): mock_app = Mock() mock_store = Mock(spec=FeatureStore) - mock_config = Mock() - mock_config.mcp_server_name = "test-server" - mock_config.mcp_server_version = "1.0.0" + mock_config = SimpleNamespace( + mcp_server_name="test-server", + mcp_server_version="1.0.0", + mcp_transport="sse", + ) - # Mock the FastApiMCP instance - mock_mcp_instance = Mock() + mock_mcp_instance = Mock(spec_set=["mount_sse", "mount", "mount_http"]) mock_fast_api_mcp.return_value = mock_mcp_instance result = add_mcp_support_to_app(mock_app, mock_store, mock_config) @@ -83,8 +87,7 @@ def test_add_mcp_support_success(self, mock_fast_api_mcp): description="Feast Feature Store MCP Server - Access feature store data and operations through MCP", ) - # Verify mount was called - mock_mcp_instance.mount.assert_called_once() + mock_mcp_instance.mount_sse.assert_called_once() # Verify the result self.assertEqual(result, mock_mcp_instance) @@ -96,11 +99,9 @@ def test_add_mcp_support_with_defaults(self, mock_fast_api_mcp): mock_app = Mock() mock_store = Mock(spec=FeatureStore) - mock_config = Mock() - # Don't set mcp_server_name to test default - del mock_config.mcp_server_name + mock_config = SimpleNamespace(mcp_transport="sse") - mock_mcp_instance = Mock() + mock_mcp_instance = Mock(spec_set=["mount_sse", "mount", "mount_http"]) mock_fast_api_mcp.return_value = mock_mcp_instance result = add_mcp_support_to_app(mock_app, mock_store, mock_config) @@ -114,6 +115,40 @@ def test_add_mcp_support_with_defaults(self, mock_fast_api_mcp): self.assertEqual(result, mock_mcp_instance) + @patch("feast.infra.mcp_servers.mcp_server.FastApiMCP") + def test_add_mcp_support_http_transport(self, mock_fast_api_mcp): + from feast.infra.mcp_servers.mcp_server import add_mcp_support_to_app + + mock_app = Mock() + mock_store = Mock(spec=FeatureStore) + mock_config = SimpleNamespace( + mcp_server_name="test-server", mcp_transport="http" + ) + + mock_mcp_instance = Mock(spec_set=["mount_http"]) + mock_fast_api_mcp.return_value = mock_mcp_instance + + result = add_mcp_support_to_app(mock_app, mock_store, mock_config) + mock_mcp_instance.mount_http.assert_called_once() + self.assertEqual(result, mock_mcp_instance) + + @patch("feast.infra.mcp_servers.mcp_server.FastApiMCP") + def test_add_mcp_support_http_missing_mount_http_fails(self, mock_fast_api_mcp): + from feast.infra.mcp_servers.mcp_server import ( + McpTransportNotSupportedError, + add_mcp_support_to_app, + ) + + mock_app = Mock() + mock_store = Mock(spec=FeatureStore) + mock_config = SimpleNamespace(mcp_transport="http") + + mock_mcp_instance = Mock(spec_set=["mount"]) + mock_fast_api_mcp.return_value = mock_mcp_instance + + with self.assertRaises(McpTransportNotSupportedError): + add_mcp_support_to_app(mock_app, mock_store, mock_config) + @patch("feast.infra.mcp_servers.mcp_server.FastApiMCP") @patch("feast.infra.mcp_servers.mcp_server.logger") def test_add_mcp_support_with_exception(self, mock_logger, mock_fast_api_mcp): @@ -122,8 +157,9 @@ def test_add_mcp_support_with_exception(self, mock_logger, mock_fast_api_mcp): mock_app = Mock() mock_store = Mock(spec=FeatureStore) - mock_config = Mock() - mock_config.mcp_server_name = "test-server" + mock_config = SimpleNamespace( + mcp_server_name="test-server", mcp_transport="sse" + ) # Mock FastApiMCP to raise an exception mock_fast_api_mcp.side_effect = Exception("MCP initialization failed") @@ -135,7 +171,8 @@ def test_add_mcp_support_with_exception(self, mock_logger, mock_fast_api_mcp): # Verify error was logged mock_logger.error.assert_called_once_with( - "Failed to initialize MCP integration: MCP initialization failed" + "Failed to initialize MCP integration: MCP initialization failed", + exc_info=True, ) @patch("feast.infra.mcp_servers.mcp_server.FastApiMCP") @@ -145,10 +182,11 @@ def test_add_mcp_support_mount_exception(self, mock_fast_api_mcp): mock_app = Mock() mock_store = Mock(spec=FeatureStore) - mock_config = Mock() - mock_config.mcp_server_name = "test-server" + mock_config = SimpleNamespace( + mcp_server_name="test-server", mcp_transport="sse" + ) - mock_mcp_instance = Mock() + mock_mcp_instance = Mock(spec_set=["mount"]) mock_mcp_instance.mount.side_effect = Exception("Mount failed") mock_fast_api_mcp.return_value = mock_mcp_instance @@ -203,3 +241,85 @@ def test_add_mcp_support_if_enabled_exception(self, mock_logger): mock_logger.error.assert_called_with( "Error checking/adding MCP support: Test error" ) + + @patch("feast.infra.mcp_servers.mcp_server.add_mcp_support_to_app") + def test_add_mcp_support_if_enabled_transport_not_supported_fails(self, mock_add): + from feast.feature_server import _add_mcp_support_if_enabled + from feast.infra.mcp_servers.mcp_server import McpTransportNotSupportedError + + mock_app = Mock() + mock_store = Mock() + mock_store.config.feature_server = Mock() + mock_store.config.feature_server.type = "mcp" + mock_store.config.feature_server.mcp_enabled = True + mock_store.config.feature_server.mcp_transport = "http" + + mock_add.side_effect = McpTransportNotSupportedError("bad") + + with self.assertRaises(McpTransportNotSupportedError): + _add_mcp_support_if_enabled(mock_app, mock_store) + + +class TestRestRegistryServerMCP(unittest.TestCase): + """Test MCP integration in RestRegistryServer.""" + + @patch("fastapi_mcp.FastApiMCP") + @patch("feast.api.registry.rest.rest_registry_server.RestRegistryServer._init_auth") + @patch( + "feast.api.registry.rest.rest_registry_server.RestRegistryServer._register_routes" + ) + def test_mcp_mounted_when_enabled( + self, mock_register, mock_auth, mock_fast_api_mcp + ): + """Test that MCP is mounted on RestRegistryServer when registry.mcp.enabled is True.""" + from feast.api.registry.rest.rest_registry_server import RestRegistryServer + + mock_store = Mock() + mock_store.config.registry.mcp = SimpleNamespace(enabled=True) + mock_store.config.auth_config.type = "no_auth" + mock_store.registry = Mock() + mock_store.project = "test_project" + + mock_mcp_instance = Mock() + mock_fast_api_mcp.return_value = mock_mcp_instance + + server = RestRegistryServer(mock_store) + + mock_fast_api_mcp.assert_called_once_with(server.app, name="feast-registry-mcp") + mock_mcp_instance.mount.assert_called_once() + + @patch("feast.api.registry.rest.rest_registry_server.RestRegistryServer._init_auth") + @patch( + "feast.api.registry.rest.rest_registry_server.RestRegistryServer._register_routes" + ) + def test_mcp_not_mounted_when_disabled(self, mock_register, mock_auth): + """Test that MCP is not mounted when registry.mcp.enabled is False.""" + from feast.api.registry.rest.rest_registry_server import RestRegistryServer + + mock_store = Mock() + mock_store.config.registry.mcp = SimpleNamespace(enabled=False) + mock_store.config.auth_config.type = "no_auth" + mock_store.registry = Mock() + mock_store.project = "test_project" + + with patch("fastapi_mcp.FastApiMCP") as mock_fast_api_mcp: + RestRegistryServer(mock_store) + mock_fast_api_mcp.assert_not_called() + + @patch("feast.api.registry.rest.rest_registry_server.RestRegistryServer._init_auth") + @patch( + "feast.api.registry.rest.rest_registry_server.RestRegistryServer._register_routes" + ) + def test_mcp_not_mounted_when_mcp_config_absent(self, mock_register, mock_auth): + """Test that MCP is not mounted when registry.mcp is None.""" + from feast.api.registry.rest.rest_registry_server import RestRegistryServer + + mock_store = Mock() + mock_store.config.registry.mcp = None + mock_store.config.auth_config.type = "no_auth" + mock_store.registry = Mock() + mock_store.project = "test_project" + + with patch("fastapi_mcp.FastApiMCP") as mock_fast_api_mcp: + RestRegistryServer(mock_store) + mock_fast_api_mcp.assert_not_called() diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/__init__.py b/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/test_mongodb.py b/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/test_mongodb.py new file mode 100644 index 00000000000..8fabcf7b28a --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/test_mongodb.py @@ -0,0 +1,1719 @@ +""" +Unit tests for MongoDB offline store (mongodb.py). + +Tests the single-collection schema with grouped aggregation. All feature +views share one collection (``feature_history``) discriminated by the +``feature_view`` field. + +Schema: + { + "entity_id": bytes, # serialized entity key + "feature_view": str, # discriminator + "features": {"feat1": val, ...}, + "event_timestamp": datetime, + "created_at": datetime + } + +Docker-dependent tests are marked with ``@_requires_docker`` and are skipped +when Docker is unavailable. +""" + +import os +import tempfile +from datetime import datetime, timedelta +from typing import Dict, Generator, Optional +from unittest.mock import MagicMock, patch + +import pandas as pd +import pyarrow +import pytest +import pytz + +pytest.importorskip("pymongo") + +from pymongo import MongoClient +from testcontainers.mongodb import MongoDbContainer + +from feast import Entity, FeatureView, Field +from feast.errors import SavedDatasetLocationAlreadyExists +from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb import ( + MongoDBOfflineStore, + MongoDBOfflineStoreConfig, + MongoDBSource, +) +from feast.infra.offline_stores.file_source import SavedDatasetFileStorage +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RepoConfig +from feast.types import Float64, Int32, Int64, String +from feast.value_type import ValueType + +# --------------------------------------------------------------------------- +# Docker availability check +# --------------------------------------------------------------------------- + +docker_available = False +try: + import docker + + try: + _docker_client = docker.from_env() + _docker_client.ping() + docker_available = True + except Exception: + pass +except ImportError: + pass + +_requires_docker = pytest.mark.skipif( + not docker_available, + reason="Docker is not available or not running.", +) + +ENTITY_KEY_VERSION = 3 + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_entity_id( + join_keys: dict, + value_types: Optional[Dict[str, ValueType]] = None, +) -> bytes: + """Serialize an entity key dict to bytes (matches offline_write_batch serialization).""" + entity_key = EntityKeyProto() + for key in sorted(join_keys.keys()): + entity_key.join_keys.append(key) + val = ValueProto() + value = join_keys[key] + declared_type = value_types.get(key) if value_types else None + if declared_type == ValueType.INT32: + val.int32_val = int(value) + elif declared_type == ValueType.INT64: + val.int64_val = int(value) + elif declared_type == ValueType.STRING: + val.string_val = str(value) + else: + if isinstance(value, bool): + val.bool_val = value + elif isinstance(value, int): + val.int64_val = value + elif isinstance(value, str): + val.string_val = value + else: + val.string_val = str(value) + entity_key.entity_values.append(val) + return serialize_entity_key(entity_key, ENTITY_KEY_VERSION) + + +# --------------------------------------------------------------------------- +# Fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture(scope="module") +def mongodb_container() -> Generator[MongoDbContainer, None, None]: + container = MongoDbContainer( + "mongo:latest", + username="test", + password="test", # pragma: allowlist secret + ).with_exposed_ports(27017) + container.start() + yield container + container.stop() + + +@pytest.fixture +def mongodb_connection_string(mongodb_container: MongoDbContainer) -> str: + exposed_port = mongodb_container.get_exposed_port(27017) + return f"mongodb://test:test@localhost:{exposed_port}" # pragma: allowlist secret + + +@pytest.fixture +def repo_config(mongodb_connection_string: str) -> RepoConfig: + return RepoConfig( + project="test_project", + registry="memory://", + provider="local", + offline_store=MongoDBOfflineStoreConfig( + connection_string=mongodb_connection_string, + database="feast_test", + collection="feature_history", + ), + online_store={"type": "sqlite"}, + entity_key_serialization_version=ENTITY_KEY_VERSION, + ) + + +@pytest.fixture +def sample_data(mongodb_connection_string: str) -> datetime: + """Insert sample data using the feature_history schema. + + 4 documents: driver 1 at 3 timestamps, driver 2 at 1 timestamp. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + collection.drop() + + now = datetime.now(tz=pytz.UTC) + + docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats", + "features": {"conv_rate": 0.5, "acc_rate": 0.9}, + "event_timestamp": now - timedelta(hours=2), + "created_at": now - timedelta(hours=2), + }, + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats", + "features": {"conv_rate": 0.6, "acc_rate": 0.85}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats", + "features": {"conv_rate": 0.7, "acc_rate": 0.8}, + "event_timestamp": now, + "created_at": now, + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats", + "features": {"conv_rate": 0.3, "acc_rate": 0.95}, + "event_timestamp": now - timedelta(hours=2), + "created_at": now - timedelta(hours=2), + }, + ] + collection.insert_many(docs) + client.close() + return now + + +@pytest.fixture +def driver_source() -> MongoDBSource: + return MongoDBSource( + name="driver_stats", + timestamp_field="event_timestamp", + created_timestamp_column="created_at", + ) + + +@pytest.fixture +def driver_fv(driver_source: MongoDBSource) -> FeatureView: + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + return FeatureView( + name="driver_stats", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + Field(name="acc_rate", dtype=Float64), + ], + source=driver_source, + ttl=timedelta(days=1), + ) + + +# --------------------------------------------------------------------------- +# Tests: pull_latest_from_table_or_query +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_pull_latest_from_table_or_query( + repo_config: RepoConfig, sample_data: datetime, driver_source: MongoDBSource +) -> None: + """pull_latest returns the most recent row per entity within the time window.""" + now = sample_data + job = MongoDBOfflineStore.pull_latest_from_table_or_query( + config=repo_config, + data_source=driver_source, + join_key_columns=["driver_id"], + feature_name_columns=["conv_rate", "acc_rate"], + timestamp_field="event_timestamp", + created_timestamp_column="created_at", + start_date=now - timedelta(days=1), + end_date=now + timedelta(hours=1), + ) + + df = job.to_df() + + assert isinstance(df, pd.DataFrame) + assert len(df) == 2 # Two unique entities + + # Join key columns must be present in the output. + assert "driver_id" in df.columns, ( + f"Expected 'driver_id' in output columns, got {list(df.columns)}" + ) + + conv_rates = sorted(df["conv_rate"].tolist()) + assert conv_rates[0] == pytest.approx(0.3) # Driver 2's only value + assert conv_rates[1] == pytest.approx(0.7) # Driver 1's latest + + +# --------------------------------------------------------------------------- +# Tests: get_historical_features (training path — repeated entity IDs) +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_get_historical_features_training_path( + repo_config: RepoConfig, sample_data: datetime, driver_fv: FeatureView +) -> None: + """Training path: repeated entity IDs at different timestamps → merge_asof PIT join.""" + now = sample_data + + entity_df = pd.DataFrame( + { + "driver_id": [1, 1, 2], + "event_timestamp": [ + now - timedelta(hours=1, minutes=30), # → conv_rate=0.5 (doc 2h ago) + now - timedelta(minutes=30), # → conv_rate=0.6 (doc 1h ago) + now - timedelta(hours=1), # → conv_rate=0.3 (only doc) + ], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df() + assert isinstance(result_df, pd.DataFrame) + assert len(result_df) == 3 + + result_df = result_df.sort_values(["driver_id", "event_timestamp"]).reset_index( + drop=True + ) + + # Driver 1, 1.5 hours ago → feature row from 2 hours ago + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.5) + # Driver 1, 30 min ago → feature row from 1 hour ago + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.6) + # Driver 2, 1 hour ago → only feature row (2 hours ago) + assert result_df.loc[2, "conv_rate"] == pytest.approx(0.3) + + +# --------------------------------------------------------------------------- +# Tests: training path created_at tiebreaker +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_training_path_created_at_tiebreaker( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """Training path must pick the highest created_at when event_timestamps tie. + + Two docs for the same entity with identical event_timestamp but different + created_at values. Without sorting fv_df on created_at, merge_asof would + pick whichever doc MongoDB returned first (undefined order). + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + collection.drop() + + now = datetime.now(tz=pytz.UTC) + t_feature = now - timedelta(hours=1) + created_early = now - timedelta(minutes=30) + created_late = now - timedelta(minutes=10) + + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + source = MongoDBSource(name="driver_stats_tiebreak") + fv = FeatureView( + name="driver_stats_tiebreak", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=source, + ttl=timedelta(days=1), + ) + + docs = [ + # Same entity, same event_timestamp, earlier created_at → stale + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_tiebreak", + "features": {"conv_rate": 0.1}, + "event_timestamp": t_feature, + "created_at": created_early, + }, + # Same entity, same event_timestamp, later created_at → should win + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_tiebreak", + "features": {"conv_rate": 0.9}, + "event_timestamp": t_feature, + "created_at": created_late, + }, + ] + collection.insert_many(docs) + client.close() + + # Repeated entity → forces training path (merge_asof) + entity_df = pd.DataFrame( + { + "driver_id": [1, 1], + "event_timestamp": [now, now], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[fv], + feature_refs=["driver_stats_tiebreak:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df() + assert len(result_df) == 2 + + # Both rows should get conv_rate=0.9 (the doc with later created_at) + for idx in range(len(result_df)): + assert result_df.loc[idx, "conv_rate"] == pytest.approx(0.9), ( + f"Row {idx}: expected 0.9 (latest created_at) but got " + f"{result_df.loc[idx, 'conv_rate']!r}. " + f"Training path may not be sorting by created_at." + ) + + +# --------------------------------------------------------------------------- +# Tests: get_historical_features (scoring path — unique entity IDs) +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_get_historical_features_scoring_path( + repo_config: RepoConfig, sample_data: datetime, driver_fv: FeatureView +) -> None: + """Scoring path: unique entity IDs → server-side $group dedup, vectorized join.""" + now = sample_data + + # Unique entity IDs → scoring path uses $group + entity_df = pd.DataFrame( + { + "driver_id": [1, 2], + "event_timestamp": [now, now], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + assert len(result_df) == 2 + + # Driver 1: latest value at or before now + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.7) + assert result_df.loc[0, "acc_rate"] == pytest.approx(0.8) + + # Driver 2: only value (2 hours ago) + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.3) + assert result_df.loc[1, "acc_rate"] == pytest.approx(0.95) + + +# --------------------------------------------------------------------------- +# Tests: pull_all_from_table_or_query +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_pull_all_from_table_or_query( + repo_config: RepoConfig, sample_data: datetime, driver_source: MongoDBSource +) -> None: + """pull_all returns all rows in the time window without deduplication.""" + now = sample_data + job = MongoDBOfflineStore.pull_all_from_table_or_query( + config=repo_config, + data_source=driver_source, + join_key_columns=["driver_id"], + feature_name_columns=["conv_rate", "acc_rate"], + timestamp_field="event_timestamp", + created_timestamp_column="created_at", + start_date=now - timedelta(hours=1, minutes=30), + end_date=now + timedelta(hours=1), + ) + + df = job.to_df() + assert isinstance(df, pd.DataFrame) + # 2 rows in window: driver 1 at 1h ago and driver 1 at now. + # Excludes: driver 1 at 2h ago (before start_date) and driver 2 at 2h ago. + assert len(df) == 2 + + # Join key columns must be present in the output. + assert "driver_id" in df.columns, ( + f"Expected 'driver_id' in output columns, got {list(df.columns)}" + ) + + +# --------------------------------------------------------------------------- +# Tests: TTL +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_ttl_excludes_stale_features( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """TTL causes stale feature values to be returned as NULL.""" + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + + ttl_docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_ttl", + "features": {"conv_rate": 0.9}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats_ttl", + "features": {"conv_rate": 0.5}, + "event_timestamp": now - timedelta(days=2), # Stale + "created_at": now - timedelta(days=2), + }, + ] + collection.insert_many(ttl_docs) + client.close() + + ttl_source = MongoDBSource( + name="driver_stats_ttl", + timestamp_field="event_timestamp", + ) + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + ttl_fv = FeatureView( + name="driver_stats_ttl", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=ttl_source, + ttl=timedelta(days=1), + ) + + entity_df = pd.DataFrame({"driver_id": [1, 2], "event_timestamp": [now, now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[ttl_fv], + feature_refs=["driver_stats_ttl:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + # Driver 1: fresh → has value + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.9) + + # Driver 2: stale (2 days ago, TTL=1 day) → NULL + assert pd.isna(result_df.loc[1, "conv_rate"]) + + +# --------------------------------------------------------------------------- +# Tests: K-collapse (multiple FVs, same join key signature) +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_k_collapse_multiple_feature_views( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """K=2 FVs sharing the same join key are resolved in a single aggregation group.""" + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + + docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_k", + "features": {"rating": 4.8}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats_k", + "features": {"rating": 4.5}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "vehicle_stats_k", + "features": {"vehicle_age": 2, "mileage": 50000}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "vehicle_stats_k", + "features": {"vehicle_age": 5, "mileage": 120000}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + ] + collection.insert_many(docs) + client.close() + + driver_source_k = MongoDBSource(name="driver_stats_k") + vehicle_source_k = MongoDBSource(name="vehicle_stats_k") + + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + + driver_fv_k = FeatureView( + name="driver_stats_k", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="rating", dtype=Float64), + ], + source=driver_source_k, + ttl=timedelta(days=1), + ) + + vehicle_fv_k = FeatureView( + name="vehicle_stats_k", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="vehicle_age", dtype=Int64), + Field(name="mileage", dtype=Int64), + ], + source=vehicle_source_k, + ttl=timedelta(days=1), + ) + + entity_df = pd.DataFrame({"driver_id": [1, 2], "event_timestamp": [now, now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv_k, vehicle_fv_k], + feature_refs=[ + "driver_stats_k:rating", + "vehicle_stats_k:vehicle_age", + "vehicle_stats_k:mileage", + ], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + assert len(result_df) == 2 + assert set(result_df.columns) >= {"driver_id", "rating", "vehicle_age", "mileage"} + + assert result_df.loc[0, "rating"] == pytest.approx(4.8) + assert result_df.loc[0, "vehicle_age"] == 2 + assert result_df.loc[0, "mileage"] == 50000 + + assert result_df.loc[1, "rating"] == pytest.approx(4.5) + assert result_df.loc[1, "vehicle_age"] == 5 + assert result_df.loc[1, "mileage"] == 120000 + + +# --------------------------------------------------------------------------- +# Tests: mixed join key cardinality (scoring_path per-FV) +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_mixed_join_key_cardinality( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """FVs with different join key sets must not lose data via $group. + + FV_A uses (user_id), FV_B uses (user_id, device_id). + entity_df has two rows: (user=1, device=X, t=09:00) and (user=1, device=Y, t=10:00). + Unique on (user_id, device_id), but user_id=1 appears twice. + + For FV_A, both rows map to the same entity_id. The old code would use + the scoring path ($group) globally, discarding older docs for user_id=1. + The fix detects that FV_A's entity_id is non-unique and falls back to + merge_asof for FV_A while FV_B can still use the scoring path. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + t_0800 = now - timedelta(hours=2) # 08:00 + t_0900 = now - timedelta(hours=1) # 09:00 + t_0930 = now - timedelta(minutes=30) # 09:30 + + user_entity = Entity( + name="user_id", join_keys=["user_id"], value_type=ValueType.INT64 + ) + device_entity = Entity( + name="device_id", join_keys=["device_id"], value_type=ValueType.STRING + ) + + # FV_A: keyed on user_id only + source_a = MongoDBSource(name="user_prefs") + fv_a = FeatureView( + name="user_prefs", + entities=[user_entity], + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="theme", dtype=String), + ], + source=source_a, + ttl=timedelta(days=1), + ) + + # FV_B: keyed on (user_id, device_id) + source_b = MongoDBSource(name="device_stats") + fv_b = FeatureView( + name="device_stats", + entities=[user_entity, device_entity], + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="device_id", dtype=String), + Field(name="battery", dtype=Float64), + ], + source=source_b, + ttl=timedelta(days=1), + ) + + # Insert docs for FV_A (user_id only key) + # Two docs for user 1: one at 08:00 ("dark") and one at 09:30 ("light") + docs = [ + { + "entity_id": _make_entity_id({"user_id": 1}), + "feature_view": "user_prefs", + "features": {"theme": "dark"}, + "event_timestamp": t_0800, + "created_at": t_0800, + }, + { + "entity_id": _make_entity_id({"user_id": 1}), + "feature_view": "user_prefs", + "features": {"theme": "light"}, + "event_timestamp": t_0930, + "created_at": t_0930, + }, + # FV_B: keyed on (user_id, device_id) + { + "entity_id": _make_entity_id({"device_id": "X", "user_id": 1}), + "feature_view": "device_stats", + "features": {"battery": 0.8}, + "event_timestamp": t_0800, + "created_at": t_0800, + }, + { + "entity_id": _make_entity_id({"device_id": "Y", "user_id": 1}), + "feature_view": "device_stats", + "features": {"battery": 0.6}, + "event_timestamp": t_0800, + "created_at": t_0800, + }, + ] + collection.insert_many(docs) + client.close() + + # entity_df: two rows, unique on (user_id, device_id) but NOT on user_id + entity_df = pd.DataFrame( + { + "user_id": [1, 1], + "device_id": ["X", "Y"], + "event_timestamp": [t_0900, now], # 09:00 and 10:00 + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[fv_a, fv_b], + feature_refs=["user_prefs:theme", "device_stats:battery"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + strict_pit=True, + ) + + result_df = job.to_df().sort_values("device_id").reset_index(drop=True) + + assert len(result_df) == 2 + + # Row 0: device=X, request at 09:00 + # FV_A (user_id=1): 09:30 doc is AFTER 09:00 (strict_pit), 08:00 doc is valid → "dark" + # FV_B (user=1, device=X): 08:00 doc is before 09:00 → battery=0.8 + assert result_df.loc[0, "theme"] == "dark", ( + f"Expected 'dark' for row at 09:00 but got {result_df.loc[0, 'theme']!r}. " + "The scoring path $group may have discarded the 08:00 doc." + ) + assert result_df.loc[0, "battery"] == pytest.approx(0.8) + + # Row 1: device=Y, request at 10:00 + # FV_A (user_id=1): 09:30 doc is before 10:00 → "light" + # FV_B (user=1, device=Y): 08:00 doc is before 10:00 → battery=0.6 + assert result_df.loc[1, "theme"] == "light" + assert result_df.loc[1, "battery"] == pytest.approx(0.6) + + +# --------------------------------------------------------------------------- +# Tests: heterogeneous timestamps prevent scoring path +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_heterogeneous_timestamps_fall_back_to_training_path( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """Unique entity IDs but different request timestamps must use training path. + + Entity A requests at 09:00, Entity B at 10:00. + Doc for A: 08:00 (valid) and 09:30 (future for A's request). + Doc for B: 09:00 (valid). + + If the scoring path were used, $group with $lte max_ts=10:00 would pick + the 09:30 doc for A. future_mask would null it, but the valid 08:00 doc + was already discarded. The training path (merge_asof) correctly returns + the 08:00 doc for A. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + t_0800 = now - timedelta(hours=2) + t_0900 = now - timedelta(hours=1) + t_0930 = now - timedelta(minutes=30) + + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + source = MongoDBSource(name="driver_stats_het") + fv = FeatureView( + name="driver_stats_het", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=source, + ttl=timedelta(days=1), + ) + + docs = [ + # Driver 1: valid doc at 08:00 + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_het", + "features": {"conv_rate": 0.5}, + "event_timestamp": t_0800, + "created_at": t_0800, + }, + # Driver 1: doc at 09:30 (future relative to driver 1's request at 09:00) + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_het", + "features": {"conv_rate": 0.9}, + "event_timestamp": t_0930, + "created_at": t_0930, + }, + # Driver 2: valid doc at 09:00 + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats_het", + "features": {"conv_rate": 0.7}, + "event_timestamp": t_0900, + "created_at": t_0900, + }, + ] + collection.insert_many(docs) + client.close() + + # Different request timestamps: driver 1 at 09:00, driver 2 at 10:00 + entity_df = pd.DataFrame( + { + "driver_id": [1, 2], + "event_timestamp": [t_0900, now], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[fv], + feature_refs=["driver_stats_het:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + strict_pit=True, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + assert len(result_df) == 2 + + # Driver 1: request at 09:00, 09:30 doc is future → must return 08:00 doc (0.5) + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.5), ( + f"Expected 0.5 for driver 1 (08:00 doc) but got " + f"{result_df.loc[0, 'conv_rate']!r}. The scoring path may have " + f"discarded the valid older doc via $group." + ) + + # Driver 2: request at 10:00, 09:00 doc is valid → 0.7 + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.7) + + +# --------------------------------------------------------------------------- +# Tests: overlapping feature names +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_overlapping_feature_names_full_feature_names( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """full_feature_names=True prevents collision when multiple FVs share a feature name.""" + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + + docs = [] + for fv_name, score_val in [ + ("fv_overlap_a", 1.0), + ("fv_overlap_b", 2.0), + ("fv_overlap_c", 3.0), + ]: + for driver_id in [1, 2]: + docs.append( + { + "entity_id": _make_entity_id({"driver_id": driver_id}), + "feature_view": fv_name, + "features": {"score": score_val + driver_id * 0.1}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + } + ) + collection.insert_many(docs) + client.close() + + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + fvs = [] + feature_refs = [] + for fv_name in ["fv_overlap_a", "fv_overlap_b", "fv_overlap_c"]: + source = MongoDBSource(name=fv_name) + fv = FeatureView( + name=fv_name, + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="score", dtype=Float64), + ], + source=source, + ttl=timedelta(days=1), + ) + fvs.append(fv) + feature_refs.append(f"{fv_name}:score") + + entity_df = pd.DataFrame({"driver_id": [1, 2], "event_timestamp": [now, now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=fvs, + feature_refs=feature_refs, + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=True, + ) + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + assert len(result_df) == 2 + assert "fv_overlap_a__score" in result_df.columns + assert "fv_overlap_b__score" in result_df.columns + assert "fv_overlap_c__score" in result_df.columns + + assert result_df.loc[0, "fv_overlap_a__score"] == pytest.approx(1.1) + assert result_df.loc[0, "fv_overlap_b__score"] == pytest.approx(2.1) + assert result_df.loc[0, "fv_overlap_c__score"] == pytest.approx(3.1) + assert result_df.loc[1, "fv_overlap_a__score"] == pytest.approx(1.2) + assert result_df.loc[1, "fv_overlap_b__score"] == pytest.approx(2.2) + assert result_df.loc[1, "fv_overlap_c__score"] == pytest.approx(3.2) + + +# --------------------------------------------------------------------------- +# Tests: compound join keys +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_compound_join_keys( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """Compound join keys (user_id + device_id) are serialized and matched correctly.""" + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + + now = datetime.now(tz=pytz.UTC) + + docs = [ + { + "entity_id": _make_entity_id({"user_id": 1, "device_id": "mobile"}), + "feature_view": "user_device_features", + "features": {"app_opens": 50}, + "event_timestamp": now - timedelta(hours=2), + "created_at": now - timedelta(hours=2), + }, + { + "entity_id": _make_entity_id({"user_id": 1, "device_id": "mobile"}), + "feature_view": "user_device_features", + "features": {"app_opens": 55}, # Latest + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"user_id": 1, "device_id": "desktop"}), + "feature_view": "user_device_features", + "features": {"app_opens": 10}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + { + "entity_id": _make_entity_id({"user_id": 2, "device_id": "tablet"}), + "feature_view": "user_device_features", + "features": {"app_opens": 25}, + "event_timestamp": now - timedelta(hours=1), + "created_at": now - timedelta(hours=1), + }, + ] + collection.insert_many(docs) + client.close() + + source = MongoDBSource(name="user_device_features") + user_entity = Entity( + name="user_id", join_keys=["user_id"], value_type=ValueType.INT64 + ) + device_entity = Entity( + name="device_id", join_keys=["device_id"], value_type=ValueType.STRING + ) + + fv = FeatureView( + name="user_device_features", + entities=[user_entity, device_entity], + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="device_id", dtype=String), + Field(name="app_opens", dtype=Int64), + ], + source=source, + ttl=timedelta(days=1), + ) + + # pull_latest: one row per unique (user_id, device_id) + job = MongoDBOfflineStore.pull_latest_from_table_or_query( + config=repo_config, + data_source=source, + join_key_columns=["user_id", "device_id"], + feature_name_columns=["app_opens"], + timestamp_field="event_timestamp", + created_timestamp_column="created_at", + start_date=now - timedelta(days=1), + end_date=now + timedelta(hours=1), + ) + + df = job.to_df() + assert len(df) == 3 + + app_opens_values = sorted(df["app_opens"].tolist()) + assert 10 in app_opens_values + assert 25 in app_opens_values + assert 55 in app_opens_values + + # get_historical_features with compound keys + entity_df = pd.DataFrame( + { + "user_id": [1, 1, 2], + "device_id": ["mobile", "desktop", "tablet"], + "event_timestamp": [now, now, now], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[fv], + feature_refs=["user_device_features:app_opens"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df() + assert len(result_df) == 3 + + result_df = result_df.sort_values(["user_id", "device_id"]).reset_index(drop=True) + + assert result_df.loc[0, "app_opens"] == 10 # user 1, desktop + assert result_df.loc[1, "app_opens"] == 55 # user 1, mobile (latest) + assert result_df.loc[2, "app_opens"] == 25 # user 2, tablet + + +# --------------------------------------------------------------------------- +# Tests: extra columns in entity_df +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_entity_df_with_extra_columns( + repo_config: RepoConfig, sample_data: datetime, driver_fv: FeatureView +) -> None: + """Label columns in entity_df must not corrupt entity key serialization.""" + now = sample_data + + entity_df = pd.DataFrame( + { + "driver_id": [1, 1, 2], + "event_timestamp": [ + now - timedelta(hours=1, minutes=30), + now - timedelta(minutes=30), + now - timedelta(hours=1), + ], + "trip_success": [1, 0, 1], # label — must not enter entity key + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df() + assert isinstance(result_df, pd.DataFrame) + assert len(result_df) == 3 + assert "trip_success" in result_df.columns + assert sorted(result_df["trip_success"].tolist()) == [0, 1, 1] + + assert result_df["conv_rate"].notna().all(), ( + "conv_rate is null — label column was likely included in entity key serialization." + ) + + result_df = result_df.sort_values(["driver_id", "event_timestamp"]).reset_index( + drop=True + ) + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.5) + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.6) + assert result_df.loc[2, "conv_rate"] == pytest.approx(0.3) + + +# --------------------------------------------------------------------------- +# Tests: INT32 entity key +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_int32_entity_key( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """INT32 entity keys use int32_val in the proto, not int64_val. + + offline_write_batch must serialize INT32 entities with int32_val so that + the bytes match what get_historical_features produces. + """ + driver_entity = Entity( + name="order_id", join_keys=["order_id"], value_type=ValueType.INT32 + ) + source = MongoDBSource(name="order_features") + fv = FeatureView( + name="order_features", + entities=[driver_entity], + schema=[ + Field(name="order_id", dtype=Int32), + Field(name="amount", dtype=Float64), + ], + source=source, + ttl=timedelta(days=1), + ) + + client: MongoClient = MongoClient(mongodb_connection_string) + client["feast_test"]["feature_history"].drop() + client.close() + + now = datetime.now(tz=pytz.UTC) + + # Write via offline_write_batch (uses mongodb.py's serializer) + df = pd.DataFrame( + { + "order_id": [1, 2], + "amount": [100.0, 200.0], + "event_timestamp": [now - timedelta(hours=1), now - timedelta(hours=1)], + "created_at": [now, now], + } + ) + table = pyarrow.Table.from_pandas(df) + + MongoDBOfflineStore.offline_write_batch( + config=repo_config, + feature_view=fv, + table=table, + progress=None, + ) + + entity_df = pd.DataFrame( + { + "order_id": [1, 2], + "event_timestamp": [now, now], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[fv], + feature_refs=["order_features:amount"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df().sort_values("order_id").reset_index(drop=True) + assert len(result_df) == 2 + assert result_df["amount"].notna().all(), ( + "amount is null — INT32 entity key serialization mismatch between " + "offline_write_batch and get_historical_features." + ) + assert result_df.loc[0, "amount"] == pytest.approx(100.0) + assert result_df.loc[1, "amount"] == pytest.approx(200.0) + + +# --------------------------------------------------------------------------- +# Tests: persist +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_persist_writes_parquet( + repo_config: RepoConfig, + sample_data: datetime, + driver_fv: FeatureView, +) -> None: + """persist() writes the joined result to a parquet file.""" + now = sample_data + + entity_df = pd.DataFrame( + { + "driver_id": [1, 2], + "event_timestamp": [now, now - timedelta(hours=2)], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + with tempfile.NamedTemporaryFile(suffix=".parquet", delete=False) as f: + path = f.name + + try: + os.unlink(path) # persist creates the file; it must not already exist + job.persist(SavedDatasetFileStorage(path=path)) + + assert os.path.exists(path) + result_df = pd.read_parquet(path) + assert len(result_df) == 2 + assert {"driver_id", "conv_rate", "acc_rate", "event_timestamp"}.issubset( + result_df.columns + ) + finally: + if os.path.exists(path): + os.unlink(path) + + +@_requires_docker +def test_persist_raises_if_file_exists( + repo_config: RepoConfig, + sample_data: datetime, + driver_fv: FeatureView, +) -> None: + """persist() raises SavedDatasetLocationAlreadyExists when the file already exists.""" + now = sample_data + + entity_df = pd.DataFrame({"driver_id": [1], "event_timestamp": [now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + with tempfile.NamedTemporaryFile(suffix=".parquet", delete=False) as f: + path = f.name + + try: + with pytest.raises(SavedDatasetLocationAlreadyExists): + job.persist(SavedDatasetFileStorage(path=path), allow_overwrite=False) + finally: + if os.path.exists(path): + os.unlink(path) + + +@_requires_docker +def test_persist_allow_overwrite( + repo_config: RepoConfig, + sample_data: datetime, + driver_fv: FeatureView, +) -> None: + """persist(allow_overwrite=True) replaces any existing file.""" + now = sample_data + + entity_df = pd.DataFrame({"driver_id": [1], "event_timestamp": [now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + with tempfile.NamedTemporaryFile(suffix=".parquet", delete=False) as f: + path = f.name + f.write(b"stale content") + + try: + job.persist(SavedDatasetFileStorage(path=path), allow_overwrite=True) + + result_df = pd.read_parquet(path) + assert len(result_df) == 1 + assert "driver_id" in result_df.columns + finally: + if os.path.exists(path): + os.unlink(path) + + +# --------------------------------------------------------------------------- +# Tests: offline_write_batch round-trip +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_offline_write_batch_round_trip( + repo_config: RepoConfig, + mongodb_connection_string: str, + driver_fv: FeatureView, +) -> None: + """offline_write_batch writes documents that get_historical_features reads back.""" + client: MongoClient = MongoClient(mongodb_connection_string) + client["feast_test"]["feature_history"].drop() + client.close() + + now = datetime.now(tz=pytz.UTC) + + df = pd.DataFrame( + { + "driver_id": [1, 2], + "conv_rate": [0.8, 0.6], + "acc_rate": [0.9, 0.7], + "event_timestamp": [now - timedelta(hours=1), now - timedelta(hours=1)], + "created_at": [now, now], + } + ) + table = pyarrow.Table.from_pandas(df) + + MongoDBOfflineStore.offline_write_batch( + config=repo_config, + feature_view=driver_fv, + table=table, + progress=None, + ) + + # Verify document structure + client = MongoClient(mongodb_connection_string) + docs = list( + client["feast_test"]["feature_history"].find( + {"feature_view": "driver_stats"}, {"_id": 0} + ) + ) + client.close() + + assert len(docs) == 2 + doc = docs[0] + assert isinstance(doc["entity_id"], bytes), "entity_id must be serialized bytes" + assert doc["feature_view"] == "driver_stats" + assert set(doc["features"].keys()) == {"conv_rate", "acc_rate"} + assert "event_timestamp" in doc + assert "created_at" in doc + + # Round-trip: read back via get_historical_features + entity_df = pd.DataFrame({"driver_id": [1, 2], "event_timestamp": [now, now]}) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[driver_fv], + feature_refs=["driver_stats:conv_rate", "driver_stats:acc_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + assert len(result_df) == 2 + assert result_df["conv_rate"].notna().all(), ( + "conv_rate is null — offline_write_batch and get_historical_features " + "produced different entity_id bytes." + ) + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.8) + assert result_df.loc[0, "acc_rate"] == pytest.approx(0.9) + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.6) + assert result_df.loc[1, "acc_rate"] == pytest.approx(0.7) + + +# --------------------------------------------------------------------------- +# Tests: max_ts overshoot (strict_pit semantics) +# --------------------------------------------------------------------------- + + +@_requires_docker +def test_scoring_path_nulls_future_doc( + repo_config: RepoConfig, mongodb_connection_string: str, driver_fv: FeatureView +) -> None: + """strict_pit=True: a doc whose timestamp is after the entity request time → NULL. + + Scenario: + Entity A requests features at 09:00. + The only available document is at 10:30 (after the request time). + With strict_pit=True the scoring path must return NULL for entity A. + + This exercises the ``future_mask`` in the scoring path. The aggregation + uses ``max_ts`` as the server-side upper bound, so the 10:30 doc IS + fetched from MongoDB. The Python-side ``future_mask`` is what nulls it. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + collection.drop() + + base = datetime.now(tz=pytz.UTC).replace(microsecond=0) + request_a = base.replace(hour=9, minute=0, second=0) + request_b = base.replace(hour=11, minute=0, second=0) + doc_ts_a = base.replace(hour=10, minute=30, second=0) # after A's request time + doc_ts_b = base.replace(hour=10, minute=0, second=0) # before B's request time + + # Replace with fixed dates to avoid day-boundary issues + from datetime import timezone + + now = datetime.now(tz=timezone.utc) + request_a = now - timedelta(hours=3) # 3 hours ago + request_b = now # now + doc_ts_a = now - timedelta( + hours=1 + ) # 1 hour ago — AFTER request_a, BEFORE request_b + doc_ts_b = now - timedelta(hours=2) # 2 hours ago — before both requests + + docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_pit", + "features": {"conv_rate": 0.9}, + "event_timestamp": doc_ts_a, + "created_at": doc_ts_a, + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats_pit", + "features": {"conv_rate": 0.5}, + "event_timestamp": doc_ts_b, + "created_at": doc_ts_b, + }, + ] + collection.insert_many(docs) + client.close() + + pit_source = MongoDBSource( + name="driver_stats_pit", timestamp_field="event_timestamp" + ) + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + pit_fv = FeatureView( + name="driver_stats_pit", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=pit_source, + ttl=timedelta(days=7), + ) + + # Unique entity IDs → scoring path + entity_df = pd.DataFrame( + { + "driver_id": [1, 2], + "event_timestamp": [request_a, request_b], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[pit_fv], + feature_refs=["driver_stats_pit:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + strict_pit=True, + ) + + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + assert len(result_df) == 2 + + # Driver 1: only doc is at doc_ts_a which is AFTER request_a → NULL + assert pd.isna(result_df.loc[0, "conv_rate"]), ( + f"Expected NULL for driver 1 (doc at {doc_ts_a} is after request at " + f"{request_a}), got {result_df.loc[0, 'conv_rate']!r}" + ) + + # Driver 2: doc is at doc_ts_b which is BEFORE request_b → value returned + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.5) + + +@_requires_docker +def test_scoring_path_nulls_future_doc_chunk_size_1( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """Same as test_scoring_path_nulls_future_doc but with CHUNK_SIZE=1. + + With CHUNK_SIZE=1 each entity is processed in its own chunk. Per-chunk + ``max_ts`` equals that entity's own request timestamp, so the 10:30 doc + for entity A is never even fetched from MongoDB (server-side filter). + Either way, the result for entity A must be NULL and entity B must have + a value. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + collection.drop() + + from datetime import timezone + + now = datetime.now(tz=timezone.utc) + request_a = now - timedelta(hours=3) + request_b = now + doc_ts_a = now - timedelta(hours=1) # after request_a + doc_ts_b = now - timedelta(hours=2) # before both + + docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_pit2", + "features": {"conv_rate": 0.9}, + "event_timestamp": doc_ts_a, + "created_at": doc_ts_a, + }, + { + "entity_id": _make_entity_id({"driver_id": 2}), + "feature_view": "driver_stats_pit2", + "features": {"conv_rate": 0.5}, + "event_timestamp": doc_ts_b, + "created_at": doc_ts_b, + }, + ] + collection.insert_many(docs) + client.close() + + pit_source = MongoDBSource( + name="driver_stats_pit2", timestamp_field="event_timestamp" + ) + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + pit_fv = FeatureView( + name="driver_stats_pit2", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=pit_source, + ttl=timedelta(days=7), + ) + + entity_df = pd.DataFrame( + { + "driver_id": [1, 2], + "event_timestamp": [request_a, request_b], + } + ) + + mongodb_module = "feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb" + + # Force CHUNK_SIZE=1 so each entity is in its own chunk + with patch(f"{mongodb_module}._CHUNK_SIZE", 1): + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[pit_fv], + feature_refs=["driver_stats_pit2:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + strict_pit=True, + ) + result_df = job.to_df().sort_values("driver_id").reset_index(drop=True) + + assert len(result_df) == 2 + + # Driver 1: doc at doc_ts_a (after request_a) → NULL regardless of chunk boundary + assert pd.isna(result_df.loc[0, "conv_rate"]), ( + f"Expected NULL for driver 1 with CHUNK_SIZE=1, got " + f"{result_df.loc[0, 'conv_rate']!r}" + ) + + # Driver 2: doc at doc_ts_b (before request_b) → value returned + assert result_df.loc[1, "conv_rate"] == pytest.approx(0.5) + + +@_requires_docker +def test_strict_pit_false_returns_future_doc( + repo_config: RepoConfig, mongodb_connection_string: str +) -> None: + """strict_pit=False: future doc IS returned (real-time inference mode). + + Same scenario as test_scoring_path_nulls_future_doc: + Entity A requests at 3 hours ago; only doc is at 1 hour ago (future). + + With strict_pit=False the future_mask is suppressed and the most recent + document is returned regardless of whether it post-dates the request time. + This is correct for real-time scoring where you always want the latest + observation. + """ + client: MongoClient = MongoClient(mongodb_connection_string) + db = client["feast_test"] + collection = db["feature_history"] + collection.drop() + + from datetime import timezone + + now = datetime.now(tz=timezone.utc) + request_a = now - timedelta(hours=3) + doc_ts_a = now - timedelta(hours=1) # AFTER request_a + + docs = [ + { + "entity_id": _make_entity_id({"driver_id": 1}), + "feature_view": "driver_stats_pit3", + "features": {"conv_rate": 0.9}, + "event_timestamp": doc_ts_a, + "created_at": doc_ts_a, + }, + ] + collection.insert_many(docs) + client.close() + + pit_source = MongoDBSource( + name="driver_stats_pit3", timestamp_field="event_timestamp" + ) + driver_entity = Entity( + name="driver_id", join_keys=["driver_id"], value_type=ValueType.INT64 + ) + pit_fv = FeatureView( + name="driver_stats_pit3", + entities=[driver_entity], + schema=[ + Field(name="driver_id", dtype=Int64), + Field(name="conv_rate", dtype=Float64), + ], + source=pit_source, + ttl=timedelta(days=7), + ) + + entity_df = pd.DataFrame( + { + "driver_id": [1], + "event_timestamp": [request_a], + } + ) + + job = MongoDBOfflineStore.get_historical_features( + config=repo_config, + feature_views=[pit_fv], + feature_refs=["driver_stats_pit3:conv_rate"], + entity_df=entity_df, + registry=MagicMock(), + project=repo_config.project, + full_feature_names=False, + strict_pit=False, # Accept future doc + ) + + result_df = job.to_df().reset_index(drop=True) + assert len(result_df) == 1 + + # With strict_pit=False the doc at doc_ts_a (after request_a) IS returned + assert result_df.loc[0, "conv_rate"] == pytest.approx(0.9), ( + f"Expected conv_rate=0.9 with strict_pit=False but got " + f"{result_df.loc[0, 'conv_rate']!r}. The future_mask may not be " + f"correctly suppressed." + ) diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/postgres_offline_store/test_postgres.py b/sdk/python/tests/unit/infra/offline_stores/contrib/postgres_offline_store/test_postgres.py index fad837e4c16..3eb01a0e6d0 100644 --- a/sdk/python/tests/unit/infra/offline_stores/contrib/postgres_offline_store/test_postgres.py +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/postgres_offline_store/test_postgres.py @@ -615,6 +615,71 @@ def test_non_entity_mode_with_both_dates(self): assert "start_date" not in str(e) assert "end_date" not in str(e) + def test_non_entity_entity_df_uses_end_date(self): + """Test that the synthetic entity_df uses end_date, not start_date. + + Regression test: the old code used pd.date_range(start=start_date, ...)[:1] + which put start_date in the entity_df. Since PIT joins use + MAX(entity_timestamp) as the upper bound, start_date made end_date + unreachable. The fix uses [end_date] directly. + """ + test_repo_config = RepoConfig( + project="test_project", + registry="test_registry", + provider="local", + offline_store=_mock_offline_store_config(), + ) + + feature_view = _mock_feature_view("test_fv", ttl=timedelta(days=1)) + start_date = datetime(2023, 1, 1, tzinfo=timezone.utc) + end_date = datetime(2023, 1, 7, tzinfo=timezone.utc) + + mock_get_entity_schema = MagicMock( + return_value={"event_timestamp": "timestamp"} + ) + + with ( + patch.multiple( + "feast.infra.offline_stores.contrib.postgres_offline_store.postgres", + _get_conn=MagicMock(), + _upload_entity_df=MagicMock(), + _get_entity_schema=mock_get_entity_schema, + _get_entity_df_event_timestamp_range=MagicMock( + return_value=(start_date, end_date) + ), + ), + patch( + "feast.infra.offline_stores.contrib.postgres_offline_store.postgres.offline_utils.get_expected_join_keys", + return_value=[], + ), + patch( + "feast.infra.offline_stores.contrib.postgres_offline_store.postgres.offline_utils.assert_expected_columns_in_entity_df", + ), + patch( + "feast.infra.offline_stores.contrib.postgres_offline_store.postgres.offline_utils.get_feature_view_query_context", + return_value=[], + ), + ): + PostgreSQLOfflineStore.get_historical_features( + config=test_repo_config, + feature_views=[feature_view], + feature_refs=["test_fv:feature1"], + entity_df=None, + registry=MagicMock(), + project="test_project", + start_date=start_date, + end_date=end_date, + ) + + # _get_entity_schema is called with the synthetic entity_df + df = mock_get_entity_schema.call_args[0][0] + assert len(df) == 1 + ts = df["event_timestamp"].iloc[0] + # The entity_df must use end_date, not start_date + assert ts == end_date, ( + f"entity_df timestamp should be end_date ({end_date}), got {ts}" + ) + def test_non_entity_mode_with_end_date_only(self): """Test non-entity retrieval calculates start_date from TTL""" test_repo_config = RepoConfig( @@ -888,7 +953,10 @@ def test_cli_date_combinations(self): from pathlib import Path from textwrap import dedent - from tests.utils.cli_repo_creator import CliRunner, get_example_repo + from click.testing import CliRunner + + from feast.cli.cli import cli + from feast.feature_store import FeatureStore runner = CliRunner() @@ -910,46 +978,76 @@ def test_cli_date_combinations(self): """) ) - repo_example = repo_path / "example.py" - repo_example.write_text(get_example_repo("example_feature_repo_1.py")) - - result = runner.run(["apply"], cwd=repo_path) - assert result.returncode == 0 - - # Test 1: Both dates provided - should parse correctly - result = runner.run( - [ - "get-historical-features", - "--features", - "driver_hourly_stats:conv_rate", - "--start-date", - "2023-01-01 00:00:00", - "--end-date", - "2023-01-07 00:00:00", - ], - cwd=repo_path, - ) + retrieval_job = MagicMock() + retrieval_job.to_df.return_value = pd.DataFrame() + + with patch.object( + FeatureStore, "get_historical_features", return_value=retrieval_job + ) as mock_get_historical_features: + # Test 1: Both dates provided - should parse correctly + result = runner.invoke( + cli, + [ + "--chdir", + str(repo_path), + "get-historical-features", + "--features", + "driver_hourly_stats:conv_rate", + "--start-date", + "2023-01-01 00:00:00", + "--end-date", + "2023-01-07 00:00:00", + ], + ) - # Should not fail on date parsing - stderr_output = result.stderr.decode() - assert "Error parsing" not in stderr_output - assert "time data" not in stderr_output # datetime parsing errors - - # Test 2: Only end date provided - should work (start_date calculated from TTL) - result = runner.run( - [ - "get-historical-features", - "--features", - "driver_hourly_stats:conv_rate", - "--end-date", - "2023-01-07 00:00:00", - ], - cwd=repo_path, - ) + assert result.exit_code == 0, result.output + assert mock_get_historical_features.call_args.kwargs[ + "start_date" + ] == datetime(2023, 1, 1) + assert mock_get_historical_features.call_args.kwargs[ + "end_date" + ] == datetime(2023, 1, 7) + + # Test 2: Only end date provided - should work (start_date calculated from TTL) + result = runner.invoke( + cli, + [ + "--chdir", + str(repo_path), + "get-historical-features", + "--features", + "driver_hourly_stats:conv_rate", + "--end-date", + "2023-01-07 00:00:00", + ], + ) - # Should not fail on parameter validation - stderr_output = result.stderr.decode() - assert "must be provided" not in stderr_output + assert result.exit_code == 0, result.output + assert ( + mock_get_historical_features.call_args.kwargs["start_date"] is None + ) + assert mock_get_historical_features.call_args.kwargs[ + "end_date" + ] == datetime(2023, 1, 7) + + # Test 3: No date or dataframe provided - should fail validation before retrieval. + result = runner.invoke( + cli, + [ + "--chdir", + str(repo_path), + "get-historical-features", + "--features", + "driver_hourly_stats:conv_rate", + ], + ) + + assert result.exit_code == 0, result.output + assert ( + "Either --dataframe or --start-date and/or --end-date must be provided." + in result.output + ) + assert mock_get_historical_features.call_count == 2 class TestPostgreSQLSourceQueryStringAlias: diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_bfv_compute_on_read.py b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_bfv_compute_on_read.py new file mode 100644 index 00000000000..130583a13b1 --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_bfv_compute_on_read.py @@ -0,0 +1,223 @@ +""" +Unit tests for BFV compute-on-read in SparkOfflineStore.get_historical_features(). + +Verifies that BatchFeatureViews with a UDF have their transformation applied +during get_historical_features(), with the transformed DataFrame registered as +a temp view that replaces the raw table_subquery in the PIT join. +""" + +from dataclasses import replace +from unittest.mock import MagicMock + +import pytest + +from feast.batch_feature_view import BatchFeatureView +from feast.feature_view import FeatureView +from feast.infra.offline_stores import offline_utils +from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _apply_bfv_transformations, +) +from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import ( + SparkSource, +) +from feast.transformation.base import Transformation + + +@pytest.fixture() +def spark_session(): + mock = MagicMock() + mock.sql.return_value = MagicMock(name="source_df") + return mock + + +@pytest.fixture() +def spark_source(): + source = MagicMock(spec=SparkSource) + source.get_table_query_string.return_value = "`raw_events`" + return source + + +@pytest.fixture() +def base_query_context(): + return offline_utils.FeatureViewQueryContext( + name="my_bfv", + ttl=3600, + entities=["user_id"], + features=["avg_rating"], + field_mapping={}, + timestamp_field="event_timestamp", + created_timestamp_column=None, + table_subquery="`raw_events`", + entity_selections=["user_id AS user_id"], + min_event_timestamp="2023-01-01T00:00:00", + max_event_timestamp="2024-01-01T00:00:00", + date_partition_column=None, + timestamp_field_type=None, + ) + + +def _make_bfv(name: str, spark_source, has_udf: bool = True): + """Create a mock BatchFeatureView with optional UDF.""" + fv = MagicMock(spec=BatchFeatureView) + fv.name = name + fv.projection = MagicMock() + fv.projection.name_to_use.return_value = name + fv.batch_source = spark_source + fv.source_views = [] + + if has_udf: + transformation = MagicMock(spec=Transformation) + transformed_df = MagicMock(name="transformed_df") + transformation.udf = MagicMock(return_value=transformed_df) + fv.feature_transformation = transformation + fv.udf = transformation.udf + else: + fv.feature_transformation = None + fv.udf = None + + return fv + + +def _make_plain_fv(name: str, spark_source): + """Create a mock plain FeatureView (not a BatchFeatureView).""" + fv = MagicMock(spec=FeatureView) + fv.name = name + fv.projection = MagicMock() + fv.projection.name_to_use.return_value = name + fv.batch_source = spark_source + fv.feature_transformation = None + fv.udf = None + return fv + + +class TestApplyBfvTransformations: + def test_bfv_with_udf_replaces_table_subquery( + self, spark_session, spark_source, base_query_context + ): + """BFV with a UDF should have its table_subquery replaced with a temp view.""" + bfv = _make_bfv("my_bfv", spark_source) + contexts = [base_query_context] + + result = _apply_bfv_transformations(spark_session, [bfv], contexts) + + assert len(result) == 1 + assert result[0].table_subquery != "`raw_events`" + assert result[0].table_subquery.startswith("feast_bfv_") + + def test_bfv_udf_is_invoked_with_source_df( + self, spark_session, spark_source, base_query_context + ): + """The UDF should be called with the DataFrame read from the raw source.""" + bfv = _make_bfv("my_bfv", spark_source) + contexts = [base_query_context] + + _apply_bfv_transformations(spark_session, [bfv], contexts) + + sql_arg = spark_session.sql.call_args[0][0] + assert "SELECT * FROM `raw_events`" in sql_arg + assert "WHERE" in sql_arg + source_df = spark_session.sql.return_value + bfv.feature_transformation.udf.assert_called_once_with(source_df) + + def test_transformed_df_registered_as_temp_view( + self, spark_session, spark_source, base_query_context + ): + """The transformed DataFrame should be registered as a temp view.""" + bfv = _make_bfv("my_bfv", spark_source) + transformed_df = bfv.feature_transformation.udf.return_value + contexts = [base_query_context] + + result = _apply_bfv_transformations(spark_session, [bfv], contexts) + + transformed_df.createOrReplaceTempView.assert_called_once() + view_name = transformed_df.createOrReplaceTempView.call_args[0][0] + assert view_name == result[0].table_subquery + + def test_plain_feature_view_unchanged( + self, spark_session, spark_source, base_query_context + ): + """Plain FeatureViews (not BFV) should pass through without modification.""" + fv = _make_plain_fv("my_bfv", spark_source) + contexts = [base_query_context] + + result = _apply_bfv_transformations(spark_session, [fv], contexts) + + assert result[0].table_subquery == "`raw_events`" + spark_session.sql.assert_not_called() + + def test_bfv_without_udf_unchanged( + self, spark_session, spark_source, base_query_context + ): + """BFV without a UDF should pass through without modification.""" + bfv = _make_bfv("my_bfv", spark_source, has_udf=False) + contexts = [base_query_context] + + result = _apply_bfv_transformations(spark_session, [bfv], contexts) + + assert result[0].table_subquery == "`raw_events`" + spark_session.sql.assert_not_called() + + def test_mixed_views_only_transforms_bfvs( + self, spark_session, spark_source, base_query_context + ): + """With mixed BFV and plain FVs, only BFVs with UDFs get transformed.""" + bfv = _make_bfv("my_bfv", spark_source) + plain_fv = _make_plain_fv("plain_fv", spark_source) + + ctx_bfv = base_query_context + ctx_plain = replace( + base_query_context, + name="plain_fv", + features=["some_feature"], + ) + + result = _apply_bfv_transformations( + spark_session, [bfv, plain_fv], [ctx_bfv, ctx_plain] + ) + + assert result[0].table_subquery.startswith("feast_bfv_") + assert result[1].table_subquery == "`raw_events`" + + def test_time_range_filter_applied( + self, spark_session, spark_source, base_query_context + ): + """Source query should include time bounds from the context.""" + bfv = _make_bfv("my_bfv", spark_source) + contexts = [base_query_context] + + _apply_bfv_transformations(spark_session, [bfv], contexts) + + sql_arg = spark_session.sql.call_args[0][0] + assert "2023-01-01" in sql_arg + assert "2024-01-01" in sql_arg + assert "event_timestamp" in sql_arg + + def test_time_range_filter_with_none_min_timestamp( + self, spark_session, spark_source, base_query_context + ): + """When min_event_timestamp is None (no TTL), query should still work.""" + bfv = _make_bfv("my_bfv", spark_source) + ctx = replace(base_query_context, min_event_timestamp=None) + + result = _apply_bfv_transformations(spark_session, [bfv], [ctx]) + + assert result[0].table_subquery.startswith("feast_bfv_") + sql_arg = spark_session.sql.call_args[0][0] + assert "2024-01-01" in sql_arg + + def test_other_context_fields_preserved( + self, spark_session, spark_source, base_query_context + ): + """All fields besides table_subquery should remain unchanged.""" + bfv = _make_bfv("my_bfv", spark_source) + contexts = [base_query_context] + + result = _apply_bfv_transformations(spark_session, [bfv], contexts) + + assert result[0].name == base_query_context.name + assert result[0].ttl == base_query_context.ttl + assert result[0].entities == base_query_context.entities + assert result[0].features == base_query_context.features + assert result[0].timestamp_field == base_query_context.timestamp_field + assert result[0].min_event_timestamp == base_query_context.min_event_timestamp + assert result[0].max_event_timestamp == base_query_context.max_event_timestamp diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_offline_store_pull_all.py b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_offline_store_pull_all.py new file mode 100644 index 00000000000..c29b89db001 --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_offline_store_pull_all.py @@ -0,0 +1,172 @@ +""" +Unit tests for SparkOfflineStore.pull_all_from_table_or_query SQL generation. + +Covers the bug where feature_name_columns=[] (signalling "read all source +columns" for BatchFeatureView UDF transformations) caused a bare + SELECT user_id, event_timestamp FROM source +instead of SELECT *, silently dropping all columns the UDF needs. +""" + +from datetime import datetime, timezone +from unittest.mock import MagicMock, patch + +import pytest + +from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( # noqa: E402 + SparkOfflineStore, + SparkOfflineStoreConfig, +) +from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import ( # noqa: E402 + SparkSource, +) +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig # noqa: E402 +from feast.repo_config import RepoConfig # noqa: E402 + +# --------------------------------------------------------------------------- +# Shared fixtures +# --------------------------------------------------------------------------- + +START = datetime(2023, 1, 1, tzinfo=timezone.utc) +END = datetime(2024, 1, 1, tzinfo=timezone.utc) + +# Fixed table name returned by the mocked get_table_query_string +_TABLE_EXPR = "`raw_reviews`" + + +@pytest.fixture() +def repo_config(): + return RepoConfig( + registry="file:///tmp/registry.db", + project="test", + provider="local", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=SparkOfflineStoreConfig(type="spark"), + ) + + +@pytest.fixture() +def spark_source(): + return SparkSource( + name="raw_reviews", + path="s3a://bucket/processed/reviews/", + file_format="parquet", + timestamp_field="event_timestamp", + ) + + +def _run_pull_all(repo_config, spark_source, feature_name_columns): + """ + Call pull_all_from_table_or_query with a mocked SparkSession and mocked + data-source table resolution, then return the SQL query string. + + Two things are patched so no real Spark/S3 access occurs: + 1. get_spark_session_or_start_new_with_repoconfig → MagicMock session + 2. spark_source.get_table_query_string → fixed table expression + (avoids SparkSource.validate / _load_dataframe_from_path hitting S3) + """ + mock_spark = MagicMock() + + with ( + patch( + "feast.infra.offline_stores.contrib.spark_offline_store.spark" + ".get_spark_session_or_start_new_with_repoconfig", + return_value=mock_spark, + ), + patch.object( + spark_source, + "get_table_query_string", + return_value=_TABLE_EXPR, + ), + ): + job = SparkOfflineStore.pull_all_from_table_or_query( + config=repo_config, + data_source=spark_source, + join_key_columns=["user_id"], + feature_name_columns=feature_name_columns, + timestamp_field="event_timestamp", + created_timestamp_column=None, + start_date=START, + end_date=END, + ) + + return job.query.strip() + + +def test_pull_all_with_empty_feature_cols_generates_select_star( + repo_config, spark_source +): + """ + feature_name_columns=[] must produce SELECT * so UDF-based + BatchFeatureViews receive all raw source columns for aggregation. + """ + sql = _run_pull_all(repo_config, spark_source, feature_name_columns=[]) + + assert sql.startswith("SELECT *"), ( + "Expected 'SELECT *' when feature_name_columns=[], " + f"got: {sql[:120]!r}\n\n" + "BatchFeatureView UDFs need all raw source columns to compute " + "aggregations — projecting only join key + timestamp silently " + "drops rating, text, helpful_vote, etc." + ) + assert "user_id" not in sql.split("FROM")[0], ( + "SELECT * must not also explicitly list join key columns" + ) + + +def test_pull_all_with_feature_cols_generates_explicit_projection( + repo_config, spark_source +): + """ + When feature_name_columns is non-empty (normal FeatureView path), + the query must project only the requested columns — not SELECT *. + """ + sql = _run_pull_all( + repo_config, + spark_source, + feature_name_columns=["avg_rating", "review_count"], + ) + + assert "SELECT *" not in sql, ( + "Non-empty feature_name_columns must produce explicit SELECT projection, not SELECT *" + ) + assert "avg_rating" in sql + assert "review_count" in sql + assert "user_id" in sql + assert "event_timestamp" in sql + + +def test_pull_all_empty_feature_cols_upstream_regression(repo_config, spark_source): + """ + Regression guard: the upstream (unfixed) behaviour with feature_name_columns=[] + produced a query that only selected join key + timestamp, dropping all columns + the UDF needs. Verify the fixed code does NOT produce that broken query. + + Broken upstream SQL looked like: + SELECT user_id, event_timestamp FROM ... WHERE ... + """ + sql = _run_pull_all(repo_config, spark_source, feature_name_columns=[]) + + projection = sql.split("FROM")[0] + assert "user_id" not in projection, ( + "Upstream bug: query projected only 'user_id, event_timestamp', " + "silently dropping all columns needed by the BFV UDF. " + "Fixed query should use SELECT *." + ) + + +@pytest.mark.parametrize( + "feature_cols,expect_star", + [ + ([], True), + (["f1"], False), + (["f1", "f2", "f3"], False), + ], +) +def test_pull_all_select_star_only_when_feature_cols_empty( + repo_config, spark_source, feature_cols, expect_star +): + sql = _run_pull_all(repo_config, spark_source, feature_name_columns=feature_cols) + has_star = sql.strip().upper().startswith("SELECT *") + assert has_star == expect_star, ( + f"feature_cols={feature_cols!r}: expected SELECT *={expect_star}, got SQL: {sql[:100]!r}" + ) diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_persist.py b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_persist.py new file mode 100644 index 00000000000..adcb54a1cf7 --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_persist.py @@ -0,0 +1,260 @@ +""" +Unit tests for SparkRetrievalJob.persist() and SavedDatasetSparkStorage.from_data_source(). + +Covers the fix for https://github.com/feast-dev/feast/issues/6261 where: +1. SavedDatasetStorage.from_data_source() did not support SparkSource +2. SavedDatasetSparkStorage lacked a from_data_source() method +3. SparkRetrievalJob.persist() only supported table-based storage, not path-based +""" + +from unittest.mock import MagicMock + +import pytest + +from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + SparkOfflineStoreConfig, + SparkRetrievalJob, +) +from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import ( + SavedDatasetSparkStorage, + SparkSource, +) +from feast.infra.offline_stores.file_source import FileSource +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.repo_config import RepoConfig +from feast.saved_dataset import SavedDatasetStorage +from feast.table_format import IcebergFormat + +# --------------------------------------------------------------------------- +# Shared fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture() +def repo_config(): + return RepoConfig( + registry="file:///tmp/registry.db", + project="test", + provider="local", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=SparkOfflineStoreConfig(type="spark"), + ) + + +@pytest.fixture() +def table_spark_source(): + return SparkSource( + name="my_table", + table="db.my_table", + timestamp_field="event_timestamp", + ) + + +@pytest.fixture() +def path_spark_source(): + return SparkSource( + name="my_path_source", + path="s3a://bucket/data/features/", + file_format="parquet", + timestamp_field="event_timestamp", + ) + + +def _make_spark_retrieval_job(repo_config, remote_warehouse=True): + """Build a SparkRetrievalJob with a mocked SparkSession.""" + mock_spark = MagicMock() + + if remote_warehouse: + mock_spark.conf.get.side_effect = lambda key: { + "hive.metastore.uris": "thrift://metastore:9083", + }.get(key, None) + else: + + def _local_conf_get(key): + if key == "hive.metastore.uris": + raise Exception("not set") + if key == "spark.sql.warehouse.dir": + return "file:///tmp/spark-warehouse" + return None + + mock_spark.conf.get.side_effect = _local_conf_get + + return SparkRetrievalJob( + spark_session=mock_spark, + query="SELECT 1", + full_feature_names=False, + config=repo_config, + ) + + +# --------------------------------------------------------------------------- +# Group 1: SavedDatasetSparkStorage.from_data_source() +# --------------------------------------------------------------------------- + + +class TestSavedDatasetSparkStorageFromDataSource: + def test_from_data_source_with_table_source(self, table_spark_source): + storage = SavedDatasetSparkStorage.from_data_source(table_spark_source) + + assert isinstance(storage, SavedDatasetSparkStorage) + assert storage.spark_options.table == "db.my_table" + assert storage.spark_options.query is None + assert storage.spark_options.path is None + + def test_from_data_source_with_path_source(self, path_spark_source): + storage = SavedDatasetSparkStorage.from_data_source(path_spark_source) + + assert isinstance(storage, SavedDatasetSparkStorage) + assert storage.spark_options.path == "s3a://bucket/data/features/" + assert storage.spark_options.file_format == "parquet" + assert storage.spark_options.table is None + assert storage.spark_options.query is None + + def test_from_data_source_rejects_non_spark_source(self): + file_source = FileSource( + path="/tmp/data.parquet", + timestamp_field="event_timestamp", + ) + with pytest.raises(AssertionError): + SavedDatasetSparkStorage.from_data_source(file_source) + + +# --------------------------------------------------------------------------- +# Group 2: SavedDatasetStorage.from_data_source() dispatch +# --------------------------------------------------------------------------- + + +class TestSavedDatasetStorageDispatch: + def test_from_data_source_resolves_spark(self, table_spark_source): + storage = SavedDatasetStorage.from_data_source(table_spark_source) + + assert isinstance(storage, SavedDatasetSparkStorage) + assert storage.spark_options.table == "db.my_table" + + def test_from_data_source_resolves_path_spark(self, path_spark_source): + storage = SavedDatasetStorage.from_data_source(path_spark_source) + + assert isinstance(storage, SavedDatasetSparkStorage) + assert storage.spark_options.path == "s3a://bucket/data/features/" + assert storage.spark_options.file_format == "parquet" + + def test_roundtrip_table_source(self, table_spark_source): + storage = SavedDatasetStorage.from_data_source(table_spark_source) + roundtripped = storage.to_data_source() + + assert isinstance(roundtripped, SparkSource) + assert roundtripped.table == table_spark_source.table + assert roundtripped.query == table_spark_source.query + assert roundtripped.path == table_spark_source.path + + def test_roundtrip_path_source(self): + source = SparkSource( + name="my_path_source", + table="fallback_name", + timestamp_field="event_timestamp", + ) + storage = SavedDatasetStorage.from_data_source(source) + roundtripped = storage.to_data_source() + + assert isinstance(roundtripped, SparkSource) + assert roundtripped.table == source.table + + +# --------------------------------------------------------------------------- +# Group 3: SparkRetrievalJob.persist() +# --------------------------------------------------------------------------- + + +class TestSparkRetrievalJobPersist: + def test_persist_with_table_saves_as_table(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage(table="output_table") + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.write.saveAsTable.assert_called_once_with("output_table") + + def test_persist_with_table_and_format(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage(table="output_table", file_format="parquet") + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.write.format.assert_called_once_with("parquet") + mock_df.write.format.return_value.saveAsTable.assert_called_once_with( + "output_table" + ) + + def test_persist_with_path_writes_to_path(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage( + path="s3a://bucket/output/", file_format="parquet" + ) + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.write.format.assert_called_once_with("parquet") + mock_df.write.format.return_value.mode.assert_called_once_with("error") + mock_df.write.format.return_value.mode.return_value.save.assert_called_once_with( + "s3a://bucket/output/" + ) + + def test_persist_with_path_defaults_to_parquet(self, repo_config): + """When path is set with table_format but no file_format, persist defaults to parquet.""" + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage( + path="s3a://bucket/output/", + file_format=None, + table_format=IcebergFormat(catalog="test_catalog"), + ) + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.write.format.assert_called_once_with("parquet") + + def test_persist_with_path_allow_overwrite(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage( + path="s3a://bucket/output/", file_format="parquet" + ) + + job.persist(storage, allow_overwrite=True) + + mock_df = job.spark_session.sql.return_value + mock_df.write.format.return_value.mode.assert_called_once_with("overwrite") + + def test_persist_with_path_custom_format(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage( + path="s3a://bucket/output/", file_format="avro" + ) + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.write.format.assert_called_once_with("avro") + mock_df.write.format.return_value.mode.return_value.save.assert_called_once_with( + "s3a://bucket/output/" + ) + + def test_persist_raises_without_table_or_path(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=True) + storage = SavedDatasetSparkStorage(query="SELECT * FROM t") + + with pytest.raises( + ValueError, match="either 'table' or 'path' must be specified" + ): + job.persist(storage) + + def test_persist_local_warehouse_creates_temp_view(self, repo_config): + job = _make_spark_retrieval_job(repo_config, remote_warehouse=False) + storage = SavedDatasetSparkStorage(table="output_table") + + job.persist(storage) + + mock_df = job.spark_session.sql.return_value + mock_df.createOrReplaceTempView.assert_called_once_with("output_table") diff --git a/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_staging_filesystem.py b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_staging_filesystem.py new file mode 100644 index 00000000000..5b91646ef7c --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_staging_filesystem.py @@ -0,0 +1,134 @@ +""" +Unit tests for SparkRetrievalJob._resolve_staging_filesystem. + +Verifies that the correct PyArrow filesystem and prefix-stripped paths +are returned for S3, S3A, GCS, file://, and plain local paths. +""" + +from unittest.mock import MagicMock, patch + +import pytest + +from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + SparkRetrievalJob, +) + + +@pytest.fixture() +def retrieval_job(): + """Minimal SparkRetrievalJob with a mock config that has no offline_store region.""" + job = object.__new__(SparkRetrievalJob) + config = MagicMock() + config.offline_store.region = None + job._config = config + return job + + +class TestResolveS3Filesystem: + def test_s3_scheme_returns_s3_filesystem(self, retrieval_job): + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + fs, paths = retrieval_job._resolve_staging_filesystem( + ["s3://my-bucket/path/a.parquet", "s3://my-bucket/path/b.parquet"] + ) + mock_s3.assert_called_once() + assert fs is mock_s3.return_value + assert paths == ["my-bucket/path/a.parquet", "my-bucket/path/b.parquet"] + + def test_s3a_scheme_strips_prefix(self, retrieval_job): + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + fs, paths = retrieval_job._resolve_staging_filesystem( + ["s3a://bucket/dir/file.parquet"] + ) + assert paths == ["bucket/dir/file.parquet"] + + def test_s3_with_minio_endpoint(self, retrieval_job, monkeypatch): + monkeypatch.setenv("AWS_ENDPOINT_URL_S3", "http://minio.local:9000") + monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1") + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert call_kwargs["endpoint_override"] == "minio.local:9000" + assert call_kwargs["scheme"] == "http" + + def test_s3_with_https_endpoint(self, retrieval_job, monkeypatch): + monkeypatch.setenv("AWS_ENDPOINT_URL_S3", "https://s3.custom.corp") + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert call_kwargs["endpoint_override"] == "s3.custom.corp" + assert call_kwargs["scheme"] == "https" + + def test_s3_falls_back_to_aws_s3_endpoint_env(self, retrieval_job, monkeypatch): + monkeypatch.delenv("AWS_ENDPOINT_URL_S3", raising=False) + monkeypatch.setenv("AWS_S3_ENDPOINT", "http://legacy-minio:9000") + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert "endpoint_override" in call_kwargs + + def test_s3_no_endpoint_no_override(self, retrieval_job, monkeypatch): + monkeypatch.delenv("AWS_ENDPOINT_URL_S3", raising=False) + monkeypatch.delenv("AWS_S3_ENDPOINT", raising=False) + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert "endpoint_override" not in call_kwargs + assert "scheme" not in call_kwargs + + def test_s3_region_from_offline_store_config(self, retrieval_job): + retrieval_job._config.offline_store.region = "eu-west-1" + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert call_kwargs["region"] == "eu-west-1" + + def test_s3_region_fallback_to_env(self, retrieval_job, monkeypatch): + retrieval_job._config.offline_store.region = None + monkeypatch.setenv("AWS_DEFAULT_REGION", "ap-southeast-1") + with patch("pyarrow.fs.S3FileSystem") as mock_s3: + mock_s3.return_value = MagicMock(name="s3fs") + retrieval_job._resolve_staging_filesystem(["s3://bucket/file.parquet"]) + call_kwargs = mock_s3.call_args[1] + assert call_kwargs["region"] == "ap-southeast-1" + + +class TestResolveGCSFilesystem: + def test_gs_scheme_returns_gcs_filesystem(self, retrieval_job): + with patch("pyarrow.fs.GcsFileSystem") as mock_gcs: + mock_gcs.return_value = MagicMock(name="gcsfs") + fs, paths = retrieval_job._resolve_staging_filesystem( + ["gs://my-bucket/path/a.parquet", "gs://my-bucket/path/b.parquet"] + ) + mock_gcs.assert_called_once() + assert fs is mock_gcs.return_value + assert paths == ["my-bucket/path/a.parquet", "my-bucket/path/b.parquet"] + + +class TestResolveLocalFilesystem: + def test_file_scheme_stripped(self, retrieval_job): + fs, paths = retrieval_job._resolve_staging_filesystem( + ["file:///tmp/staging/a.parquet"] + ) + assert fs is None + assert paths == ["/tmp/staging/a.parquet"] + + def test_plain_local_path_unchanged(self, retrieval_job): + fs, paths = retrieval_job._resolve_staging_filesystem( + ["/tmp/staging/a.parquet", "/tmp/staging/b.parquet"] + ) + assert fs is None + assert paths == ["/tmp/staging/a.parquet", "/tmp/staging/b.parquet"] + + def test_mixed_file_and_plain_paths(self, retrieval_job): + fs, paths = retrieval_job._resolve_staging_filesystem( + ["file:///tmp/a.parquet", "/tmp/b.parquet"] + ) + assert fs is None + assert paths == ["/tmp/a.parquet", "/tmp/b.parquet"] diff --git a/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py b/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py index 662be20b316..132339e1034 100644 --- a/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py +++ b/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py @@ -1,3 +1,4 @@ +from datetime import datetime, timezone from unittest.mock import Mock, patch import pandas as pd @@ -5,9 +6,11 @@ import pytest from feast.infra.offline_stores.bigquery import ( + BigQueryOfflineStore, BigQueryOfflineStoreConfig, BigQueryRetrievalJob, ) +from feast.infra.offline_stores.bigquery_source import BigQuerySource from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig from feast.repo_config import RepoConfig @@ -82,3 +85,290 @@ def test_to_arrow_timeout(self, big_query_result): self.retrieval_job._execute_query.assert_called_once_with( query=self.query, timeout=30 ) + + +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_pull_latest_from_table_or_query_partition_pruning(mock_get_bigquery_client): + mock_get_bigquery_client.return_value = Mock() + test_repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="test", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + test_data_source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_timestamp", + date_partition_column="partition_date", + ) + retrieval_job = BigQueryOfflineStore.pull_latest_from_table_or_query( + config=test_repo_config, + data_source=test_data_source, + join_key_columns=["driver_id"], + feature_name_columns=["feature1"], + timestamp_field="event_timestamp", + created_timestamp_column=None, + start_date=datetime(2021, 1, 1, tzinfo=timezone.utc), + end_date=datetime(2021, 1, 2, tzinfo=timezone.utc), + ) + actual_query = retrieval_job.to_sql() + assert ( + "event_timestamp BETWEEN TIMESTAMP('2021-01-01T00:00:00+00:00') AND TIMESTAMP('2021-01-02T00:00:00+00:00')" + in actual_query + ) + assert "partition_date >= '2021-01-01'" in actual_query + assert "partition_date <= '2021-01-02'" in actual_query + + +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_pull_all_from_table_or_query_partition_pruning(mock_get_bigquery_client): + mock_get_bigquery_client.return_value = Mock() + test_repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="test", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + test_data_source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_timestamp", + date_partition_column="partition_date", + ) + retrieval_job = BigQueryOfflineStore.pull_all_from_table_or_query( + config=test_repo_config, + data_source=test_data_source, + join_key_columns=["driver_id"], + feature_name_columns=["feature1"], + timestamp_field="event_timestamp", + start_date=datetime(2021, 1, 1, tzinfo=timezone.utc), + end_date=datetime(2021, 1, 2, tzinfo=timezone.utc), + ) + actual_query = retrieval_job.to_sql() + assert ( + "event_timestamp BETWEEN TIMESTAMP('2021-01-01T00:00:00+00:00') AND TIMESTAMP('2021-01-02T00:00:00+00:00')" + in actual_query + ) + assert "partition_date >= '2021-01-01'" in actual_query + assert "partition_date <= '2021-01-02'" in actual_query + + +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_pull_latest_date_type_timestamp_field(mock_get_bigquery_client): + mock_get_bigquery_client.return_value = Mock() + test_repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="test", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + test_data_source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_date", + timestamp_field_type="DATE", + ) + retrieval_job = BigQueryOfflineStore.pull_latest_from_table_or_query( + config=test_repo_config, + data_source=test_data_source, + join_key_columns=["driver_id"], + feature_name_columns=["feature1"], + timestamp_field="event_date", + created_timestamp_column=None, + start_date=datetime(2021, 1, 1, tzinfo=timezone.utc), + end_date=datetime(2021, 1, 2, tzinfo=timezone.utc), + ) + actual_query = retrieval_job.to_sql() + assert ( + "event_date BETWEEN DATE('2021-01-01') AND DATE('2021-01-02')" in actual_query + ) + assert "TIMESTAMP(" not in actual_query + + +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_pull_all_date_type_timestamp_field(mock_get_bigquery_client): + mock_get_bigquery_client.return_value = Mock() + test_repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="test", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + test_data_source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_date", + timestamp_field_type="DATE", + ) + retrieval_job = BigQueryOfflineStore.pull_all_from_table_or_query( + config=test_repo_config, + data_source=test_data_source, + join_key_columns=["driver_id"], + feature_name_columns=["feature1"], + timestamp_field="event_date", + start_date=datetime(2021, 1, 1, tzinfo=timezone.utc), + end_date=datetime(2021, 1, 2, tzinfo=timezone.utc), + ) + actual_query = retrieval_job.to_sql() + assert ( + "event_date BETWEEN DATE('2021-01-01') AND DATE('2021-01-02')" in actual_query + ) + assert "TIMESTAMP(" not in actual_query + + +@patch("feast.infra.offline_stores.bigquery._get_bigquery_client") +def test_pull_latest_date_type_with_partition_column(mock_get_bigquery_client): + mock_get_bigquery_client.return_value = Mock() + test_repo_config = RepoConfig( + registry="gs://ml-test/repo/registry.db", + project="test", + provider="gcp", + online_store=SqliteOnlineStoreConfig(type="sqlite"), + offline_store=BigQueryOfflineStoreConfig(type="bigquery", dataset="feast"), + ) + test_data_source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_date", + timestamp_field_type="DATE", + date_partition_column="_PARTITIONDATE", + ) + retrieval_job = BigQueryOfflineStore.pull_latest_from_table_or_query( + config=test_repo_config, + data_source=test_data_source, + join_key_columns=["driver_id"], + feature_name_columns=["feature1"], + timestamp_field="event_date", + created_timestamp_column=None, + start_date=datetime(2021, 1, 1, tzinfo=timezone.utc), + end_date=datetime(2021, 1, 2, tzinfo=timezone.utc), + ) + actual_query = retrieval_job.to_sql() + assert "DATE('2021-01-01')" in actual_query + assert "DATE('2021-01-02')" in actual_query + assert "_PARTITIONDATE >= '2021-01-01'" in actual_query + assert "_PARTITIONDATE <= '2021-01-02'" in actual_query + + +def test_bigquery_source_date_type_proto_roundtrip(): + source = BigQuerySource( + table="project:dataset.table", + timestamp_field="event_date", + timestamp_field_type="DATE", + date_partition_column="_PARTITIONDATE", + ) + proto = source.to_proto() + restored = BigQuerySource.from_proto(proto) + assert restored.timestamp_field_type == "DATE" + assert restored.date_partition_column == "_PARTITIONDATE" + assert restored.timestamp_field == "event_date" + assert source == restored + + +class TestBigQuerySourceGetTableQueryString: + def test_table_only(self): + source = BigQuerySource( + name="test", + table="project.dataset.table", + timestamp_field="ts", + ) + assert source.get_table_query_string() == "`project.dataset.table`" + + def test_query_only(self): + source = BigQuerySource( + name="test", + query="SELECT * FROM `project.dataset.table` WHERE active = TRUE", + timestamp_field="ts", + ) + assert ( + source.get_table_query_string() + == "(SELECT * FROM `project.dataset.table` WHERE active = TRUE)" + ) + + def test_both_table_and_query_prefers_query(self): + """When both table and query are set, query takes priority for reads.""" + query = ( + "SELECT * FROM `project.dataset.table`" + " QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id, event_time) = 1" + ) + source = BigQuerySource( + name="test", + table="project.dataset.table", + query=query, + timestamp_field="ts", + ) + result = source.get_table_query_string() + assert result.startswith("(") + assert "QUALIFY" in result + assert result != "`project.dataset.table`" + + def test_table_property_unaffected_by_query_priority(self): + """The .table property is still accessible for write paths.""" + source = BigQuerySource( + name="test", + table="project.dataset.write_target", + query="SELECT * FROM `project.dataset.write_target` WHERE deduped", + timestamp_field="ts", + ) + assert source.table == "project.dataset.write_target" + + +class TestOfflineWriteBatch: + @patch("feast.infra.offline_stores.bigquery._get_bigquery_client") + def test_offline_write_batch_enables_list_inference(self, mock_get_client): + """LoadJobConfig must set parquet_options.enable_list_inference = True + so that BigQuery correctly interprets PyArrow list columns from parquet. + """ + from unittest.mock import MagicMock + + source = BigQuerySource( + name="test", + table="project.dataset.table", + timestamp_field="ts", + ) + fv = MagicMock() + fv.batch_source = source + + pa_schema = pyarrow.schema( + [ + pyarrow.field("entity_id", pyarrow.string()), + pyarrow.field("tags", pyarrow.list_(pyarrow.string())), + pyarrow.field("ts", pyarrow.timestamp("us", tz="UTC")), + ] + ) + pa_table = pyarrow.table( + { + "entity_id": ["e1"], + "tags": [["a", "b"]], + "ts": [datetime(2024, 1, 1, tzinfo=timezone.utc)], + }, + schema=pa_schema, + ) + + mock_client = MagicMock() + mock_get_client.return_value = mock_client + mock_client.load_table_from_file.return_value = MagicMock() + + config = RepoConfig( + registry="gs://test/registry.db", + project="test", + provider="gcp", + offline_store=BigQueryOfflineStoreConfig(project_id="test-project"), + online_store=SqliteOnlineStoreConfig(), + ) + + with patch( + "feast.infra.offline_stores.offline_utils.get_pyarrow_schema_from_batch_source", + return_value=(pa_schema, pa_table.column_names), + ): + BigQueryOfflineStore.offline_write_batch( + config=config, + feature_view=fv, + table=pa_table, + progress=None, + ) + + call_kwargs = mock_client.load_table_from_file.call_args + job_config = call_kwargs[1]["job_config"] + assert job_config.parquet_options is not None + assert job_config.parquet_options.enable_list_inference is True diff --git a/sdk/python/tests/unit/infra/offline_stores/test_dask_non_entity.py b/sdk/python/tests/unit/infra/offline_stores/test_dask_non_entity.py index f3d78ff5a9b..4f8ad322eee 100644 --- a/sdk/python/tests/unit/infra/offline_stores/test_dask_non_entity.py +++ b/sdk/python/tests/unit/infra/offline_stores/test_dask_non_entity.py @@ -311,7 +311,7 @@ def test_non_entity_mode_with_end_date_only_calculates_start_from_ttl( # Latest value should be 0.3 (from 2023-01-07) assert 0.3 in driver1_data["conv_rate"].values - @patch("feast.infra.offline_stores.dask.datetime") + @patch("feast.utils.datetime") def test_no_dates_provided_defaults_to_current_time_and_filters_data( self, mock_datetime, monkeypatch ): diff --git a/sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py b/sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py index 7e5558e19d7..3b84b1a3547 100644 --- a/sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py +++ b/sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py @@ -1050,3 +1050,240 @@ def tracking_client(*args, **kwargs): f"Expected 1 shared client for thread-safety, " f"got {len(set(dynamodb_clients))} unique clients" ) + + +@mock_dynamodb +def test_dynamodb_online_store_online_read_with_requested_features( + repo_config, dynamodb_online_store +): + """Test that requested_features filters returned features.""" + n_samples = 5 + db_table_name = f"{TABLE_NAME}_requested_features" + create_test_table(PROJECT, db_table_name, REGION) + data = create_n_customer_test_samples(n=n_samples) + insert_data_test_table(data, PROJECT, db_table_name, REGION) + + entity_keys, features, *rest = zip(*data) + returned_items = dynamodb_online_store.online_read( + config=repo_config, + table=MockFeatureView(name=db_table_name), + entity_keys=entity_keys, + requested_features=["name", "age"], + ) + assert len(returned_items) == n_samples + for _, feat_dict in returned_items: + assert feat_dict is not None + assert "name" in feat_dict + assert "age" in feat_dict + assert "avg_orders_day" not in feat_dict + + +@mock_dynamodb +def test_dynamodb_online_store_online_read_without_requested_features( + repo_config, dynamodb_online_store +): + """Test that omitting requested_features returns all features.""" + n_samples = 5 + db_table_name = f"{TABLE_NAME}_all_features" + create_test_table(PROJECT, db_table_name, REGION) + data = create_n_customer_test_samples(n=n_samples) + insert_data_test_table(data, PROJECT, db_table_name, REGION) + + entity_keys, features, *rest = zip(*data) + returned_items = dynamodb_online_store.online_read( + config=repo_config, + table=MockFeatureView(name=db_table_name), + entity_keys=entity_keys, + requested_features=None, + ) + assert len(returned_items) == n_samples + for _, feat_dict in returned_items: + assert feat_dict is not None + assert set(feat_dict.keys()) == {"avg_orders_day", "name", "age"} + + +def test_build_projection_expression(): + """Test that _build_projection_expression generates correct DynamoDB expressions.""" + result = DynamoDBOnlineStore._build_projection_expression(["feat_a", "feat_b"]) + assert result is not None + assert "#entity_id" in result["ProjectionExpression"] + assert "#event_ts" in result["ProjectionExpression"] + assert "#vals.#feat0" in result["ProjectionExpression"] + assert "#vals.#feat1" in result["ProjectionExpression"] + attr_names = result["ExpressionAttributeNames"] + assert attr_names["#vals"] == "values" + assert attr_names["#feat0"] == "feat_a" + assert attr_names["#feat1"] == "feat_b" + + +def test_build_projection_expression_none(): + """Test that _build_projection_expression returns None for empty input.""" + assert DynamoDBOnlineStore._build_projection_expression(None) is None + assert DynamoDBOnlineStore._build_projection_expression([]) is None + + +@mock_dynamodb +def test_dynamodb_online_store_online_read_requested_features_parallel( + dynamodb_online_store, +): + """Test that requested_features works across parallel batches.""" + small_batch_config = RepoConfig( + registry=REGISTRY, + project=PROJECT, + provider=PROVIDER, + online_store=DynamoDBOnlineStoreConfig(region=REGION, batch_size=5), + offline_store=DaskOfflineStoreConfig(), + entity_key_serialization_version=3, + ) + n_samples = 15 + db_table_name = f"{TABLE_NAME}_requested_parallel" + create_test_table(PROJECT, db_table_name, REGION) + data = create_n_customer_test_samples(n=n_samples) + insert_data_test_table(data, PROJECT, db_table_name, REGION) + + entity_keys, features, *rest = zip(*data) + returned_items = dynamodb_online_store.online_read( + config=small_batch_config, + table=MockFeatureView(name=db_table_name), + entity_keys=entity_keys, + requested_features=["age"], + ) + assert len(returned_items) == n_samples + for _, feat_dict in returned_items: + assert feat_dict is not None + assert "age" in feat_dict + assert "name" not in feat_dict + assert "avg_orders_day" not in feat_dict + + +# --------------------------------------------------------------------------- +# Tests for the diff-based _update_tags (fix for GitHub issue #6418) +# +# DynamoDB's TagResource / UntagResource are eventually consistent, so the +# old approach of "remove all → re-add all" could leave tables tag-less due +# to the async propagation gap. The new approach only touches tags that +# actually need to change. +# --------------------------------------------------------------------------- + + +def _make_mock_dynamodb_client( + current_tags: list[dict[str, str]], + table_arn: str = "arn:aws:dynamodb:us-west-2:123456789012:table/test_table", +): + """Helper: create a pure MagicMock DynamoDB client for tag tests. + This avoids Moto's authentication issues with DynamoDB tag APIs. + """ + from unittest.mock import MagicMock + + client = MagicMock() + # Mock describe_table + client.describe_table.return_value = {"Table": {"TableArn": table_arn}} + # Mock list_tags_of_resource + client.list_tags_of_resource.return_value = {"Tags": current_tags} + return client + + +def test_update_tags_no_change_makes_no_api_calls(): + """Idempotency: calling _update_tags with identical tags must not call + untag_resource or tag_resource (avoids unnecessary eventual-consistency exposure). + """ + table_name = f"{TABLE_NAME}_no_change" + initial_tags = [{"Key": "env", "Value": "prod"}, {"Key": "team", "Value": "ml"}] + client = _make_mock_dynamodb_client(current_tags=initial_tags) + + DynamoDBOnlineStore._update_tags(client, table_name, initial_tags) + + client.untag_resource.assert_not_called() + client.tag_resource.assert_not_called() + + +def test_update_tags_adds_new_tags_without_untag(): + """Adding a new tag key must call tag_resource but NOT untag_resource.""" + table_name = f"{TABLE_NAME}_add_only" + existing = [{"Key": "env", "Value": "prod"}] + client = _make_mock_dynamodb_client(current_tags=existing) + + new_tags = [{"Key": "env", "Value": "prod"}, {"Key": "team", "Value": "ml"}] + DynamoDBOnlineStore._update_tags(client, table_name, new_tags) + + client.untag_resource.assert_not_called() + client.tag_resource.assert_called_once() + added = client.tag_resource.call_args[1]["Tags"] + assert added == [{"Key": "team", "Value": "ml"}] + + +def test_update_tags_removes_obsolete_tags_only(): + """Only truly obsolete tag keys (not in new_tags) must be passed to untag_resource.""" + table_name = f"{TABLE_NAME}_remove_only" + existing = [{"Key": "env", "Value": "prod"}, {"Key": "old-key", "Value": "old"}] + client = _make_mock_dynamodb_client(current_tags=existing) + + new_tags = [{"Key": "env", "Value": "prod"}] + DynamoDBOnlineStore._update_tags(client, table_name, new_tags) + + client.untag_resource.assert_called_once() + removed_keys = client.untag_resource.call_args[1]["TagKeys"] + assert removed_keys == ["old-key"] + + client.tag_resource.assert_not_called() + + +def test_update_tags_updates_changed_value(): + """A tag whose value changed must be passed to tag_resource (not untag_resource).""" + table_name = f"{TABLE_NAME}_change_value" + existing = [{"Key": "env", "Value": "staging"}] + client = _make_mock_dynamodb_client(current_tags=existing) + + new_tags = [{"Key": "env", "Value": "prod"}] + + DynamoDBOnlineStore._update_tags(client, table_name, new_tags) + + client.untag_resource.assert_not_called() + client.tag_resource.assert_called_once() + updated = client.tag_resource.call_args[1]["Tags"] + assert updated == [{"Key": "env", "Value": "prod"}] + + +def test_update_tags_full_replace(): + """Replacing an entire tag set removes old keys and adds new ones correctly.""" + table_name = f"{TABLE_NAME}_full_replace" + existing = [{"Key": "old1", "Value": "v1"}, {"Key": "old2", "Value": "v2"}] + client = _make_mock_dynamodb_client(current_tags=existing) + + new_tags = [{"Key": "new1", "Value": "n1"}, {"Key": "new2", "Value": "n2"}] + + DynamoDBOnlineStore._update_tags(client, table_name, new_tags) + + client.untag_resource.assert_called_once() + removed = set(client.untag_resource.call_args[1]["TagKeys"]) + assert removed == {"old1", "old2"} + + client.tag_resource.assert_called_once() + added = {t["Key"] for t in client.tag_resource.call_args[1]["Tags"]} + assert added == {"new1", "new2"} + + +def test_update_tags_clear_all_tags(): + """Passing an empty new_tags list removes all existing tags without calling tag_resource.""" + table_name = f"{TABLE_NAME}_clear_all" + existing = [{"Key": "env", "Value": "prod"}] + client = _make_mock_dynamodb_client(current_tags=existing) + + DynamoDBOnlineStore._update_tags(client, table_name, []) + + client.untag_resource.assert_called_once() + removed = client.untag_resource.call_args[1]["TagKeys"] + assert removed == ["env"] + + client.tag_resource.assert_not_called() + + +def test_update_tags_no_existing_tags_no_new_tags(): + """Both old and new tag sets are empty: no API calls at all.""" + table_name = f"{TABLE_NAME}_empty_both" + client = _make_mock_dynamodb_client(current_tags=[]) + + DynamoDBOnlineStore._update_tags(client, table_name, []) + + client.untag_resource.assert_not_called() + client.tag_resource.assert_not_called() diff --git a/sdk/python/tests/unit/infra/online_store/test_dynamodb_versioning.py b/sdk/python/tests/unit/infra/online_store/test_dynamodb_versioning.py new file mode 100644 index 00000000000..492d68494d8 --- /dev/null +++ b/sdk/python/tests/unit/infra/online_store/test_dynamodb_versioning.py @@ -0,0 +1,128 @@ +"""Unit tests for DynamoDB online store feature view versioning.""" + +from datetime import timedelta +from unittest.mock import MagicMock + +from feast import Entity, FeatureView +from feast.field import Field +from feast.types import Float32 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version_number=None, version_tag=None): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + fv = FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[Field(name="trips_today", dtype=Float32)], + ) + if version_number is not None: + fv.current_version_number = version_number + if version_tag is not None: + fv.projection.version_tag = version_tag + return fv + + +def _make_config(project="test_project", versioning=False): + config = MagicMock() + config.project = project + config.entity_key_serialization_version = 2 + config.registry.enable_online_feature_view_versioning = versioning + return config + + +def _make_online_config(template="{project}.{table_name}"): + online_config = MagicMock() + online_config.table_name_template = template + return online_config + + +class TestGetTableName: + """Test _get_table_name with versioning enabled/disabled.""" + + def test_no_versioning(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view() + config = _make_config(versioning=False) + online_config = _make_online_config() + assert _get_table_name(online_config, config, fv) == "test_project.driver_stats" + + def test_versioning_enabled_with_version(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view(version_number=2) + config = _make_config(versioning=True) + online_config = _make_online_config() + assert ( + _get_table_name(online_config, config, fv) == "test_project.driver_stats_v2" + ) + + def test_projection_version_tag_takes_priority(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view(version_number=1, version_tag=3) + config = _make_config(versioning=True) + online_config = _make_online_config() + assert ( + _get_table_name(online_config, config, fv) == "test_project.driver_stats_v3" + ) + + def test_version_zero_no_suffix(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view(version_number=0) + config = _make_config(versioning=True) + online_config = _make_online_config() + assert _get_table_name(online_config, config, fv) == "test_project.driver_stats" + + def test_versioning_enabled_no_version_set(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view() + config = _make_config(versioning=True) + online_config = _make_online_config() + assert _get_table_name(online_config, config, fv) == "test_project.driver_stats" + + def test_custom_template_with_versioning(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view(version_number=2) + config = _make_config(project="prod", versioning=True) + online_config = _make_online_config(template="feast-{project}-{table_name}") + assert ( + _get_table_name(online_config, config, fv) == "feast-prod-driver_stats_v2" + ) + + def test_versioning_disabled_ignores_version(self): + from feast.infra.online_stores.dynamodb import _get_table_name + + fv = _make_feature_view(version_number=5) + config = _make_config(versioning=False) + online_config = _make_online_config() + assert _get_table_name(online_config, config, fv) == "test_project.driver_stats" + + +class TestDynamoDBVersionedReadSupport: + """Test that DynamoDBOnlineStore passes _check_versioned_read_support.""" + + def test_allowed_with_version_tag(self): + from feast.infra.online_stores.dynamodb import DynamoDBOnlineStore + + store = DynamoDBOnlineStore() + fv = _make_feature_view() + fv.projection.version_tag = 2 + # Should not raise + store._check_versioned_read_support([(fv, ["trips_today"])]) + + def test_allowed_without_version_tag(self): + from feast.infra.online_stores.dynamodb import DynamoDBOnlineStore + + store = DynamoDBOnlineStore() + fv = _make_feature_view() + store._check_versioned_read_support([(fv, ["trips_today"])]) diff --git a/sdk/python/tests/unit/infra/online_store/test_faiss_versioning.py b/sdk/python/tests/unit/infra/online_store/test_faiss_versioning.py new file mode 100644 index 00000000000..84b0aa24e99 --- /dev/null +++ b/sdk/python/tests/unit/infra/online_store/test_faiss_versioning.py @@ -0,0 +1,249 @@ +"""Unit tests for FAISS online store feature view versioning.""" + +import sys +from datetime import timedelta +from unittest.mock import MagicMock, patch + +import numpy as np +import pytest + +from feast import Entity, FeatureView +from feast.field import Field +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.types import Float32 +from feast.value_type import ValueType + + +def _make_feature_view(name="driver_stats", version_number=None, version_tag=None): + entity = Entity( + name="driver_id", + join_keys=["driver_id"], + value_type=ValueType.INT64, + ) + fv = FeatureView( + name=name, + entities=[entity], + ttl=timedelta(days=1), + schema=[Field(name="feature_a", dtype=Float32)], + ) + if version_number is not None: + fv.current_version_number = version_number + if version_tag is not None: + fv.projection.version_tag = version_tag + return fv + + +@pytest.fixture(autouse=True) +def _mock_faiss(): + """Inject a minimal faiss mock so faiss_online_store can be imported.""" + faiss_mock = MagicMock() + with patch.dict(sys.modules, {"faiss": faiss_mock}): + sys.modules.pop("feast.infra.online_stores.faiss_online_store", None) + yield faiss_mock + sys.modules.pop("feast.infra.online_stores.faiss_online_store", None) + + +class TestFaissTableId: + """Test _table_id generates correct versioned table names.""" + + def test_default_no_versioning(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view() + assert _table_id("proj", fv) == "proj_driver_stats" + + def test_versioning_explicitly_disabled(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_number=3) + assert _table_id("proj", fv, enable_versioning=False) == "proj_driver_stats" + + def test_versioning_enabled_no_version_set(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view() + assert _table_id("proj", fv, enable_versioning=True) == "proj_driver_stats" + + def test_versioning_enabled_with_current_version_number(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_number=2) + assert _table_id("proj", fv, enable_versioning=True) == "proj_driver_stats_v2" + + def test_version_zero_no_suffix(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_number=0) + assert _table_id("proj", fv, enable_versioning=True) == "proj_driver_stats" + + def test_projection_version_tag_takes_priority(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_number=1, version_tag=3) + assert _table_id("proj", fv, enable_versioning=True) == "proj_driver_stats_v3" + + def test_projection_version_tag_zero_no_suffix(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_tag=0, version_number=3) + assert _table_id("proj", fv, enable_versioning=True) == "proj_driver_stats" + + def test_different_project_names(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(version_number=1) + assert _table_id("prod", fv, enable_versioning=True) == "prod_driver_stats_v1" + assert ( + _table_id("staging", fv, enable_versioning=True) + == "staging_driver_stats_v1" + ) + + def test_different_feature_view_names(self): + from feast.infra.online_stores.faiss_online_store import _table_id + + fv = _make_feature_view(name="user_stats", version_number=2) + assert _table_id("proj", fv, enable_versioning=True) == "proj_user_stats_v2" + + +class TestFaissVersionedReadSupport: + """Test that FaissOnlineStore passes _check_versioned_read_support.""" + + def test_allowed_with_version_tag(self): + from feast.infra.online_stores.faiss_online_store import FaissOnlineStore + + store = FaissOnlineStore() + fv = _make_feature_view() + fv.projection.version_tag = 2 + store._check_versioned_read_support([(fv, ["feature_a"])]) + + def test_allowed_without_version_tag(self): + from feast.infra.online_stores.faiss_online_store import FaissOnlineStore + + store = FaissOnlineStore() + fv = _make_feature_view() + store._check_versioned_read_support([(fv, ["feature_a"])]) + + +def _make_config(project="test_project", versioning=False): + """Build a minimal RepoConfig-like mock.""" + config = MagicMock() + config.project = project + config.entity_key_serialization_version = 2 + config.online_store.dict.return_value = { + "dimension": 1, + "index_path": "/tmp/test.index", + "index_type": "IVFFlat", + "nlist": 10, + } + config.registry.enable_online_feature_view_versioning = versioning + return config + + +def _make_entity_key(driver_id=1): + return EntityKeyProto( + join_keys=["driver_id"], + entity_values=[ValueProto(int64_val=driver_id)], + ) + + +class TestFaissOnlineStoreVersionedReadWrite: + def _make_store(self, faiss_mock, nlist=10): + """Create a FaissOnlineStore with a real-enough faiss mock.""" + index_mock = MagicMock() + index_mock.ntotal = 0 + + def add_side_effect(vectors): + index_mock.ntotal += len(vectors) + + index_mock.add.side_effect = add_side_effect + + def reconstruct_side_effect(idx): + return np.array([float(idx)], dtype=np.float32) + + index_mock.reconstruct.side_effect = reconstruct_side_effect + + faiss_mock.IndexFlatL2.return_value = MagicMock() + faiss_mock.IndexIVFFlat.return_value = index_mock + + from feast.infra.online_stores.faiss_online_store import FaissOnlineStore + + store = FaissOnlineStore() + return store, index_mock + + def test_write_and_read_without_versioning(self, _mock_faiss): + store, _ = self._make_store(_mock_faiss) + config = _make_config(versioning=False) + fv = _make_feature_view() + + store.update(config, [], [fv], [], [], partial=False) + + entity_key = _make_entity_key(driver_id=42) + data = [(entity_key, {"feature_a": ValueProto(double_val=1.5)}, None, None)] + store.online_write_batch(config, fv, data, None) + + results = store.online_read(config, fv, [entity_key]) + assert len(results) == 1 + _, feature_dict = results[0] + assert feature_dict is not None + assert "feature_a" in feature_dict + + def test_write_and_read_with_versioning(self, _mock_faiss): + store, _ = self._make_store(_mock_faiss) + config = _make_config(versioning=True) + fv_v2 = _make_feature_view(version_number=2) + + store.update(config, [], [fv_v2], [], [], partial=False) + + entity_key = _make_entity_key(driver_id=7) + data = [(entity_key, {"feature_a": ValueProto(double_val=2.0)}, None, None)] + store.online_write_batch(config, fv_v2, data, None) + + results = store.online_read(config, fv_v2, [entity_key]) + assert len(results) == 1 + _, feature_dict = results[0] + assert feature_dict is not None + + def test_versioned_namespaces_are_isolated(self, _mock_faiss): + """Data written under v1 must not be visible when reading under v2.""" + store, _ = self._make_store(_mock_faiss) + config = _make_config(versioning=True) + + fv_v1 = _make_feature_view(version_number=1) + fv_v2 = _make_feature_view(version_number=2) + + store.update(config, [], [fv_v1, fv_v2], [], [], partial=False) + + entity_key = _make_entity_key(driver_id=99) + data = [(entity_key, {"feature_a": ValueProto(double_val=9.9)}, None, None)] + store.online_write_batch(config, fv_v1, data, None) + + results_v2 = store.online_read(config, fv_v2, [entity_key]) + assert results_v2 == [(None, None)] + + results_v1 = store.online_read(config, fv_v1, [entity_key]) + assert results_v1[0][1] is not None + + def test_missing_index_returns_none(self, _mock_faiss): + store, _ = self._make_store(_mock_faiss) + config = _make_config(versioning=True) + fv = _make_feature_view(version_number=5) + entity_key = _make_entity_key(driver_id=1) + results = store.online_read(config, fv, [entity_key]) + assert results == [(None, None)] + + def test_teardown_removes_versioned_index(self, _mock_faiss): + store, _ = self._make_store(_mock_faiss) + config = _make_config(versioning=True) + fv = _make_feature_view(version_number=3) + + store.update(config, [], [fv], [], [], partial=False) + + entity_key = _make_entity_key(driver_id=1) + data = [(entity_key, {"feature_a": ValueProto(double_val=3.0)}, None, None)] + store.online_write_batch(config, fv, data, None) + + store.teardown(config, [fv], []) + + results = store.online_read(config, fv, [entity_key]) + assert results == [(None, None)] diff --git a/sdk/python/tests/unit/infra/online_store/test_helpers.py b/sdk/python/tests/unit/infra/online_store/test_helpers.py new file mode 100644 index 00000000000..2d65dff5203 --- /dev/null +++ b/sdk/python/tests/unit/infra/online_store/test_helpers.py @@ -0,0 +1,150 @@ +import struct +from datetime import datetime, timezone +from unittest.mock import MagicMock, patch + +import mmh3 + +from feast.infra.online_stores.helpers import ( + _mmh3, + _redis_key, + _redis_key_prefix, + _to_naive_utc, + compute_entity_id, + get_online_store_from_config, +) +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto + + +def _make_entity_key(join_keys, values): + """Helper to build an EntityKeyProto.""" + entity_key = EntityKeyProto() + for k in join_keys: + entity_key.join_keys.append(k) + for v in values: + entity_key.entity_values.append(v) + return entity_key + + +class TestRedisKey: + def test_redis_key_produces_bytes(self): + entity_key = _make_entity_key(["user_id"], [ValueProto(string_val="user_1")]) + result = _redis_key("my_project", entity_key) + assert isinstance(result, bytes) + + def test_redis_key_contains_project(self): + entity_key = _make_entity_key(["user_id"], [ValueProto(string_val="user_1")]) + result = _redis_key("my_project", entity_key) + assert b"my_project" in result + + def test_redis_key_different_projects_produce_different_keys(self): + entity_key = _make_entity_key(["user_id"], [ValueProto(string_val="user_1")]) + key_a = _redis_key("project_a", entity_key) + key_b = _redis_key("project_b", entity_key) + assert key_a != key_b + + def test_redis_key_different_entities_produce_different_keys(self): + ek1 = _make_entity_key(["user_id"], [ValueProto(string_val="user_1")]) + ek2 = _make_entity_key(["user_id"], [ValueProto(string_val="user_2")]) + assert _redis_key("proj", ek1) != _redis_key("proj", ek2) + + def test_redis_key_serialization_version_changes_key(self): + entity_key = _make_entity_key(["user_id"], [ValueProto(string_val="user_1")]) + key_v2 = _redis_key("proj", entity_key, entity_key_serialization_version=2) + key_v3 = _redis_key("proj", entity_key, entity_key_serialization_version=3) + assert key_v2 != key_v3 + + +class TestRedisKeyPrefix: + def test_returns_bytes(self): + result = _redis_key_prefix(["user_id"]) + assert isinstance(result, bytes) + + def test_different_keys_produce_different_prefixes(self): + prefix_a = _redis_key_prefix(["user_id"]) + prefix_b = _redis_key_prefix(["merchant_id"]) + assert prefix_a != prefix_b + + +class TestMmh3: + def test_returns_bytes(self): + result = _mmh3("test_key") + assert isinstance(result, bytes) + + def test_consistent_hash(self): + assert _mmh3("hello") == _mmh3("hello") + + def test_different_keys_different_hashes(self): + assert _mmh3("key_a") != _mmh3("key_b") + + def test_hash_length(self): + result = _mmh3("test") + assert len(result) == 4 # 32-bit hash = 4 bytes + + def test_little_endian_format(self): + """Verify the hash matches the expected little-endian encoding.""" + key = "test_key" + key_hash = mmh3.hash(key, signed=False) + expected = bytes.fromhex(struct.pack(" RegistryServer_pb2.ListProjectsResponse: + spec = Project_pb2.ProjectSpec( + name="test_project", + description="created by mTLS test", + ) + project = Project_pb2.Project(spec=spec) + return RegistryServer_pb2.ListProjectsResponse(projects=[project]) + + def Proto( + self, + request: Empty, + context: grpc.ServicerContext, + ) -> Registry_pb2.Registry: + return Registry_pb2.Registry() + + +# --------------------------------------------------------------------------- +# Fixtures +# --------------------------------------------------------------------------- + + +def _generate_certs_and_start_server( + tmpdir: str, server_san: str +) -> tuple[dict[str, str], grpc.Server, int]: + """Helper: generate mTLS certs and start a gRPC server requiring client auth.""" + certs = generate_mtls_certs(tmpdir, server_san=server_san) + + with open(certs["ca_cert"], "rb") as f: + ca_cert = f.read() + with open(certs["server_key"], "rb") as f: + server_key = f.read() + with open(certs["server_cert"], "rb") as f: + server_cert = f.read() + + server_creds = grpc.ssl_server_credentials( + [(server_key, server_cert)], + root_certificates=ca_cert, + require_client_auth=True, + ) + + server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) + RegistryServer_pb2_grpc.add_RegistryServerServicer_to_server( + _StubRegistryServicer(), server + ) + port = server.add_secure_port("localhost:0", server_creds) + server.start() + return certs, server, port + + +# -- Fixtures for IAP-tunnel tests (SAN ≠ localhost) -- + + +@pytest.fixture(scope="module") +def mtls_certs() -> Generator[tuple[dict[str, str], int], None, None]: + """Certs where the server SAN is SERVICE_HOSTNAME (not localhost).""" + with tempfile.TemporaryDirectory() as tmpdir: + certs, server, port = _generate_certs_and_start_server(tmpdir, SERVICE_HOSTNAME) + yield certs, port + server.stop(grace=0) + + +@pytest.fixture(scope="module") +def mtls_server(mtls_certs: tuple[dict[str, str], int]) -> int: + return mtls_certs[1] + + +@pytest.fixture(scope="module") +def mtls_certs_only(mtls_certs: tuple[dict[str, str], int]) -> dict[str, str]: + return mtls_certs[0] + + +# -- Fixtures for direct-connection tests (SAN = localhost) -- + + +@pytest.fixture(scope="module") +def direct_mtls() -> Generator[tuple[dict[str, str], int], None, None]: + """Certs where the server SAN includes localhost (direct connection).""" + with tempfile.TemporaryDirectory() as tmpdir: + certs, server, port = _generate_certs_and_start_server(tmpdir, "localhost") + yield certs, port + server.stop(grace=0) + + +@pytest.fixture(scope="module") +def direct_server(direct_mtls: tuple[dict[str, str], int]) -> int: + return direct_mtls[1] + + +@pytest.fixture(scope="module") +def direct_certs(direct_mtls: tuple[dict[str, str], int]) -> dict[str, str]: + return direct_mtls[0] + + +# --------------------------------------------------------------------------- +# Tests +# --------------------------------------------------------------------------- + + +class TestMtlsDirectConnection: + """ + Direct connection to the registry — no proxy or tunnel. + + The server cert's SAN includes ``localhost`` so gRPC's default authority + (derived from the connection target) already matches. The ``authority`` + field should be optional. + + Config equivalent: + registry: + registry_type: remote + path: feature-registry.example.com:443 + cert: /etc/tls/internal-client/ca.crt + client_cert: /etc/tls/internal-client/tls.crt + client_key: /etc/tls/internal-client/tls.key + """ + + def test_mtls_without_authority( + self, direct_server: int, direct_certs: dict[str, str] + ) -> None: + """authority is not set — gRPC defaults it to 'localhost', which matches the SAN.""" + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{direct_server}", + cert=direct_certs["ca_cert"], + client_cert=direct_certs["client_cert"], + client_key=direct_certs["client_key"], + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + projects = registry.list_projects() + assert len(projects) == 1 + assert projects[0].name == "test_project" + finally: + registry.close() + + def test_mtls_with_explicit_authority_matching_san( + self, direct_server: int, direct_certs: dict[str, str] + ) -> None: + """authority is explicitly set to the same host — should also work.""" + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{direct_server}", + cert=direct_certs["ca_cert"], + client_cert=direct_certs["client_cert"], + client_key=direct_certs["client_key"], + authority="localhost", + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + projects = registry.list_projects() + assert len(projects) == 1 + assert projects[0].name == "test_project" + finally: + registry.close() + + +class TestMtlsIapTunnel: + """ + Simulates ``gcloud compute start-iap-tunnel`` to a remote registry. + + The server cert's SAN is ``feature-registry.example.com`` — it does NOT + include ``localhost``. The ``authority`` field is mandatory. + + Config equivalent: + registry: + registry_type: remote + path: localhost:8443 + cert: /etc/tls/internal-client/ca.crt + client_cert: /etc/tls/internal-client/tls.crt + client_key: /etc/tls/internal-client/tls.key + authority: feature-registry.example.com + """ + + def test_list_projects_via_mtls_with_authority( + self, mtls_server: int, mtls_certs_only: dict[str, str] + ) -> None: + """The primary IAP-tunnel scenario: all four fields set.""" + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{mtls_server}", + cert=mtls_certs_only["ca_cert"], + client_cert=mtls_certs_only["client_cert"], + client_key=mtls_certs_only["client_key"], + authority=SERVICE_HOSTNAME, + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + projects = registry.list_projects() + assert len(projects) == 1 + assert projects[0].name == "test_project" + assert projects[0].description == "created by mTLS test" + finally: + registry.close() + + def test_proto_via_mtls_with_authority( + self, mtls_server: int, mtls_certs_only: dict[str, str] + ) -> None: + """Proto() is the simplest RPC — verify the channel works for it too.""" + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{mtls_server}", + cert=mtls_certs_only["ca_cert"], + client_cert=mtls_certs_only["client_cert"], + client_key=mtls_certs_only["client_key"], + authority=SERVICE_HOSTNAME, + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + proto = registry.proto() + assert proto is not None + finally: + registry.close() + + +class TestMtlsRejections: + """Verify mTLS enforcement — connections fail without proper credentials.""" + + def test_rejected_without_client_cert( + self, mtls_server: int, mtls_certs_only: dict[str, str] + ) -> None: + """Server requires mTLS; connecting with only server-TLS must fail.""" + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{mtls_server}", + cert=mtls_certs_only["ca_cert"], + is_tls=True, + authority=SERVICE_HOSTNAME, + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + with pytest.raises(grpc.RpcError): + registry.list_projects() + finally: + registry.close() + + def test_fails_without_authority_when_san_mismatch( + self, mtls_server: int, mtls_certs_only: dict[str, str] + ) -> None: + """ + Without authority override, the gRPC client checks the server cert SAN + against 'localhost' — which doesn't match — so the handshake fails. + This proves the authority field is necessary for the IAP-tunnel case. + """ + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path=f"localhost:{mtls_server}", + cert=mtls_certs_only["ca_cert"], + client_cert=mtls_certs_only["client_cert"], + client_key=mtls_certs_only["client_key"], + # No authority — should fail because SAN is SERVICE_HOSTNAME, not localhost + ) + registry = RemoteRegistry(config, project="test", repo_path=None) + try: + with pytest.raises(grpc.RpcError): + registry.list_projects() + finally: + registry.close() + + +class TestMtlsConfigValidation: + """Config validation catches mismatched cert/key before any I/O.""" + + def test_client_cert_without_client_key_raises(self) -> None: + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path="localhost:0", + cert="/dev/null", + client_cert="/dev/null", + ) + with pytest.raises( + ValueError, match="Both client_cert and client_key must be provided" + ): + RemoteRegistry(config, project="test", repo_path=None) + + def test_client_key_without_client_cert_raises(self) -> None: + from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig + + config = RemoteRegistryConfig( + registry_type="remote", + path="localhost:0", + cert="/dev/null", + client_key="/dev/null", + ) + with pytest.raises( + ValueError, match="Both client_cert and client_key must be provided" + ): + RemoteRegistry(config, project="test", repo_path=None) diff --git a/sdk/python/tests/unit/infra/registry/test_snowflake_registry.py b/sdk/python/tests/unit/infra/registry/test_snowflake_registry.py new file mode 100644 index 00000000000..f1935f329b0 --- /dev/null +++ b/sdk/python/tests/unit/infra/registry/test_snowflake_registry.py @@ -0,0 +1,330 @@ +# Copyright 2024 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest.mock import MagicMock, patch + +import pandas as pd +import pytest + +from feast.entity import Entity +from feast.infra.registry.snowflake import SnowflakeRegistry, SnowflakeRegistryConfig +from feast.infra.utils.snowflake.snowflake_utils import GetSnowflakeConnection + + +@pytest.fixture +def registry(): + config = SnowflakeRegistryConfig( + database="TEST_DB", + schema="PUBLIC", + account="test_account", + user="test_user", + password="test_password", # pragma: allowlist secret + ) + mock_conn = MagicMock() + mock_conn.__enter__ = MagicMock(return_value=MagicMock()) + mock_conn.__exit__ = MagicMock(return_value=False) + + # execute_snowflake_statement during __init__ creates tables; return empty cursor + mock_cursor = MagicMock() + mock_cursor.fetch_pandas_all.return_value = pd.DataFrame() + + with ( + patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + return_value=mock_conn, + ), + patch( + "feast.infra.registry.snowflake.execute_snowflake_statement", + return_value=mock_cursor, + ), + ): + reg = SnowflakeRegistry(config, "test_project", None) + return reg + + +def test_apply_object_update_includes_project_id_in_where_clause(registry): + """ + Regression test for feast-dev/feast#6208. + + _apply_object UPDATE path was missing project_id in the WHERE clause, + allowing a same-named object in one project to silently overwrite the + same-named object in a different project when a Snowflake registry is shared. + + The SELECT path correctly scopes by project_id; the UPDATE must do the same. + """ + entity = Entity(name="driver", join_keys=["driver_id"]) + project = "project_b" + + # Non-empty DataFrame tells _apply_object the row already exists → UPDATE path + existing_row = pd.DataFrame({"project_id": [project]}) + + captured_queries = [] + + def capture_and_respond(conn, query): + normalised = " ".join(query.split()) + captured_queries.append(normalised) + cursor = MagicMock() + cursor.fetch_pandas_all.return_value = ( + existing_row if "SELECT" in normalised else pd.DataFrame() + ) + return cursor + + mock_conn = MagicMock() + mock_conn.__enter__ = MagicMock(return_value=MagicMock()) + mock_conn.__exit__ = MagicMock(return_value=False) + + with ( + patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + return_value=mock_conn, + ), + patch( + "feast.infra.registry.snowflake.execute_snowflake_statement", + side_effect=capture_and_respond, + ), + patch.object(registry, "_maybe_init_project_metadata"), + patch.object(registry, "_initialize_project_if_not_exists"), + patch.object(registry, "get_project", return_value=MagicMock()), + patch.object(registry, "apply_project"), + patch.object(registry, "_set_last_updated_metadata"), + ): + registry._apply_object( + "ENTITIES", + project, + "ENTITY_NAME", + entity, + "ENTITY_PROTO", + ) + + update_queries = [q for q in captured_queries if q.startswith("UPDATE")] + assert len(update_queries) == 1, ( + f"Expected exactly 1 UPDATE query, got {len(update_queries)}: {update_queries}" + ) + + update_query = update_queries[0] + assert f"project_id = '{project}'" in update_query, ( + f"feast#6208: UPDATE WHERE clause is missing project_id filter — " + f"cross-project overwrites are possible in shared Snowflake registries.\n" + f"Query was: {update_query}" + ) + + +def test_apply_object_does_not_overwrite_sibling_project(registry): + """ + Cross-project isolation: applying an object in project_b must not overwrite + the same-named object in project_a when sharing a Snowflake registry. + + Regression coverage for feast-dev/feast#6208: the UPDATE path must scope by + project_id so writes in one project cannot bleed into a sibling project. + """ + entity = Entity(name="driver", join_keys=["driver_id"]) + project_a, project_b = "project_a", "project_b" + + # Simulate both projects having a pre-existing "driver" entity row + row_b = pd.DataFrame({"project_id": [project_b]}) + + update_queries = [] + + def simulated_snowflake(conn, query): + normalised = " ".join(query.split()) + cursor = MagicMock() + if "SELECT" in normalised: + # Scope the response to the project in the query; no row for project_a + if f"project_id = '{project_b}'" in normalised: + cursor.fetch_pandas_all.return_value = row_b + else: + cursor.fetch_pandas_all.return_value = pd.DataFrame() + elif "UPDATE" in normalised: + update_queries.append(normalised) + cursor.fetch_pandas_all.return_value = pd.DataFrame() + else: + cursor.fetch_pandas_all.return_value = pd.DataFrame() + return cursor + + mock_conn = MagicMock() + mock_conn.__enter__ = MagicMock(return_value=MagicMock()) + mock_conn.__exit__ = MagicMock(return_value=False) + + with ( + patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + return_value=mock_conn, + ), + patch( + "feast.infra.registry.snowflake.execute_snowflake_statement", + side_effect=simulated_snowflake, + ), + patch.object(registry, "_maybe_init_project_metadata"), + patch.object(registry, "_initialize_project_if_not_exists"), + patch.object(registry, "get_project", return_value=MagicMock()), + patch.object(registry, "apply_project"), + patch.object(registry, "_set_last_updated_metadata"), + ): + registry._apply_object( + "ENTITIES", project_b, "ENTITY_NAME", entity, "ENTITY_PROTO" + ) + + assert len(update_queries) == 1, ( + f"Expected exactly 1 UPDATE, got {len(update_queries)}: {update_queries}" + ) + update_query = update_queries[0] + assert f"project_id = '{project_b}'" in update_query, ( + f"feast#6208: UPDATE is not scoped to {project_b!r} — cross-project overwrite possible.\n" + f"Query: {update_query}" + ) + assert f"project_id = '{project_a}'" not in update_query, ( + f"feast#6208: UPDATE WHERE clause references {project_a!r} — unintended cross-project write.\n" + f"Query: {update_query}" + ) + + +class TestSyncFeastMetadataToProjectsTable: + def _make_registry(self): + """Create a SnowflakeRegistry with mocked __init__.""" + with patch.object(SnowflakeRegistry, "__init__", lambda self: None): + registry = SnowflakeRegistry() + registry.registry_config = MagicMock() + registry.registry_path = "test_db.test_schema" + registry.purge_feast_metadata = False + return registry + + @patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + ) + @patch("feast.infra.registry.snowflake.execute_snowflake_statement") + def test_sync_with_feast_metadata_projects(self, mock_execute, mock_get_conn): + registry = self._make_registry() + + metadata_df = pd.DataFrame({"PROJECT_ID": ["project_a", "project_b"]}) + projects_df = pd.DataFrame({"PROJECT_ID": ["project_a"]}) + + mock_cursor = MagicMock() + mock_cursor.fetch_pandas_all.side_effect = [metadata_df, projects_df] + mock_execute.return_value = mock_cursor + + mock_conn = MagicMock() + mock_get_conn.return_value.__enter__ = MagicMock(return_value=mock_conn) + mock_get_conn.return_value.__exit__ = MagicMock(return_value=False) + + with patch.object(registry, "apply_project") as mock_apply: + registry._sync_feast_metadata_to_projects_table() + + mock_apply.assert_called_once() + applied_project = mock_apply.call_args[0][0] + assert applied_project.name == "project_b" + + @patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + ) + @patch("feast.infra.registry.snowflake.execute_snowflake_statement") + def test_sync_with_no_feast_metadata(self, mock_execute, mock_get_conn): + registry = self._make_registry() + + empty_df = pd.DataFrame({"PROJECT_ID": []}) + mock_cursor = MagicMock() + mock_cursor.fetch_pandas_all.return_value = empty_df + mock_execute.return_value = mock_cursor + + mock_conn = MagicMock() + mock_get_conn.return_value.__enter__ = MagicMock(return_value=mock_conn) + mock_get_conn.return_value.__exit__ = MagicMock(return_value=False) + + with patch.object(registry, "apply_project") as mock_apply: + registry._sync_feast_metadata_to_projects_table() + + mock_apply.assert_not_called() + + @patch( + "feast.infra.registry.snowflake.GetSnowflakeConnection", + ) + @patch("feast.infra.registry.snowflake.execute_snowflake_statement") + def test_sync_deduplicates_project_ids(self, mock_execute, mock_get_conn): + """Sets should deduplicate project IDs; lists would not.""" + registry = self._make_registry() + + metadata_df = pd.DataFrame( + {"PROJECT_ID": ["project_a", "project_a", "project_b"]} + ) + projects_df = pd.DataFrame({"PROJECT_ID": []}) + + mock_cursor = MagicMock() + mock_cursor.fetch_pandas_all.side_effect = [metadata_df, projects_df] + mock_execute.return_value = mock_cursor + + mock_conn = MagicMock() + mock_get_conn.return_value.__enter__ = MagicMock(return_value=mock_conn) + mock_get_conn.return_value.__exit__ = MagicMock(return_value=False) + + with patch.object(registry, "apply_project") as mock_apply: + registry._sync_feast_metadata_to_projects_table() + + assert mock_apply.call_count == 2 + applied_names = {call[0][0].name for call in mock_apply.call_args_list} + assert applied_names == {"project_a", "project_b"} + + +class _DictableConfig: + """A config object that supports dict() conversion and attribute access.""" + + def __init__(self, data): + self._data = data + for k, v in data.items(): + setattr(self, k, v) + + def __iter__(self): + return iter(self._data) + + def keys(self): + return self._data.keys() + + def __getitem__(self, key): + return self._data[key] + + +class TestGetSnowflakeConnection: + @patch("feast.infra.utils.snowflake.snowflake_utils.parse_private_key_path") + @patch("feast.infra.utils.snowflake.snowflake_utils.snowflake.connector") + @patch("feast.infra.utils.snowflake.snowflake_utils._cache", {}) + def test_private_key_kwargs_not_leaked_to_connect( + self, mock_connector, mock_parse_key + ): + """private_key_passphrase and private_key_content must not be passed to connect().""" + mock_parse_key.return_value = b"parsed_key_bytes" + mock_conn = MagicMock() + mock_connector.connect.return_value = mock_conn + + config = _DictableConfig( + { + "type": "snowflake.registry", + "account": "test_account", + "user": "test_user", + "password": None, + "role": "test_role", + "warehouse": "test_wh", + "database": "test_db", + "schema_": "test_schema", + "config_path": "", + "private_key": "/path/to/key.p8", + "private_key_passphrase": "my_secret", # pragma: allowlist secret + "private_key_content": None, + } + ) + + with GetSnowflakeConnection(config): + pass + + connect_kwargs = mock_connector.connect.call_args[1] + assert "private_key_passphrase" not in connect_kwargs + assert "private_key_content" not in connect_kwargs + assert connect_kwargs["private_key"] == b"parsed_key_bytes" diff --git a/sdk/python/tests/unit/infra/registry/test_sql_registry.py b/sdk/python/tests/unit/infra/registry/test_sql_registry.py index 5f144adbaf4..1a3ec92a4a6 100644 --- a/sdk/python/tests/unit/infra/registry/test_sql_registry.py +++ b/sdk/python/tests/unit/infra/registry/test_sql_registry.py @@ -12,9 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys import tempfile +import types from datetime import timedelta +import dill import pytest from feast import Field @@ -23,7 +26,11 @@ from feast.errors import ConflictingFeatureViewNames from feast.feature_view import FeatureView from feast.infra.offline_stores.file_source import FileSource -from feast.infra.registry.sql import SqlRegistry, SqlRegistryConfig +from feast.infra.registry.sql import SqlRegistry, SqlRegistryConfig, feature_views +from feast.protos.feast.core.Transformation_pb2 import ( + FeatureTransformationV2, + UserDefinedFunctionV2, +) from feast.stream_feature_view import StreamFeatureView from feast.types import Float32 from feast.value_type import ValueType @@ -44,6 +51,13 @@ def sqlite_registry(): registry.teardown() +@pytest.fixture +def shared_sqlite_db_path(): + """Return a shared SQLite DB path for cross-project tests.""" + fd, path = tempfile.mkstemp() + yield path + + def test_sql_registry(sqlite_registry): """ Test the SQL registry @@ -105,3 +119,104 @@ def test_feature_view_name_conflict_between_stream_and_batch(sqlite_registry): with pytest.raises(ConflictingFeatureViewNames): sqlite_registry.apply_feature_view(stream_view, "test_project") + + +def _serialize_udf_referencing_module(module_name: str) -> bytes: + """Create a dill-serialized UDF that references a fake module. + + The function is defined inside a temporary module so that dill records + a dependency on that module. After serialization, the module is removed + from sys.modules so that deserializing the bytes will raise + ModuleNotFoundError. + """ + mod = types.ModuleType(module_name) + mod.__package__ = module_name + sys.modules[module_name] = mod + exec("def _udf(x): return x", mod.__dict__) + udf_bytes = dill.dumps(mod._udf) + del sys.modules[module_name] + return udf_bytes + + +def test_shared_registry_cross_project_udf_does_not_crash(shared_sqlite_db_path): + """Initializing a SqlRegistry must not crash when another project in the + same database has a feature view whose UDF references a module that is + not installed in the current environment. + + Before the fix, proto() called from_proto() on every feature view across + all projects, triggering dill.loads() which raised ModuleNotFoundError. + """ + db_url = f"sqlite:///{shared_sqlite_db_path}" + config = SqlRegistryConfig( + registry_type="sql", path=db_url, purge_feast_metadata=False + ) + + registry_a = SqlRegistry(config, "project_a", None) + + entity = Entity(name="driver", join_keys=["driver_id"]) + registry_a.apply_entity(entity, "project_a") + + file_source = FileSource( + path="driver_stats.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + fv = FeatureView( + name="driver_features", + entities=[entity], + ttl=timedelta(days=1), + schema=[Field(name="conv_rate", dtype=Float32)], + source=file_source, + ) + registry_a.apply_feature_view(fv, "project_a") + + # Inject a UDF body that references a non-existent module directly into + # the DB, simulating a feature view from another project that uses a + # module not available in this environment. + fake_udf_bytes = _serialize_udf_referencing_module("nonexistent_project_module") + + fv_proto = fv.to_proto() + fv_proto.spec.project = "project_a" + fv_proto.spec.feature_transformation.CopyFrom( + FeatureTransformationV2( + user_defined_function=UserDefinedFunctionV2( + name="fake_udf", + body=fake_udf_bytes, + body_text="def _udf(x): return x", + mode="python", + ) + ) + ) + with registry_a.write_engine.begin() as conn: + from sqlalchemy import update + + stmt = ( + update(feature_views) + .where( + feature_views.c.feature_view_name == "driver_features", + feature_views.c.project_id == "project_a", + ) + .values(feature_view_proto=fv_proto.SerializeToString()) + ) + conn.execute(stmt) + + # Creating a new SqlRegistry for project_b against the same DB should + # NOT crash even though project_a has a UDF referencing an unavailable + # module. proto() should read raw protos without deserializing UDFs. + registry_b = SqlRegistry(config, "project_b", None) + + entity_b = Entity(name="customer", join_keys=["customer_id"]) + registry_b.apply_entity(entity_b, "project_b") + retrieved = registry_b.get_entity("customer", "project_b") + assert retrieved.name == "customer" + + # Verify project_a's data is still accessible in the cached proto + proto = registry_b.proto() + project_names = [p.spec.name for p in proto.projects] + assert "project_a" in project_names + assert "project_b" in project_names + + fv_names = [fv.spec.name for fv in proto.feature_views] + assert "driver_features" in fv_names + + registry_a.teardown() diff --git a/sdk/python/tests/unit/infra/scaffolding/test_repo_operations.py b/sdk/python/tests/unit/infra/scaffolding/test_repo_operations.py index 672c8f43d96..9034f0cbcb5 100644 --- a/sdk/python/tests/unit/infra/scaffolding/test_repo_operations.py +++ b/sdk/python/tests/unit/infra/scaffolding/test_repo_operations.py @@ -28,15 +28,27 @@ def feature_repo(feastignore_contents: Optional[str]): (repo_root / "bar").mkdir() (repo_root / "bar/subdir1").mkdir() (repo_root / "bar/subdir1/subdir2").mkdir() + (repo_root / "foo/__pycache__").mkdir() + (repo_root / "foo/.pytest_cache").mkdir() + (repo_root / "foo/.ipynb_checkpoints").mkdir() + (repo_root / "bar/subdir1/.ipynb_checkpoints").mkdir() + (repo_root / "bar/subdir1/subdir2/.ipynb_checkpoints").mkdir() (repo_root / "a.py").touch() (repo_root / ".ipynb_checkpoints/test-checkpoint.py").touch() (repo_root / "foo/b.py").touch() + (repo_root / "foo/__pycache__/b.cpython.pyc").touch() + (repo_root / "foo/.pytest_cache/test-README.md").touch() + (repo_root / "foo/.ipynb_checkpoints/foo-checkpoint.py").touch() (repo_root / "foo1/c.py").touch() (repo_root / "foo1/bar/d.py").touch() (repo_root / "bar/e.py").touch() (repo_root / "bar/subdir1/f.py").touch() + (repo_root / "bar/subdir1/.ipynb_checkpoints/subdir1-checkpoint.py").touch() (repo_root / "bar/subdir1/subdir2/g.py").touch() + ( + repo_root / "bar/subdir1/subdir2/.ipynb_checkpoints/nested-checkpoint.py" + ).touch() if feastignore_contents: with open(repo_root / ".feastignore", "w") as f: @@ -80,6 +92,7 @@ def test_feastignore_no_stars(): { (repo_root / "foo/b.py").resolve(), (repo_root / "bar/subdir1/f.py").resolve(), + (repo_root / "foo/.ipynb_checkpoints/foo-checkpoint.py").resolve(), } ) assertpy.assert_that(get_repo_files(repo_root)).is_equal_to( @@ -110,6 +123,13 @@ def test_feastignore_with_stars(): { (repo_root / "foo/b.py").resolve(), (repo_root / "bar/subdir1/f.py").resolve(), + ( + repo_root + / "bar/subdir1/subdir2/.ipynb_checkpoints/nested-checkpoint.py" + ).resolve(), + ( + repo_root / "bar/subdir1/.ipynb_checkpoints/subdir1-checkpoint.py" + ).resolve(), (repo_root / "bar/e.py").resolve(), (repo_root / "bar/subdir1/f.py").resolve(), (repo_root / "bar/subdir1/subdir2/g.py").resolve(), @@ -135,6 +155,13 @@ def test_feastignore_with_stars2(): assertpy.assert_that(get_ignore_files(repo_root, ignore_paths)).is_equal_to( { (repo_root / "bar/subdir1/f.py").resolve(), + ( + repo_root + / "bar/subdir1/subdir2/.ipynb_checkpoints/nested-checkpoint.py" + ).resolve(), + ( + repo_root / "bar/subdir1/.ipynb_checkpoints/subdir1-checkpoint.py" + ).resolve(), (repo_root / "bar/e.py").resolve(), (repo_root / "bar/subdir1/f.py").resolve(), (repo_root / "bar/subdir1/subdir2/g.py").resolve(), @@ -162,12 +189,13 @@ def test_parse_repo(): repo_contents = parse_repo(repo_path) - assert len(repo_contents.data_sources) == 3 + assert len(repo_contents.data_sources) == 5 assert len(repo_contents.feature_views) == 2 assert len(repo_contents.on_demand_feature_views) == 2 assert len(repo_contents.stream_feature_views) == 0 assert len(repo_contents.entities) == 2 assert len(repo_contents.feature_services) == 3 + assert len(repo_contents.label_views) == 1 def test_parse_repo_with_future_annotations(): @@ -188,9 +216,10 @@ def test_parse_repo_with_future_annotations(): repo_contents = parse_repo(repo_path) - assert len(repo_contents.data_sources) == 3 + assert len(repo_contents.data_sources) == 5 assert len(repo_contents.feature_views) == 2 assert len(repo_contents.on_demand_feature_views) == 2 assert len(repo_contents.stream_feature_views) == 0 assert len(repo_contents.entities) == 2 assert len(repo_contents.feature_services) == 3 + assert len(repo_contents.label_views) == 1 diff --git a/sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py b/sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py index 8ae6ec63ba5..4bb02076354 100644 --- a/sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py +++ b/sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py @@ -1,11 +1,16 @@ import tempfile from typing import Optional +from unittest.mock import MagicMock, patch import pytest from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa -from feast.infra.utils.snowflake.snowflake_utils import parse_private_key_path +from feast.infra.utils.snowflake.snowflake_utils import ( + GetSnowflakeConnection, + execute_snowflake_statement, + parse_private_key_path, +) PRIVATE_KEY_PASSPHRASE = "test" @@ -69,3 +74,96 @@ def test_parse_private_key_path_key_path_encrypted(encrypted_private_key): f.name, None, ) + + +class _AttrDict(dict): + __getattr__ = dict.__getitem__ + + +def _make_config(**overrides): + defaults = { + "type": "snowflake.offline", + "account": "test_account", + "user": "test_user", + "password": "test_password", # pragma: allowlist secret + "role": "test_role", + "warehouse": "test_wh", + "database": "test_db", + "schema_": "test_schema", + "config_path": "", + } + defaults.update(overrides) + return _AttrDict(defaults) + + +@patch("feast.infra.utils.snowflake.snowflake_utils.snowflake.connector") +class TestGetSnowflakeConnectionIdentifierQuoting: + @pytest.fixture(autouse=True) + def _clear_cache(self): + with patch("feast.infra.utils.snowflake.snowflake_utils._cache", {}): + yield + + @pytest.mark.parametrize( + "config_key,connect_key,value", + [ + ("warehouse", "warehouse", "MY_WH"), + ("role", "role", "ANALYST"), + ("database", "database", "PROD_DB"), + ("schema_", "schema", "PUBLIC"), + ], + ) + def test_identifier_passed_without_quoting( + self, mock_connector, config_key, connect_key, value + ): + mock_connector.connect.return_value = MagicMock() + + with GetSnowflakeConnection(_make_config(**{config_key: value})): + pass + + kwargs = mock_connector.connect.call_args[1] + assert kwargs[connect_key] == value + + def test_schema_key_renamed_from_schema_underscore(self, mock_connector): + mock_connector.connect.return_value = MagicMock() + + with GetSnowflakeConnection(_make_config(schema_="analytics")): + pass + + kwargs = mock_connector.connect.call_args[1] + assert "schema" in kwargs + assert "schema_" not in kwargs + + +class TestExecuteSnowflakeStatement: + def test_empty_query_is_passed_through_to_execute(self): + mock_conn = MagicMock() + mock_cursor = MagicMock() + mock_executed_cursor = MagicMock() + mock_conn.cursor.return_value = mock_cursor + mock_cursor.execute.return_value = mock_executed_cursor + + result = execute_snowflake_statement(mock_conn, "") + + assert result is mock_executed_cursor + mock_cursor.execute.assert_called_once_with("") + + def test_valid_query_executes_and_returns_cursor(self): + mock_conn = MagicMock() + mock_cursor = MagicMock() + mock_executed_cursor = MagicMock() + mock_conn.cursor.return_value = mock_cursor + mock_cursor.execute.return_value = mock_executed_cursor + + result = execute_snowflake_statement(mock_conn, "SELECT 1") + + assert result is mock_executed_cursor + mock_cursor.execute.assert_called_once_with("SELECT 1") + + def test_valid_query_raises_on_none_cursor(self): + mock_conn = MagicMock() + mock_cursor = MagicMock() + mock_conn.cursor.return_value = mock_cursor + mock_cursor.execute.return_value = None + + with pytest.raises(Exception, match="Snowflake query failed"): + execute_snowflake_statement(mock_conn, "SELECT 1") diff --git a/sdk/python/tests/unit/monitoring/__init__.py b/sdk/python/tests/unit/monitoring/__init__.py new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/sdk/python/tests/unit/monitoring/__init__.py @@ -0,0 +1 @@ + diff --git a/sdk/python/tests/unit/monitoring/test_compute_correctness.py b/sdk/python/tests/unit/monitoring/test_compute_correctness.py new file mode 100644 index 00000000000..9f9005380df --- /dev/null +++ b/sdk/python/tests/unit/monitoring/test_compute_correctness.py @@ -0,0 +1,1831 @@ +""" +Compute correctness tests for monitoring metric calculations. + +Verifies that each offline store backend's SQL/compute helpers produce +mathematically correct results for a known golden dataset. + +- DuckDB and Dask tests run fully in-memory with zero external dependencies. +- PostgreSQL tests require a live Postgres instance (skipped if unavailable). +- Snowflake, BigQuery, Redshift, Spark, Oracle tests require their respective + backends (skipped if unavailable). +""" + +import statistics +from datetime import datetime, timezone +from typing import Any, Dict + +import pyarrow as pa +import pytest + +# --------------------------------------------------------------------------- +# Golden dataset: known values with hand-computable statistics +# --------------------------------------------------------------------------- + +NUMERIC_VALUES = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] +NUMERIC_WITH_NULLS = [1.0, None, 3.0, None, 5.0, None, 7.0, None, 9.0, None] +CATEGORICAL_VALUES = ["a", "b", "a", "c", "a", "b", "d", "a", "b", "c"] + +ROW_COUNT = len(NUMERIC_VALUES) +NON_NULL_VALUES = [v for v in NUMERIC_WITH_NULLS if v is not None] + + +def _expected_numeric_stats(): + """Hand-computed expected values for NUMERIC_VALUES = [1..10].""" + vals = NUMERIC_VALUES + return { + "row_count": 10, + "null_count": 0, + "null_rate": 0.0, + "mean": 5.5, + "stddev": statistics.stdev(vals), # sample stddev ≈ 3.0277 + "min_val": 1.0, + "max_val": 10.0, + "p50": 5.5, + "p75": 7.75, + "p90": 9.1, + "p95": 9.55, + "p99": 9.91, + } + + +def _expected_numeric_with_nulls_stats(): + """Hand-computed expected values for NUMERIC_WITH_NULLS.""" + vals = NON_NULL_VALUES # [1, 3, 5, 7, 9] + return { + "row_count": 10, + "null_count": 5, + "null_rate": 0.5, + "mean": 5.0, + "stddev": statistics.stdev(vals), # sample stddev ≈ 3.1623 + "min_val": 1.0, + "max_val": 9.0, + } + + +def _expected_categorical_stats(): + """Expected values for CATEGORICAL_VALUES.""" + return { + "row_count": 10, + "null_count": 0, + "null_rate": 0.0, + "unique_count": 4, + "top_value": "a", + "top_count": 4, + } + + +# --------------------------------------------------------------------------- +# Shared assertions: validate any backend's numeric/categorical result +# --------------------------------------------------------------------------- + + +def assert_numeric_correctness( + result: Dict[str, Any], expected: Dict, label: str, approx_percentiles: bool = False +): + """Assert that a numeric result from any backend matches expected values.""" + assert result["feature_type"] == "numeric", f"{label}: wrong feature_type" + assert result["row_count"] == expected["row_count"], f"{label}: wrong row_count" + assert result["null_count"] == expected["null_count"], f"{label}: wrong null_count" + assert result["null_rate"] == pytest.approx(expected["null_rate"], abs=1e-6), ( + f"{label}: wrong null_rate" + ) + assert result["mean"] == pytest.approx(expected["mean"], abs=1e-4), ( + f"{label}: wrong mean" + ) + assert result["stddev"] == pytest.approx(expected["stddev"], abs=0.05), ( + f"{label}: wrong stddev" + ) + assert result["min_val"] == pytest.approx(expected["min_val"], abs=1e-6), ( + f"{label}: wrong min_val" + ) + assert result["max_val"] == pytest.approx(expected["max_val"], abs=1e-6), ( + f"{label}: wrong max_val" + ) + + if "p50" in expected and not approx_percentiles: + assert result["p50"] == pytest.approx(expected["p50"], abs=0.5), ( + f"{label}: wrong p50" + ) + assert result["p75"] == pytest.approx(expected["p75"], abs=0.5), ( + f"{label}: wrong p75" + ) + assert result["p90"] == pytest.approx(expected["p90"], abs=0.5), ( + f"{label}: wrong p90" + ) + + # Percentile ordering is always enforced + assert result["p50"] <= result["p75"], f"{label}: p50 > p75" + assert result["p75"] <= result["p90"], f"{label}: p75 > p90" + assert result["p90"] <= result["p95"], f"{label}: p90 > p95" + assert result["p95"] <= result["p99"], f"{label}: p95 > p99" + assert result["p50"] >= result["min_val"], f"{label}: p50 < min" + assert result["p99"] <= result["max_val"], f"{label}: p99 > max" + + +def assert_histogram_correctness( + result: Dict[str, Any], label: str, expected_bins: int = 5 +): + """Assert that a numeric histogram has consistent structure and totals.""" + hist = result.get("histogram") + assert hist is not None, f"{label}: histogram is None" + assert len(hist["counts"]) == expected_bins, f"{label}: wrong number of bins" + assert len(hist["bins"]) == expected_bins + 1, f"{label}: wrong number of bin edges" + total = sum(hist["counts"]) + non_null = result["row_count"] - result["null_count"] + assert total == non_null, f"{label}: histogram total {total} != non_null {non_null}" + assert hist["bins"][0] <= result["min_val"], f"{label}: first bin edge > min_val" + assert hist["bins"][-1] >= result["max_val"], f"{label}: last bin edge < max_val" + + +def assert_categorical_correctness(result: Dict[str, Any], expected: Dict, label: str): + """Assert that a categorical result from any backend matches expected values.""" + assert result["feature_type"] == "categorical", f"{label}: wrong feature_type" + assert result["row_count"] == expected["row_count"], f"{label}: wrong row_count" + assert result["null_count"] == expected["null_count"], f"{label}: wrong null_count" + assert result["null_rate"] == pytest.approx(expected["null_rate"], abs=1e-6), ( + f"{label}: wrong null_rate" + ) + + hist = result["histogram"] + assert hist is not None, f"{label}: histogram is None" + assert hist["unique_count"] == expected["unique_count"], ( + f"{label}: wrong unique_count" + ) + + top_entry = hist["values"][0] + assert top_entry["value"] == expected["top_value"], f"{label}: wrong top value" + assert top_entry["count"] == expected["top_count"], f"{label}: wrong top count" + + total = sum(e["count"] for e in hist["values"]) + hist["other_count"] + expected_total = expected["row_count"] - expected["null_count"] + assert total == expected_total, ( + f"{label}: categorical total {total} != expected {expected_total}" + ) + + +# =================================================================== +# DuckDB compute correctness tests (fully in-memory, no external deps) +# =================================================================== + + +class TestDuckDBComputeCorrectness: + """Test DuckDB SQL helper functions produce correct metric values.""" + + @pytest.fixture(autouse=True) + def setup_duckdb(self): + duckdb = pytest.importorskip("duckdb") + self.conn = duckdb.connect() + + self.conn.execute(""" + CREATE TABLE test_data ( + event_timestamp TIMESTAMP, + numeric_col DOUBLE, + numeric_with_nulls DOUBLE, + categorical_col VARCHAR + ) + """) + + ts = datetime(2025, 1, 15, 12, 0, 0) + for i in range(ROW_COUNT): + n_val = NUMERIC_VALUES[i] + n_null = NUMERIC_WITH_NULLS[i] + c_val = CATEGORICAL_VALUES[i] + n_null_sql = f"{n_null}" if n_null is not None else "NULL" + self.conn.execute( + f"INSERT INTO test_data VALUES " + f"(TIMESTAMP '{ts.strftime('%Y-%m-%d %H:%M:%S')}', " + f"{n_val}, {n_null_sql}, '{c_val}')" + ) + yield + self.conn.close() + + def test_numeric_stats_basic(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + results = _duckdb_numeric_stats( + self.conn, + "test_data", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + result = results[0] + expected = _expected_numeric_stats() + assert_numeric_correctness(result, expected, "duckdb_numeric") + assert_histogram_correctness(result, "duckdb_numeric", expected_bins=5) + + def test_numeric_stats_with_nulls(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + results = _duckdb_numeric_stats( + self.conn, + "test_data", + ["numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + result = results[0] + expected = _expected_numeric_with_nulls_stats() + assert_numeric_correctness(result, expected, "duckdb_numeric_nulls") + assert_histogram_correctness(result, "duckdb_numeric_nulls", expected_bins=5) + + def test_numeric_multiple_features(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + results = _duckdb_numeric_stats( + self.conn, + "test_data", + ["numeric_col", "numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 2 + assert results[0]["feature_name"] == "numeric_col" + assert results[1]["feature_name"] == "numeric_with_nulls" + assert results[0]["mean"] == pytest.approx(5.5, abs=1e-4) + assert results[1]["mean"] == pytest.approx(5.0, abs=1e-4) + assert results[0]["null_count"] == 0 + assert results[1]["null_count"] == 5 + + def test_categorical_stats(self): + from feast.infra.offline_stores.duckdb import _duckdb_categorical_stats + + result = _duckdb_categorical_stats( + self.conn, + "test_data", + "categorical_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "duckdb_categorical") + + def test_categorical_top_n_truncation(self): + from feast.infra.offline_stores.duckdb import _duckdb_categorical_stats + + result = _duckdb_categorical_stats( + self.conn, + "test_data", + "categorical_col", + "1=1", + top_n=2, + ) + + assert len(result["histogram"]["values"]) == 2 + assert result["histogram"]["other_count"] > 0 + total = ( + sum(e["count"] for e in result["histogram"]["values"]) + + result["histogram"]["other_count"] + ) + assert total == 10 + + def test_histogram_bin_edges_cover_range(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_histogram + + hist = _duckdb_numeric_histogram( + self.conn, + "test_data", + "numeric_col", + "1=1", + bins=5, + min_val=1.0, + max_val=10.0, + ) + + assert hist["bins"][0] == pytest.approx(1.0, abs=1e-6) + assert hist["bins"][-1] == pytest.approx(10.0, abs=0.1) + assert sum(hist["counts"]) == 10 + assert hist["bin_width"] == pytest.approx(1.8, abs=0.01) + + def test_histogram_single_value(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_histogram + + self.conn.execute(""" + CREATE TABLE single_val (event_timestamp TIMESTAMP, v DOUBLE) + """) + self.conn.execute( + "INSERT INTO single_val VALUES (TIMESTAMP '2025-01-15 12:00:00', 42.0)" + ) + + hist = _duckdb_numeric_histogram( + self.conn, + "single_val", + "v", + "1=1", + bins=5, + min_val=42.0, + max_val=42.0, + ) + + assert hist["counts"] == [1] + assert hist["bin_width"] == 0.0 + + def test_empty_table(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + self.conn.execute(""" + CREATE TABLE empty_tbl (event_timestamp TIMESTAMP, v DOUBLE) + """) + results = _duckdb_numeric_stats( + self.conn, + "empty_tbl", + ["v"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + assert results[0]["row_count"] == 0 + assert results[0]["mean"] is None + assert results[0]["histogram"] is None + + def test_stddev_with_single_row(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + self.conn.execute(""" + CREATE TABLE one_row (event_timestamp TIMESTAMP, v DOUBLE) + """) + self.conn.execute( + "INSERT INTO one_row VALUES (TIMESTAMP '2025-01-15 12:00:00', 7.0)" + ) + results = _duckdb_numeric_stats( + self.conn, + "one_row", + ["v"], + "1=1", + histogram_bins=5, + ) + + assert results[0]["mean"] == pytest.approx(7.0) + assert results[0]["min_val"] == 7.0 + assert results[0]["max_val"] == 7.0 + # STDDEV_SAMP of a single value is NULL + assert results[0]["stddev"] is None + + def test_large_dataset_percentiles(self): + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + + self.conn.execute(""" + CREATE TABLE large_tbl (event_timestamp TIMESTAMP, v DOUBLE) + """) + for i in range(1, 1001): + self.conn.execute( + f"INSERT INTO large_tbl VALUES " + f"(TIMESTAMP '2025-01-15 12:00:00', {float(i)})" + ) + + results = _duckdb_numeric_stats( + self.conn, + "large_tbl", + ["v"], + "1=1", + histogram_bins=10, + ) + + r = results[0] + assert r["mean"] == pytest.approx(500.5, abs=0.1) + assert r["min_val"] == 1.0 + assert r["max_val"] == 1000.0 + assert r["p50"] == pytest.approx(500.5, abs=5.0) + assert r["p90"] == pytest.approx(900.0, abs=10.0) + assert r["p99"] == pytest.approx(990.0, abs=10.0) + assert_histogram_correctness(r, "duckdb_large", expected_bins=10) + + +# =================================================================== +# Dask (PyArrow) compute correctness tests (no external deps) +# =================================================================== + + +class TestDaskComputeCorrectness: + """Test Dask/PyArrow compute helpers produce correct metric values.""" + + def test_numeric_stats_basic(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + col = pa.chunked_array([pa.array(NUMERIC_VALUES, type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + expected = _expected_numeric_stats() + result["feature_name"] = "test" + assert_numeric_correctness(result, expected, "dask_numeric") + assert_histogram_correctness(result, "dask_numeric", expected_bins=5) + + def test_numeric_stats_with_nulls(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + col = pa.chunked_array([pa.array(NUMERIC_WITH_NULLS, type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=5) + result["feature_name"] = "test" + + expected = _expected_numeric_with_nulls_stats() + assert_numeric_correctness(result, expected, "dask_numeric_nulls") + assert_histogram_correctness(result, "dask_numeric_nulls", expected_bins=5) + + def test_numeric_all_nulls(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + col = pa.chunked_array([pa.array([None, None, None], type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + assert result["row_count"] == 3 + assert result["null_count"] == 3 + assert result["mean"] is None + assert result["histogram"] is None + + def test_numeric_empty(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + col = pa.chunked_array([pa.array([], type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + assert result["row_count"] == 0 + assert result["mean"] is None + + def test_numeric_single_value(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + col = pa.chunked_array([pa.array([42.0], type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + assert result["mean"] == pytest.approx(42.0) + assert result["min_val"] == 42.0 + assert result["max_val"] == 42.0 + assert result["stddev"] is None # STDDEV_SAMP of single value + + def test_numeric_large_dataset_percentiles(self): + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + + vals = list(range(1, 1001)) + col = pa.chunked_array([pa.array(vals, type=pa.float64())]) + result = _dask_compute_numeric_metrics(col, histogram_bins=10) + + assert result["mean"] == pytest.approx(500.5, abs=0.1) + assert result["p50"] == pytest.approx(500.5, abs=5.0) + assert result["p90"] == pytest.approx(900.0, abs=10.0) + assert result["p99"] == pytest.approx(990.0, abs=10.0) + result["feature_name"] = "test" + assert_histogram_correctness(result, "dask_large", expected_bins=10) + + def test_categorical_stats_basic(self): + from feast.infra.offline_stores.dask import _dask_compute_categorical_metrics + + col = pa.chunked_array([pa.array(CATEGORICAL_VALUES, type=pa.string())]) + result = _dask_compute_categorical_metrics(col, top_n=10) + result["feature_name"] = "test" + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "dask_categorical") + + def test_categorical_with_nulls(self): + from feast.infra.offline_stores.dask import _dask_compute_categorical_metrics + + vals = ["a", None, "b", None, "a", "c"] + col = pa.chunked_array([pa.array(vals, type=pa.string())]) + result = _dask_compute_categorical_metrics(col, top_n=10) + + assert result["row_count"] == 6 + assert result["null_count"] == 2 + assert result["null_rate"] == pytest.approx(1 / 3, abs=1e-4) + assert result["histogram"]["unique_count"] == 3 + + def test_categorical_top_n_truncation(self): + from feast.infra.offline_stores.dask import _dask_compute_categorical_metrics + + col = pa.chunked_array([pa.array(CATEGORICAL_VALUES, type=pa.string())]) + result = _dask_compute_categorical_metrics(col, top_n=2) + + assert len(result["histogram"]["values"]) == 2 + assert result["histogram"]["other_count"] > 0 + total = ( + sum(e["count"] for e in result["histogram"]["values"]) + + result["histogram"]["other_count"] + ) + assert total == 10 + + def test_categorical_all_nulls(self): + from feast.infra.offline_stores.dask import _dask_compute_categorical_metrics + + col = pa.chunked_array([pa.array([None, None], type=pa.string())]) + result = _dask_compute_categorical_metrics(col, top_n=10) + + assert result["null_count"] == 2 + assert result["histogram"] is None + + +# =================================================================== +# PostgreSQL compute correctness tests (requires live Postgres) +# =================================================================== + + +def _pg_available(): + try: + import psycopg # noqa: F401 + + return True + except ImportError: + return False + + +@pytest.mark.skipif(not _pg_available(), reason="psycopg not installed") +class TestPostgresComputeCorrectness: + """Test PostgreSQL SQL helpers produce correct metric values. + + Requires env vars: FEAST_PG_HOST, FEAST_PG_PORT, FEAST_PG_DB, + FEAST_PG_USER, FEAST_PG_PASS (or a local Postgres at localhost:5432). + """ + + @pytest.fixture(autouse=True) + def setup_pg(self): + import os + + import psycopg + + host = os.environ.get("FEAST_PG_HOST", "localhost") + port = os.environ.get("FEAST_PG_PORT", "5432") + db = os.environ.get("FEAST_PG_DB", "feast") + user = os.environ.get("FEAST_PG_USER", "feast") + password = os.environ.get("FEAST_PG_PASS", "feast") + + try: + self.conn = psycopg.connect( + f"host={host} port={port} dbname={db} user={user} password={password}", + autocommit=True, + ) + except psycopg.OperationalError: + pytest.skip("PostgreSQL not reachable") + + self.conn.execute("DROP TABLE IF EXISTS feast_test_monitoring_correctness") + self.conn.execute(""" + CREATE TABLE feast_test_monitoring_correctness ( + event_timestamp TIMESTAMPTZ, + numeric_col DOUBLE PRECISION, + numeric_with_nulls DOUBLE PRECISION, + categorical_col TEXT + ) + """) + + ts = datetime(2025, 1, 15, 12, 0, 0, tzinfo=timezone.utc) + for i in range(ROW_COUNT): + n_val = NUMERIC_VALUES[i] + n_null = NUMERIC_WITH_NULLS[i] + c_val = CATEGORICAL_VALUES[i] + self.conn.execute( + "INSERT INTO feast_test_monitoring_correctness VALUES (%s, %s, %s, %s)", + (ts, n_val, n_null, c_val), + ) + yield + self.conn.execute("DROP TABLE IF EXISTS feast_test_monitoring_correctness") + self.conn.close() + + def test_numeric_stats(self): + from feast.infra.offline_stores.contrib.postgres_offline_store.postgres import ( + _sql_numeric_stats, + ) + + results = _sql_numeric_stats( + self.conn, + "feast_test_monitoring_correctness", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + expected = _expected_numeric_stats() + assert_numeric_correctness(results[0], expected, "pg_numeric") + assert_histogram_correctness(results[0], "pg_numeric", expected_bins=5) + + def test_numeric_stats_with_nulls(self): + from feast.infra.offline_stores.contrib.postgres_offline_store.postgres import ( + _sql_numeric_stats, + ) + + results = _sql_numeric_stats( + self.conn, + "feast_test_monitoring_correctness", + ["numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + expected = _expected_numeric_with_nulls_stats() + assert_numeric_correctness(results[0], expected, "pg_numeric_nulls") + + def test_numeric_multiple_features(self): + from feast.infra.offline_stores.contrib.postgres_offline_store.postgres import ( + _sql_numeric_stats, + ) + + results = _sql_numeric_stats( + self.conn, + "feast_test_monitoring_correctness", + ["numeric_col", "numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 2 + assert results[0]["mean"] == pytest.approx(5.5, abs=1e-4) + assert results[1]["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_stats(self): + from feast.infra.offline_stores.contrib.postgres_offline_store.postgres import ( + _sql_categorical_stats, + ) + + result = _sql_categorical_stats( + self.conn, + "feast_test_monitoring_correctness", + "categorical_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "pg_categorical") + + +# =================================================================== +# Snowflake compute correctness (mocked connection, real parsing) +# =================================================================== + + +def _snowflake_importable(): + try: + from feast.infra.offline_stores.snowflake import ( + _snowflake_sql_numeric_stats, # noqa: F401 + ) + + return True + except (ImportError, Exception): + return False + + +@pytest.mark.skipif(not _snowflake_importable(), reason="Snowflake deps not installed") +class TestSnowflakeComputeCorrectness: + """Tests Snowflake result parsing with mocked cursor. + + The cursor returns exactly the row format Snowflake would produce. + This validates column indexing, opt_float, null_count math, and + histogram assembly without needing a live Snowflake account. + """ + + def _make_mock_cursor(self, fetchone_val=None, fetchall_val=None): + from unittest.mock import MagicMock + + cursor = MagicMock() + cursor.fetchone.return_value = fetchone_val + cursor.fetchall.return_value = fetchall_val or [] + return cursor + + def test_numeric_stats(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.snowflake import ( + _snowflake_sql_numeric_stats, + ) + + vals = NUMERIC_VALUES + mean_v = statistics.mean(vals) + stddev_v = statistics.stdev(vals) + # row: COUNT(*), then per-feature: nn, avg, stddev, min, max, p50..p99 + stats_row = ( + 10, + 10, + mean_v, + stddev_v, + 1.0, + 10.0, + 5.5, + 7.75, + 9.1, + 9.55, + 9.91, + ) + stats_cursor = self._make_mock_cursor(fetchone_val=stats_row) + hist_row_data = [(1, 2), (2, 2), (3, 2), (4, 2), (5, 2)] + hist_cursor = self._make_mock_cursor(fetchall_val=hist_row_data) + + call_count = [0] + + def mock_execute(conn, query): + call_count[0] += 1 + return stats_cursor if call_count[0] == 1 else hist_cursor + + with patch( + "feast.infra.offline_stores.snowflake.execute_snowflake_statement", + side_effect=mock_execute, + ): + results = _snowflake_sql_numeric_stats( + MagicMock(), + "test_table", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + r = results[0] + expected = _expected_numeric_stats() + assert_numeric_correctness(r, expected, "snowflake_numeric") + assert r["histogram"] is not None + assert sum(r["histogram"]["counts"]) == 10 + + def test_numeric_stats_with_nulls(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.snowflake import ( + _snowflake_sql_numeric_stats, + ) + + vals = NON_NULL_VALUES + stats_row = ( + 10, + 5, + statistics.mean(vals), + statistics.stdev(vals), + 1.0, + 9.0, + 5.0, + 7.0, + 8.6, + 8.8, + 8.96, + ) + stats_cursor = self._make_mock_cursor(fetchone_val=stats_row) + hist_cursor = self._make_mock_cursor( + fetchall_val=[(1, 1), (2, 1), (3, 1), (4, 1), (5, 1)] + ) + + call_count = [0] + + def mock_execute(conn, query): + call_count[0] += 1 + return stats_cursor if call_count[0] == 1 else hist_cursor + + with patch( + "feast.infra.offline_stores.snowflake.execute_snowflake_statement", + side_effect=mock_execute, + ): + results = _snowflake_sql_numeric_stats( + MagicMock(), + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + r = results[0] + assert r["null_count"] == 5 + assert r["null_rate"] == pytest.approx(0.5) + assert r["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_stats(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.snowflake import ( + _snowflake_sql_categorical_stats, + ) + + rows = [ + (10, 0, 4, "a", 4), + (10, 0, 4, "b", 3), + (10, 0, 4, "c", 2), + (10, 0, 4, "d", 1), + ] + cursor = self._make_mock_cursor(fetchall_val=rows) + + with patch( + "feast.infra.offline_stores.snowflake.execute_snowflake_statement", + return_value=cursor, + ): + result = _snowflake_sql_categorical_stats( + MagicMock(), + "t", + "cat_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "snowflake_categorical") + + def test_empty_result(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.snowflake import ( + _snowflake_sql_numeric_stats, + ) + + cursor = self._make_mock_cursor(fetchone_val=None) + with patch( + "feast.infra.offline_stores.snowflake.execute_snowflake_statement", + return_value=cursor, + ): + results = _snowflake_sql_numeric_stats( + MagicMock(), + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + assert results[0]["mean"] is None + assert results[0]["row_count"] == 0 + + +# =================================================================== +# BigQuery compute correctness (mocked client, real parsing) +# =================================================================== + + +class TestBigQueryComputeCorrectness: + """Tests BigQuery result parsing with mocked client. + + BigQuery results use dict-like row access (row["column_name"]). + """ + + def _make_mock_bq_row(self, data: dict): + """Create an object supporting both dict-key and index access.""" + + class BQRow: + def __init__(self, d): + self._data = d + self._keys = list(d.keys()) + + def __getitem__(self, key): + if isinstance(key, int): + return self._data[self._keys[key]] + return self._data[key] + + return BQRow(data) + + def _make_mock_job(self, rows): + from unittest.mock import MagicMock + + job = MagicMock() + job.result.return_value = None + job.__iter__ = lambda self_: iter(rows) + return job + + def test_numeric_stats(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.bigquery import _bq_numeric_stats + + vals = NUMERIC_VALUES + row_data = { + "_row_count": 10, + "c0_nn": 10, + "c0_avg": statistics.mean(vals), + "c0_stddev": statistics.stdev(vals), + "c0_min": 1.0, + "c0_max": 10.0, + "c0_p50": 5.5, + "c0_p75": 7.75, + "c0_p90": 9.1, + "c0_p95": 9.55, + "c0_p99": 9.91, + } + stats_row = self._make_mock_bq_row(row_data) + stats_job = self._make_mock_job([stats_row]) + + hist_rows = [ + self._make_mock_bq_row({"bucket": i + 1, "cnt": 2}) for i in range(5) + ] + hist_job = self._make_mock_job(hist_rows) + + call_count = [0] + + def mock_query(sql, *args, **kwargs): + call_count[0] += 1 + return stats_job if call_count[0] == 1 else hist_job + + mock_config = MagicMock() + mock_config.offline_store.billing_project_id = "proj" + mock_config.offline_store.project_id = "proj" + mock_config.offline_store.location = "US" + + with patch( + "feast.infra.offline_stores.bigquery._get_bigquery_client" + ) as mock_client: + mock_client.return_value.query = mock_query + results = _bq_numeric_stats( + mock_config, + "test_table", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + r = results[0] + expected = _expected_numeric_stats() + assert_numeric_correctness(r, expected, "bq_numeric") + assert r["histogram"] is not None + assert sum(r["histogram"]["counts"]) == 10 + + def test_numeric_stats_with_nulls(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.bigquery import _bq_numeric_stats + + vals = NON_NULL_VALUES + row_data = { + "_row_count": 10, + "c0_nn": 5, + "c0_avg": statistics.mean(vals), + "c0_stddev": statistics.stdev(vals), + "c0_min": 1.0, + "c0_max": 9.0, + "c0_p50": 5.0, + "c0_p75": 7.0, + "c0_p90": 8.6, + "c0_p95": 8.8, + "c0_p99": 8.96, + } + stats_row = self._make_mock_bq_row(row_data) + stats_job = self._make_mock_job([stats_row]) + hist_job = self._make_mock_job( + [self._make_mock_bq_row({"bucket": i + 1, "cnt": 1}) for i in range(5)] + ) + + call_count = [0] + + def mock_query(sql, *args, **kwargs): + call_count[0] += 1 + return stats_job if call_count[0] == 1 else hist_job + + mock_config = MagicMock() + mock_config.offline_store.billing_project_id = "proj" + mock_config.offline_store.project_id = "proj" + mock_config.offline_store.location = "US" + + with patch( + "feast.infra.offline_stores.bigquery._get_bigquery_client" + ) as mock_client: + mock_client.return_value.query = mock_query + results = _bq_numeric_stats( + mock_config, + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + r = results[0] + assert r["null_count"] == 5 + assert r["null_rate"] == pytest.approx(0.5) + assert r["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_stats(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.bigquery import _bq_categorical_stats + + rows = [ + self._make_mock_bq_row( + { + "row_count": 10, + "null_count": 0, + "unique_count": 4, + "value": "a", + "cnt": 4, + } + ), + self._make_mock_bq_row( + { + "row_count": 10, + "null_count": 0, + "unique_count": 4, + "value": "b", + "cnt": 3, + } + ), + self._make_mock_bq_row( + { + "row_count": 10, + "null_count": 0, + "unique_count": 4, + "value": "c", + "cnt": 2, + } + ), + self._make_mock_bq_row( + { + "row_count": 10, + "null_count": 0, + "unique_count": 4, + "value": "d", + "cnt": 1, + } + ), + ] + job = self._make_mock_job(rows) + + mock_config = MagicMock() + mock_config.offline_store.billing_project_id = "proj" + mock_config.offline_store.project_id = "proj" + mock_config.offline_store.location = "US" + + with patch( + "feast.infra.offline_stores.bigquery._get_bigquery_client" + ) as mock_client: + mock_client.return_value.query.return_value = job + result = _bq_categorical_stats( + mock_config, + "t", + "cat_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "bq_categorical") + + def test_multiple_features(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.bigquery import _bq_numeric_stats + + row_data = { + "_row_count": 10, + "c0_nn": 10, + "c0_avg": 5.5, + "c0_stddev": 3.03, + "c0_min": 1.0, + "c0_max": 10.0, + "c0_p50": 5.5, + "c0_p75": 7.75, + "c0_p90": 9.1, + "c0_p95": 9.55, + "c0_p99": 9.91, + "c1_nn": 5, + "c1_avg": 5.0, + "c1_stddev": 3.16, + "c1_min": 1.0, + "c1_max": 9.0, + "c1_p50": 5.0, + "c1_p75": 7.0, + "c1_p90": 8.6, + "c1_p95": 8.8, + "c1_p99": 8.96, + } + stats_job = self._make_mock_job([self._make_mock_bq_row(row_data)]) + hist_job = self._make_mock_job( + [self._make_mock_bq_row({"bucket": i + 1, "cnt": 2}) for i in range(5)] + ) + + call_count = [0] + + def mock_query(sql, *args, **kwargs): + call_count[0] += 1 + return stats_job if call_count[0] == 1 else hist_job + + mock_config = MagicMock() + mock_config.offline_store.billing_project_id = "p" + mock_config.offline_store.project_id = "p" + mock_config.offline_store.location = "US" + + with patch( + "feast.infra.offline_stores.bigquery._get_bigquery_client" + ) as mock_client: + mock_client.return_value.query = mock_query + results = _bq_numeric_stats( + mock_config, + "t", + ["col_a", "col_b"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 2 + assert results[0]["mean"] == pytest.approx(5.5, abs=1e-2) + assert results[1]["mean"] == pytest.approx(5.0, abs=1e-2) + assert results[0]["null_count"] == 0 + assert results[1]["null_count"] == 5 + + +# =================================================================== +# Redshift compute correctness (mocked Data API, real parsing) +# =================================================================== + + +class TestRedshiftComputeCorrectness: + """Tests Redshift result parsing with mocked _redshift_execute_fetch_rows. + + Redshift Data API returns rows as lists of field dicts, e.g. + [{"longValue": 10}, {"doubleValue": 5.5}, ...]. + """ + + def _long(self, v): + return {"longValue": v} + + def _double(self, v): + return {"doubleValue": v} + + def _string(self, v): + return {"stringValue": v} + + def _null(self): + return {"isNull": True} + + def test_numeric_stats(self): + from unittest.mock import patch + + from feast.infra.offline_stores.redshift import ( + _redshift_sql_numeric_stats, + ) + + vals = NUMERIC_VALUES + row = [ + self._long(10), # COUNT(*) + self._long(10), # COUNT(col) + self._double(statistics.mean(vals)), # AVG + self._double(statistics.stdev(vals)), # STDDEV_SAMP + self._double(1.0), # MIN + self._double(10.0), # MAX + self._double(5.5), # p50 + self._double(7.75), # p75 + self._double(9.1), # p90 + self._double(9.55), # p95 + self._double(9.91), # p99 + ] + hist_rows = [[self._long(i + 1), self._long(2)] for i in range(5)] + + call_count = [0] + + def mock_fetch(config, sql): + call_count[0] += 1 + return [row] if call_count[0] == 1 else hist_rows + + with patch( + "feast.infra.offline_stores.redshift._redshift_execute_fetch_rows", + side_effect=mock_fetch, + ): + from unittest.mock import MagicMock + + results = _redshift_sql_numeric_stats( + MagicMock(), + "test_table", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + r = results[0] + expected = _expected_numeric_stats() + assert_numeric_correctness(r, expected, "redshift_numeric") + assert r["histogram"] is not None + assert sum(r["histogram"]["counts"]) == 10 + + def test_numeric_stats_with_nulls(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.redshift import ( + _redshift_sql_numeric_stats, + ) + + vals = NON_NULL_VALUES + row = [ + self._long(10), + self._long(5), + self._double(statistics.mean(vals)), + self._double(statistics.stdev(vals)), + self._double(1.0), + self._double(9.0), + self._double(5.0), + self._double(7.0), + self._double(8.6), + self._double(8.8), + self._double(8.96), + ] + hist_rows = [[self._long(i + 1), self._long(1)] for i in range(5)] + + call_count = [0] + + def mock_fetch(config, sql): + call_count[0] += 1 + return [row] if call_count[0] == 1 else hist_rows + + with patch( + "feast.infra.offline_stores.redshift._redshift_execute_fetch_rows", + side_effect=mock_fetch, + ): + results = _redshift_sql_numeric_stats( + MagicMock(), + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + r = results[0] + assert r["null_count"] == 5 + assert r["null_rate"] == pytest.approx(0.5) + assert r["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_stats(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.redshift import ( + _redshift_sql_categorical_stats, + ) + + rows = [ + [ + self._long(10), + self._long(0), + self._long(4), + self._string("a"), + self._long(4), + ], + [ + self._long(10), + self._long(0), + self._long(4), + self._string("b"), + self._long(3), + ], + [ + self._long(10), + self._long(0), + self._long(4), + self._string("c"), + self._long(2), + ], + [ + self._long(10), + self._long(0), + self._long(4), + self._string("d"), + self._long(1), + ], + ] + + with patch( + "feast.infra.offline_stores.redshift._redshift_execute_fetch_rows", + return_value=rows, + ): + result = _redshift_sql_categorical_stats( + MagicMock(), + "t", + "cat_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "redshift_categorical") + + def test_empty_result(self): + from unittest.mock import MagicMock, patch + + from feast.infra.offline_stores.redshift import ( + _redshift_sql_numeric_stats, + ) + + with patch( + "feast.infra.offline_stores.redshift._redshift_execute_fetch_rows", + return_value=[], + ): + results = _redshift_sql_numeric_stats( + MagicMock(), + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + assert results[0]["mean"] is None + assert results[0]["row_count"] == 0 + + +# =================================================================== +# Spark compute correctness tests (requires SparkSession) +# =================================================================== + + +def _spark_available(): + try: + from pyspark.sql import SparkSession # noqa: F401 + + return True + except ImportError: + return False + + +@pytest.mark.skipif(not _spark_available(), reason="PySpark not installed") +class TestSparkComputeCorrectness: + """Test Spark SQL helpers produce correct metric values. + + Uses a local SparkSession — no external cluster required. + """ + + @pytest.fixture(autouse=True) + def setup_spark(self): + from pyspark.sql import SparkSession + from pyspark.sql.types import ( + DoubleType, + StringType, + StructField, + StructType, + TimestampType, + ) + + try: + self.spark = ( + SparkSession.builder.master("local[1]") + .appName("feast_monitoring_test") + .config("spark.ui.enabled", "false") + .config("spark.driver.bindAddress", "127.0.0.1") + .getOrCreate() + ) + except Exception as e: + pytest.skip(f"SparkSession unavailable: {e}") + + schema = StructType( + [ + StructField("event_timestamp", TimestampType(), False), + StructField("numeric_col", DoubleType(), True), + StructField("numeric_with_nulls", DoubleType(), True), + StructField("categorical_col", StringType(), True), + ] + ) + + ts = datetime(2025, 1, 15, 12, 0, 0) + rows = [ + (ts, NUMERIC_VALUES[i], NUMERIC_WITH_NULLS[i], CATEGORICAL_VALUES[i]) + for i in range(ROW_COUNT) + ] + df = self.spark.createDataFrame(rows, schema) + df.createOrReplaceTempView("feast_test_monitoring") + + yield + self.spark.sql("DROP VIEW IF EXISTS feast_test_monitoring") + + def test_numeric_stats(self): + from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _spark_sql_numeric_stats, + ) + + results = _spark_sql_numeric_stats( + self.spark, + "feast_test_monitoring", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + expected = _expected_numeric_stats() + assert_numeric_correctness( + results[0], + expected, + "spark_numeric", + approx_percentiles=True, + ) + assert results[0]["histogram"] is not None + assert sum(results[0]["histogram"]["counts"]) == 10 + + def test_numeric_stats_with_nulls(self): + from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _spark_sql_numeric_stats, + ) + + results = _spark_sql_numeric_stats( + self.spark, + "feast_test_monitoring", + ["numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + expected = _expected_numeric_with_nulls_stats() + assert_numeric_correctness( + results[0], + expected, + "spark_numeric_nulls", + approx_percentiles=True, + ) + + def test_categorical_stats(self): + from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _spark_sql_categorical_stats, + ) + + result = _spark_sql_categorical_stats( + self.spark, + "feast_test_monitoring", + "categorical_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "spark_categorical") + + def test_numeric_multiple_features(self): + from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _spark_sql_numeric_stats, + ) + + results = _spark_sql_numeric_stats( + self.spark, + "feast_test_monitoring", + ["numeric_col", "numeric_with_nulls"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 2 + assert results[0]["mean"] == pytest.approx(5.5, abs=1e-4) + assert results[1]["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_top_n_truncation(self): + from feast.infra.offline_stores.contrib.spark_offline_store.spark import ( + _spark_sql_categorical_stats, + ) + + result = _spark_sql_categorical_stats( + self.spark, + "feast_test_monitoring", + "categorical_col", + "1=1", + top_n=2, + ) + + assert len(result["histogram"]["values"]) == 2 + assert result["histogram"]["other_count"] > 0 + total = ( + sum(e["count"] for e in result["histogram"]["values"]) + + result["histogram"]["other_count"] + ) + assert total == 10 + + +# =================================================================== +# Oracle compute correctness (mocked Ibis connection, real parsing) +# =================================================================== + + +def _oracle_importable(): + try: + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_numeric_stats, # noqa: F401 + ) + + return True + except ImportError: + return False + + +@pytest.mark.skipif(not _oracle_importable(), reason="Oracle deps not installed") +class TestOracleComputeCorrectness: + """Tests Oracle result parsing with mocked Ibis connection. + + _oracle_fetchall returns list of tuples (positional indexing). + """ + + def test_numeric_stats(self): + from unittest.mock import patch + + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_numeric_stats, + ) + + vals = NUMERIC_VALUES + row = ( + 10, + 10, + statistics.mean(vals), + statistics.stdev(vals), + 1.0, + 10.0, + 5.5, + 7.75, + 9.1, + 9.55, + 9.91, + ) + hist_rows = [(i + 1, 2) for i in range(5)] + + call_count = [0] + + def mock_fetchall(con, sql): + call_count[0] += 1 + return [row] if call_count[0] == 1 else hist_rows + + with patch( + "feast.infra.offline_stores.contrib.oracle_offline_store.oracle._oracle_fetchall", + side_effect=mock_fetchall, + ): + results = _oracle_numeric_stats( + None, + "test_table", + ["numeric_col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + r = results[0] + expected = _expected_numeric_stats() + assert_numeric_correctness(r, expected, "oracle_numeric") + assert r["histogram"] is not None + assert sum(r["histogram"]["counts"]) == 10 + + def test_numeric_stats_with_nulls(self): + from unittest.mock import patch + + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_numeric_stats, + ) + + vals = NON_NULL_VALUES + row = ( + 10, + 5, + statistics.mean(vals), + statistics.stdev(vals), + 1.0, + 9.0, + 5.0, + 7.0, + 8.6, + 8.8, + 8.96, + ) + hist_rows = [(i + 1, 1) for i in range(5)] + + call_count = [0] + + def mock_fetchall(con, sql): + call_count[0] += 1 + return [row] if call_count[0] == 1 else hist_rows + + with patch( + "feast.infra.offline_stores.contrib.oracle_offline_store.oracle._oracle_fetchall", + side_effect=mock_fetchall, + ): + results = _oracle_numeric_stats( + None, + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + r = results[0] + assert r["null_count"] == 5 + assert r["null_rate"] == pytest.approx(0.5) + assert r["mean"] == pytest.approx(5.0, abs=1e-4) + + def test_categorical_stats(self): + from unittest.mock import patch + + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_categorical_stats, + ) + + rows = [ + (10, 0, 4, "a", 4), + (10, 0, 4, "b", 3), + (10, 0, 4, "c", 2), + (10, 0, 4, "d", 1), + ] + + with patch( + "feast.infra.offline_stores.contrib.oracle_offline_store.oracle._oracle_fetchall", + return_value=rows, + ): + result = _oracle_categorical_stats( + None, + "t", + "cat_col", + "1=1", + top_n=10, + ) + + expected = _expected_categorical_stats() + assert_categorical_correctness(result, expected, "oracle_categorical") + + def test_empty_result(self): + from unittest.mock import patch + + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_numeric_stats, + ) + + with patch( + "feast.infra.offline_stores.contrib.oracle_offline_store.oracle._oracle_fetchall", + return_value=[None], + ): + results = _oracle_numeric_stats( + None, + "t", + ["col"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 1 + assert results[0]["mean"] is None + assert results[0]["row_count"] == 0 + + def test_multiple_features(self): + from unittest.mock import patch + + from feast.infra.offline_stores.contrib.oracle_offline_store.oracle import ( + _oracle_numeric_stats, + ) + + row = ( + 10, + # Feature 0: numeric_col + 10, + 5.5, + 3.03, + 1.0, + 10.0, + 5.5, + 7.75, + 9.1, + 9.55, + 9.91, + # Feature 1: numeric_with_nulls + 5, + 5.0, + 3.16, + 1.0, + 9.0, + 5.0, + 7.0, + 8.6, + 8.8, + 8.96, + ) + hist_rows = [(i + 1, 2) for i in range(5)] + + call_count = [0] + + def mock_fetchall(con, sql): + call_count[0] += 1 + return [row] if call_count[0] == 1 else hist_rows + + with patch( + "feast.infra.offline_stores.contrib.oracle_offline_store.oracle._oracle_fetchall", + side_effect=mock_fetchall, + ): + results = _oracle_numeric_stats( + None, + "t", + ["col_a", "col_b"], + "1=1", + histogram_bins=5, + ) + + assert len(results) == 2 + assert results[0]["mean"] == pytest.approx(5.5, abs=1e-2) + assert results[1]["mean"] == pytest.approx(5.0, abs=1e-2) + assert results[0]["null_count"] == 0 + assert results[1]["null_count"] == 5 + + +# =================================================================== +# Cross-backend consistency: MetricsCalculator vs DuckDB vs Dask +# =================================================================== + + +class TestCrossBackendConsistency: + """Verify that DuckDB, Dask, and MetricsCalculator produce + consistent results for the same dataset.""" + + def test_numeric_mean_matches_across_backends(self): + duckdb = pytest.importorskip("duckdb") + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + from feast.monitoring.metrics_calculator import MetricsCalculator + + calc = MetricsCalculator(histogram_bins=5, top_n=10) + arr = pa.array(NUMERIC_VALUES, type=pa.float64()) + pyarrow_result = calc.compute_numeric(arr) + + col = pa.chunked_array([arr]) + dask_result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + conn = duckdb.connect() + conn.execute("CREATE TABLE consistency_test (v DOUBLE)") + for v in NUMERIC_VALUES: + conn.execute(f"INSERT INTO consistency_test VALUES ({v})") + + duckdb_results = _duckdb_numeric_stats( + conn, + "consistency_test", + ["v"], + "1=1", + histogram_bins=5, + ) + conn.close() + + duckdb_result = duckdb_results[0] + + assert pyarrow_result["mean"] == pytest.approx(dask_result["mean"], abs=1e-6) + assert pyarrow_result["mean"] == pytest.approx(duckdb_result["mean"], abs=1e-6) + assert dask_result["mean"] == pytest.approx(duckdb_result["mean"], abs=1e-6) + + assert pyarrow_result["stddev"] == pytest.approx( + dask_result["stddev"], abs=0.01 + ) + assert pyarrow_result["stddev"] == pytest.approx( + duckdb_result["stddev"], abs=0.01 + ) + + assert pyarrow_result["min_val"] == dask_result["min_val"] + assert pyarrow_result["min_val"] == duckdb_result["min_val"] + assert pyarrow_result["max_val"] == dask_result["max_val"] + assert pyarrow_result["max_val"] == duckdb_result["max_val"] + + def test_categorical_unique_count_matches(self): + duckdb = pytest.importorskip("duckdb") + from feast.infra.offline_stores.dask import ( + _dask_compute_categorical_metrics, + ) + from feast.infra.offline_stores.duckdb import _duckdb_categorical_stats + from feast.monitoring.metrics_calculator import MetricsCalculator + + calc = MetricsCalculator(histogram_bins=5, top_n=10) + arr = pa.array(CATEGORICAL_VALUES, type=pa.string()) + pyarrow_result = calc.compute_categorical(arr) + + col = pa.chunked_array([arr]) + dask_result = _dask_compute_categorical_metrics(col, top_n=10) + + conn = duckdb.connect() + conn.execute("CREATE TABLE cat_consistency (v VARCHAR)") + for v in CATEGORICAL_VALUES: + conn.execute(f"INSERT INTO cat_consistency VALUES ('{v}')") + + duckdb_result = _duckdb_categorical_stats( + conn, + "cat_consistency", + "v", + "1=1", + top_n=10, + ) + conn.close() + + assert ( + pyarrow_result["histogram"]["unique_count"] + == dask_result["histogram"]["unique_count"] + == duckdb_result["histogram"]["unique_count"] + == 4 + ) + + pyarrow_top = pyarrow_result["histogram"]["values"][0] + dask_top = dask_result["histogram"]["values"][0] + duckdb_top = duckdb_result["histogram"]["values"][0] + assert pyarrow_top["value"] == dask_top["value"] == duckdb_top["value"] == "a" + assert pyarrow_top["count"] == dask_top["count"] == duckdb_top["count"] == 4 + + def test_null_rate_matches_across_backends(self): + duckdb = pytest.importorskip("duckdb") + from feast.infra.offline_stores.dask import _dask_compute_numeric_metrics + from feast.infra.offline_stores.duckdb import _duckdb_numeric_stats + from feast.monitoring.metrics_calculator import MetricsCalculator + + calc = MetricsCalculator(histogram_bins=5, top_n=10) + arr = pa.array(NUMERIC_WITH_NULLS, type=pa.float64()) + pyarrow_result = calc.compute_numeric(arr) + + col = pa.chunked_array([arr]) + dask_result = _dask_compute_numeric_metrics(col, histogram_bins=5) + + conn = duckdb.connect() + conn.execute("CREATE TABLE null_consistency (v DOUBLE)") + for v in NUMERIC_WITH_NULLS: + val = f"{v}" if v is not None else "NULL" + conn.execute(f"INSERT INTO null_consistency VALUES ({val})") + + duckdb_results = _duckdb_numeric_stats( + conn, + "null_consistency", + ["v"], + "1=1", + histogram_bins=5, + ) + conn.close() + + assert pyarrow_result["null_rate"] == pytest.approx(0.5, abs=1e-6) + assert dask_result["null_rate"] == pytest.approx(0.5, abs=1e-6) + assert duckdb_results[0]["null_rate"] == pytest.approx(0.5, abs=1e-6) diff --git a/sdk/python/tests/unit/monitoring/test_metrics_calculator.py b/sdk/python/tests/unit/monitoring/test_metrics_calculator.py new file mode 100644 index 00000000000..8124531d765 --- /dev/null +++ b/sdk/python/tests/unit/monitoring/test_metrics_calculator.py @@ -0,0 +1,289 @@ +import json +import math + +import pyarrow as pa +import pytest + +from feast.monitoring.metrics_calculator import MetricsCalculator +from feast.monitoring.monitoring_utils import opt_float +from feast.types import PrimitiveFeastType + + +def _make_calc(bins=20, top_n=10): + return MetricsCalculator(histogram_bins=bins, top_n=top_n) + + +class TestClassifyFeature: + @pytest.mark.parametrize( + "dtype, expected", + [ + (PrimitiveFeastType.INT32, "numeric"), + (PrimitiveFeastType.INT64, "numeric"), + (PrimitiveFeastType.FLOAT32, "numeric"), + (PrimitiveFeastType.FLOAT64, "numeric"), + (PrimitiveFeastType.STRING, "categorical"), + (PrimitiveFeastType.BOOL, "categorical"), + (PrimitiveFeastType.BYTES, None), + (PrimitiveFeastType.UNIX_TIMESTAMP, None), + ], + ) + def test_classification(self, dtype, expected): + assert MetricsCalculator.classify_feature(dtype) == expected + + +class TestComputeNumeric: + def test_basic_stats(self): + calc = _make_calc() + arr = pa.array([1.0, 2.0, 3.0, 4.0, 5.0]) + result = calc.compute_numeric(arr) + + assert result["feature_type"] == "numeric" + assert result["row_count"] == 5 + assert result["null_count"] == 0 + assert result["null_rate"] == 0.0 + assert result["mean"] == pytest.approx(3.0) + assert result["min_val"] == 1.0 + assert result["max_val"] == 5.0 + assert result["p50"] is not None + assert result["histogram"] is not None + assert "bins" in result["histogram"] + assert "counts" in result["histogram"] + + def test_with_nulls(self): + calc = _make_calc() + arr = pa.array([1.0, None, 3.0, None, 5.0]) + result = calc.compute_numeric(arr) + + assert result["row_count"] == 5 + assert result["null_count"] == 2 + assert result["null_rate"] == pytest.approx(0.4) + assert result["mean"] == pytest.approx(3.0) + + def test_all_nulls(self): + calc = _make_calc() + arr = pa.array([None, None, None], type=pa.float64()) + result = calc.compute_numeric(arr) + + assert result["null_count"] == 3 + assert result["mean"] is None + assert result["histogram"] is None + + def test_empty_array(self): + calc = _make_calc() + arr = pa.array([], type=pa.float64()) + result = calc.compute_numeric(arr) + + assert result["row_count"] == 0 + assert result["null_rate"] == 0.0 + + def test_single_value(self): + calc = _make_calc() + arr = pa.array([42.0]) + result = calc.compute_numeric(arr) + + assert result["mean"] == 42.0 + assert result["min_val"] == 42.0 + assert result["max_val"] == 42.0 + assert result["stddev"] is None # STDDEV_SAMP of 1 value is NaN → None + + def test_histogram_bin_count(self): + calc = _make_calc(bins=5) + arr = pa.array(list(range(100)), type=pa.float64()) + result = calc.compute_numeric(arr) + + assert len(result["histogram"]["counts"]) == 5 + assert len(result["histogram"]["bins"]) == 6 + + def test_percentiles_order(self): + calc = _make_calc() + arr = pa.array(list(range(1000)), type=pa.float64()) + result = calc.compute_numeric(arr) + + assert result["p50"] <= result["p75"] + assert result["p75"] <= result["p90"] + assert result["p90"] <= result["p95"] + assert result["p95"] <= result["p99"] + + +class TestComputeCategorical: + def test_basic(self): + calc = _make_calc() + arr = pa.array(["a", "b", "a", "c", "a", "b"]) + result = calc.compute_categorical(arr) + + assert result["feature_type"] == "categorical" + assert result["row_count"] == 6 + assert result["null_count"] == 0 + assert result["histogram"] is not None + assert result["histogram"]["unique_count"] == 3 + + top_values = {v["value"] for v in result["histogram"]["values"]} + assert "a" in top_values + + def test_with_nulls(self): + calc = _make_calc() + arr = pa.array(["a", None, "b", None]) + result = calc.compute_categorical(arr) + + assert result["null_count"] == 2 + assert result["null_rate"] == 0.5 + + def test_high_cardinality(self): + calc = _make_calc(top_n=3) + arr = pa.array([f"val_{i}" for i in range(100)]) + result = calc.compute_categorical(arr) + + assert len(result["histogram"]["values"]) == 3 + assert result["histogram"]["unique_count"] == 100 + assert result["histogram"]["other_count"] == 97 + + def test_all_nulls(self): + calc = _make_calc() + arr = pa.array([None, None], type=pa.string()) + result = calc.compute_categorical(arr) + + assert result["null_count"] == 2 + assert result["histogram"] is None + + +class TestComputeAll: + def test_mixed_features(self): + calc = _make_calc() + table = pa.table( + { + "age": [25, 30, 35, 40], + "city": ["NYC", "LA", "NYC", "SF"], + } + ) + fields = [("age", "numeric"), ("city", "categorical")] + results = calc.compute_all(table, fields) + + assert len(results) == 2 + assert results[0]["feature_name"] == "age" + assert results[0]["feature_type"] == "numeric" + assert results[1]["feature_name"] == "city" + assert results[1]["feature_type"] == "categorical" + + def test_missing_column_skipped(self): + calc = _make_calc() + table = pa.table({"age": [25, 30]}) + fields = [("age", "numeric"), ("missing_col", "numeric")] + results = calc.compute_all(table, fields) + + assert len(results) == 1 + assert results[0]["feature_name"] == "age" + + +class TestNaNSanitization: + """Verify that NaN/Inf values never leak into metric results.""" + + def test_opt_float_none(self): + assert opt_float(None) is None + + def test_opt_float_normal(self): + assert opt_float(3.14) == pytest.approx(3.14) + + def test_opt_float_nan(self): + assert opt_float(float("nan")) is None + + def test_opt_float_inf(self): + assert opt_float(float("inf")) is None + + def test_opt_float_neg_inf(self): + assert opt_float(float("-inf")) is None + + def test_opt_float_zero(self): + assert opt_float(0) == 0.0 + + def test_opt_float_integer(self): + assert opt_float(42) == 42.0 + + def test_single_value_stddev_is_none_not_nan(self): + """pc.stddev(ddof=1) on a single value returns NaN; we must convert to None.""" + calc = _make_calc() + arr = pa.array([7.0]) + result = calc.compute_numeric(arr) + + assert result["stddev"] is None + assert result["mean"] == pytest.approx(7.0) + + def test_two_values_stddev_is_valid(self): + calc = _make_calc() + arr = pa.array([4.0, 6.0]) + result = calc.compute_numeric(arr) + + assert result["stddev"] is not None + assert result["stddev"] == pytest.approx(math.sqrt(2.0)) + + def test_all_numeric_results_json_serializable(self): + """Every field in a numeric result must be JSON-serializable (no NaN/Inf).""" + calc = _make_calc(bins=5) + for test_data in [ + [42.0], # single value + [1.0, 2.0], # two values + [1.0, None, 3.0], # with nulls + list(range(100)), # many values + ]: + arr = pa.array(test_data, type=pa.float64()) + result = calc.compute_numeric(arr) + json.dumps(result) # raises ValueError if NaN/Inf present + + def test_all_categorical_results_json_serializable(self): + calc = _make_calc() + for test_data in [ + ["a", "b", "a"], + ["x", None, "y"], + [None, None], + ]: + arr = pa.array(test_data, type=pa.string()) + result = calc.compute_categorical(arr) + json.dumps(result) + + def test_sanitize_floats_cleans_nan(self): + from feast.monitoring.monitoring_service import _sanitize_floats + + row = { + "feature_name": "test", + "mean": float("nan"), + "stddev": float("inf"), + "null_rate": float("-inf"), + "min_val": 1.0, + "max_val": 10.0, + "p50": 5.0, + "p75": None, + "row_count": 100, + } + result = _sanitize_floats(row) + + assert result["mean"] is None + assert result["stddev"] is None + assert result["null_rate"] is None + assert result["min_val"] == 1.0 + assert result["max_val"] == 10.0 + assert result["p50"] == 5.0 + assert result["p75"] is None + assert result["row_count"] == 100 # non-float fields untouched + assert result["feature_name"] == "test" + json.dumps(result) + + def test_sanitize_floats_preserves_valid_values(self): + from feast.monitoring.monitoring_service import _sanitize_floats + + row = { + "mean": 5.5, + "stddev": 2.3, + "null_rate": 0.0, + "min_val": 0.0, + "max_val": 10.0, + "p50": 5.0, + "p75": 7.5, + "p90": 9.0, + "p95": 9.5, + "p99": 9.9, + "avg_null_rate": 0.05, + "max_null_rate": 0.1, + } + result = _sanitize_floats(row) + + for key, val in row.items(): + assert result[key] == val diff --git a/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py b/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py index cfadc3151fd..485ab2dce08 100644 --- a/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py +++ b/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py @@ -1,9 +1,6 @@ -""" -Unit tests for MongoDB online store. +"""Pure unit tests for MongoDB online store helpers.""" -Docker-dependent tests are marked with ``@_requires_docker`` and are skipped when -Docker is unavailable. Pure Python tests (no container needed) run in all environments. -""" +# ruff: noqa: E402 from datetime import datetime, timedelta, timezone @@ -11,186 +8,12 @@ pytest.importorskip("pymongo") -from feast import FeatureView, Field, FileSource # noqa: E402 +from feast import Entity, FeatureView, Field, FileSource, RepoConfig # noqa: E402 from feast.infra.online_stores.mongodb_online_store.mongodb import ( # noqa: E402 MongoDBOnlineStore, ) -from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto -from feast.types import Int64 -from feast.utils import _utc_now -from tests.universal.feature_repos.universal.feature_views import TAGS -from tests.utils.cli_repo_creator import CliRunner, get_example_repo - -# Check if Docker is available -docker_available = False -try: - import docker - from testcontainers.mongodb import MongoDbContainer - - # Try to connect to Docker daemon - try: - client = docker.from_env() - client.ping() - docker_available = True - except Exception: - pass -except ImportError: - pass - -# Applied per-test so that pure Python tests still run without Docker. -_requires_docker = pytest.mark.skipif( - not docker_available, - reason="Docker is not available or not running. Start Docker daemon to run these tests.", -) - - -@pytest.fixture(scope="module") -def mongodb_container(): - """Start a MongoDB container for testing.""" - container = MongoDbContainer( - "mongo:latest", - username="test", - password="test", # pragma: allowlist secret - ).with_exposed_ports(27017) - container.start() - yield container - container.stop() - - -@pytest.fixture -def mongodb_connection_string(mongodb_container): - """Get MongoDB connection string from the container.""" - exposed_port = mongodb_container.get_exposed_port(27017) - return f"mongodb://test:test@localhost:{exposed_port}" # pragma: allowlist secret - - -@_requires_docker -def test_mongodb_online_features(mongodb_connection_string): - """ - Test reading from MongoDB online store using testcontainers. - """ - runner = CliRunner() - with ( - runner.local_repo( - get_example_repo("example_feature_repo_1.py"), - offline_store="file", - online_store="mongodb", - teardown=False, # Disable CLI teardown since container will be stopped by fixture - ) as store - ): - # Update the connection string to use the test container - store.config.online_store.connection_string = mongodb_connection_string - - # Write some data to two tables - driver_locations_fv = store.get_feature_view(name="driver_locations") - customer_profile_fv = store.get_feature_view(name="customer_profile") - customer_driver_combined_fv = store.get_feature_view( - name="customer_driver_combined" - ) - - provider = store._get_provider() - - driver_key = EntityKeyProto( - join_keys=["driver_id"], entity_values=[ValueProto(int64_val=1)] - ) - provider.online_write_batch( - config=store.config, - table=driver_locations_fv, - data=[ - ( - driver_key, - { - "lat": ValueProto(double_val=0.1), - "lon": ValueProto(string_val="1.0"), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - customer_key = EntityKeyProto( - join_keys=["customer_id"], entity_values=[ValueProto(string_val="5")] - ) - provider.online_write_batch( - config=store.config, - table=customer_profile_fv, - data=[ - ( - customer_key, - { - "avg_orders_day": ValueProto(float_val=1.0), - "name": ValueProto(string_val="John"), - "age": ValueProto(int64_val=3), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - customer_key = EntityKeyProto( - join_keys=["customer_id", "driver_id"], - entity_values=[ValueProto(string_val="5"), ValueProto(int64_val=1)], - ) - provider.online_write_batch( - config=store.config, - table=customer_driver_combined_fv, - data=[ - ( - customer_key, - {"trips": ValueProto(int64_val=7)}, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - assert len(store.list_entities()) == 3 - assert len(store.list_entities(tags=TAGS)) == 2 - - # Retrieve features using two keys - result = store.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[ - {"driver_id": 1, "customer_id": "5"}, - {"driver_id": 1, "customer_id": 5}, - ], - full_feature_names=False, - ).to_dict() - - assert "lon" in result - assert "avg_orders_day" in result - assert "name" in result - assert result["driver_id"] == [1, 1] - assert result["customer_id"] == ["5", "5"] - assert result["lon"] == ["1.0", "1.0"] - assert result["avg_orders_day"] == [1.0, 1.0] - assert result["name"] == ["John", "John"] - assert result["trips"] == [7, 7] - - # Ensure features are still in result when keys not found - result = store.get_online_features( - features=["customer_driver_combined:trips"], - entity_rows=[{"driver_id": 0, "customer_id": 0}], - full_feature_names=False, - ).to_dict() - - assert result["trips"] == [None] - - -# --------------------------------------------------------------------------- -# Pure Python tests — no Docker required -# --------------------------------------------------------------------------- +from feast.types import Array, Float32, Int64, String def _make_fv(*field_names: str) -> FeatureView: @@ -303,3 +126,118 @@ def test_convert_raw_docs_ordering(): assert results[0][1]["score"].int64_val == 1 # entity_z assert results[1][1]["score"].int64_val == 2 # entity_a assert results[2][1]["score"].int64_val == 3 # entity_m + + +# --------------------------------------------------------------------------- +# Vector search validation — pure Python, no Docker required +# --------------------------------------------------------------------------- + + +def _make_vector_fv( + *, vector_index: bool = True, vector_length: int = 3 +) -> FeatureView: + """Build a FeatureView with an embedding field for vector search tests.""" + embedding_kwargs: dict = {"name": "embedding", "dtype": Array(Float32)} + if vector_index: + embedding_kwargs.update( + vector_index=True, + vector_length=vector_length, + vector_search_metric="cosine", + ) + return FeatureView( + name="item_embeddings", + entities=[Entity(name="item_id", join_keys=["item_id"])], + schema=[ + Field(**embedding_kwargs), + Field(name="title", dtype=String), + Field(name="item_id", dtype=Int64), + ], + source=FileSource(path="fake.parquet", timestamp_field="event_timestamp"), + ttl=timedelta(hours=24), + ) + + +def _make_repo_config(*, vector_enabled: bool = True) -> RepoConfig: + """Build a RepoConfig with MongoDB online store for vector search tests.""" + return RepoConfig( + project="test_vs", + provider="local", + online_store={ + "type": "mongodb", + "connection_string": "mongodb://localhost:27017", + "vector_enabled": vector_enabled, + }, + registry="memory://", + entity_key_serialization_version=3, + ) + + +def test_retrieve_raises_when_vector_not_enabled(): + """retrieve_online_documents_v2 raises ValueError when vector_enabled=False.""" + store = MongoDBOnlineStore() + config = _make_repo_config(vector_enabled=False) + fv = _make_vector_fv() + + with pytest.raises(ValueError, match="Vector search is not enabled"): + store.retrieve_online_documents_v2( + config=config, + table=fv, + requested_features=["embedding"], + embedding=[1.0, 0.0, 0.0], + top_k=3, + ) + + +def test_retrieve_raises_when_embedding_is_none(): + """retrieve_online_documents_v2 raises ValueError when embedding is None.""" + store = MongoDBOnlineStore() + config = _make_repo_config(vector_enabled=True) + fv = _make_vector_fv() + + with pytest.raises(ValueError, match="embedding vector must be provided"): + store.retrieve_online_documents_v2( + config=config, + table=fv, + requested_features=["embedding"], + embedding=None, + top_k=3, + ) + + +def test_retrieve_raises_when_no_vector_fields(): + """retrieve_online_documents_v2 raises ValueError when no fields have vector_index=True.""" + store = MongoDBOnlineStore() + config = _make_repo_config(vector_enabled=True) + fv = _make_vector_fv(vector_index=False) + + with pytest.raises(ValueError, match="has no fields with vector_index=True"): + store.retrieve_online_documents_v2( + config=config, + table=fv, + requested_features=["embedding"], + embedding=[1.0, 0.0, 0.0], + top_k=3, + ) + + +def test_ensure_vector_indexes_raises_on_missing_vector_length(): + """_ensure_vector_indexes raises ValueError when vector_length is not set.""" + from unittest.mock import MagicMock + + store = MongoDBOnlineStore() + config = _make_repo_config(vector_enabled=True) + online_config = config.online_store + + # Create a feature view where vector_index=True but vector_length=0/None + fv = _make_vector_fv(vector_index=True, vector_length=0) + + # Mock collection so we don't need a real MongoDB connection + mock_collection = MagicMock() + mock_collection.database.list_collection_names.return_value = ["test_vs_latest"] + mock_collection.name = "test_vs_latest" + mock_collection.list_search_indexes.return_value = [] + + with pytest.raises( + ValueError, match="vector_index=True but vector_length is not set" + ): + store._ensure_vector_indexes(mock_collection, [fv], online_config) diff --git a/sdk/python/tests/unit/online_store/test_online_retrieval.py b/sdk/python/tests/unit/online_store/test_online_retrieval.py index 60f583ad669..63dcc8c7e48 100644 --- a/sdk/python/tests/unit/online_store/test_online_retrieval.py +++ b/sdk/python/tests/unit/online_store/test_online_retrieval.py @@ -1714,3 +1714,181 @@ def test_milvus_keyword_search() -> None: assert len(result_hybrid["content"]) > 0 assert any("Feast" in content for content in result_hybrid["content"]) assert len(result_hybrid["vector"]) > 0 + + +def test_milvus_update_preserves_collection_cache() -> None: + """ + Regression test: update() used to overwrite self._collections with the + describe_collection() dict of the last processed table, replacing the + dict-of-dicts cache with a single flat dict. After the fix, each call + to _get_or_create_collection() updates the keyed entry in-place and the + cache remains a proper mapping from collection name to collection info. + """ + from datetime import timedelta + + from feast import Entity, FeatureView, Field, FileSource + from feast.types import Array, Float32, Int64, String + + runner = CliRunner() + with runner.local_repo( + example_repo_py=get_example_repo("example_rag_feature_repo.py"), + offline_store="file", + online_store="milvus", + apply=False, + teardown=False, + ) as store: + source = FileSource( + path="data/dummy.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created_timestamp", + ) + entity_a = Entity(name="id_a", join_keys=["id_a"], value_type=ValueType.INT64) + entity_b = Entity(name="id_b", join_keys=["id_b"], value_type=ValueType.INT64) + + fv_a = FeatureView( + name="fv_a", + entities=[entity_a], + schema=[ + Field(name="id_a", dtype=Int64), + Field( + name="vec_a", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="text_a", dtype=String), + ], + source=source, + ttl=timedelta(hours=1), + ) + fv_b = FeatureView( + name="fv_b", + entities=[entity_b], + schema=[ + Field(name="id_b", dtype=Int64), + Field( + name="vec_b", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="text_b", dtype=String), + ], + source=source, + ttl=timedelta(hours=1), + ) + + store.apply([source, entity_a, entity_b, fv_a, fv_b]) + + online_store = store._provider._online_store + # After applying two feature views, the cache must be a proper dict + # mapping collection names to collection-info dicts, not a flat dict. + assert isinstance(online_store._collections, dict), ( + "_collections should be a dict" + ) + collection_name_a = f"{store.config.project}_fv_a" + collection_name_b = f"{store.config.project}_fv_b" + assert collection_name_a in online_store._collections, ( + f"Cache missing entry for {collection_name_a}" + ) + assert collection_name_b in online_store._collections, ( + f"Cache missing entry for {collection_name_b} — " + "update() likely overwrote _collections with a single collection dict" + ) + # Each cached value must be a collection-info dict (has a 'fields' key), + # not itself keyed by collection name. + for name in [collection_name_a, collection_name_b]: + assert "fields" in online_store._collections[name], ( + f"Cache entry for {name} looks like a corrupted flat dict" + ) + + +def test_milvus_plan_returns_empty_list() -> None: + """ + Regression test: plan() used to raise NotImplementedError, causing + `feast plan` to crash for any project using the Milvus online store. + It should return [] matching the OnlineStore base class default. + """ + from feast.infra.online_stores.milvus_online_store.milvus import MilvusOnlineStore + + store = MilvusOnlineStore() + result = store.plan(config=None, desired_registry_proto=None) # type: ignore[arg-type] + assert result == [], f"plan() should return [] but returned {result!r}" + + +def test_milvus_retrieve_online_documents_v2_missing_entity_key() -> None: + """ + Regression test: retrieve_online_documents_v2() passed the raw + hit.get("entity", {}).get(composite_key_name, None) directly to + bytes.fromhex(), raising TypeError when the key was absent. + After the fix, a missing composite key produces a None entity_key_proto + instead of crashing. + """ + from datetime import timedelta + from unittest.mock import patch + + from feast import Entity, FeatureView, Field, FileSource + from feast.types import Array, Float32, Int64, String + + runner = CliRunner() + with runner.local_repo( + example_repo_py=get_example_repo("example_rag_feature_repo.py"), + offline_store="file", + online_store="milvus", + apply=False, + teardown=False, + ) as store: + source = FileSource( + path="data/dummy.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created_timestamp", + ) + entity = Entity(name="doc_id", join_keys=["doc_id"], value_type=ValueType.INT64) + fv = FeatureView( + name="docs", + entities=[entity], + schema=[ + Field(name="doc_id", dtype=Int64), + Field( + name="vec", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="COSINE", + ), + Field(name="text", dtype=String), + ], + source=source, + ttl=timedelta(hours=1), + ) + store.apply([source, entity, fv]) + + online_store = store._provider._online_store + fv_obj = store.get_feature_view("docs") + # Simulate a search hit that is missing the composite primary key. + fake_hit = { + "entity": { + "event_ts": int(_utc_now().timestamp() * 1e6), + "created_ts": int(_utc_now().timestamp() * 1e6), + "text": "hello", + }, + "distance": 0.9, + } + + mock_results = [[fake_hit]] + with patch.object(online_store.client, "search", return_value=mock_results): + with patch.object( + online_store.client, "load_collection", return_value=None + ): + # Before the fix this raised TypeError: fromhex argument must be str, not None + result = online_store.retrieve_online_documents_v2( + config=store.config, + table=fv_obj, + requested_features=["text"], + embedding=[0.1] * 10, + top_k=1, + ) + assert len(result) == 1 + _ts, entity_key_proto, _features = result[0] + assert entity_key_proto is None, ( + "entity_key_proto should be None when the composite key is absent from the hit" + ) diff --git a/sdk/python/tests/unit/permissions/auth/server/mock_utils.py b/sdk/python/tests/unit/permissions/auth/server/mock_utils.py index 5bde4d4ecbc..4d62bbf4348 100644 --- a/sdk/python/tests/unit/permissions/auth/server/mock_utils.py +++ b/sdk/python/tests/unit/permissions/auth/server/mock_utils.py @@ -32,14 +32,14 @@ async def mock_oath2(self, request): } monkeypatch.setattr( "feast.permissions.client.oidc_authentication_client_manager.requests.get", - lambda url: discovery_response, + lambda url, verify=True: discovery_response, ) token_response = Mock(spec=Response) token_response.status_code = 200 token_response.json.return_value = {"access_token": "my-token"} monkeypatch.setattr( "feast.permissions.client.oidc_authentication_client_manager.requests.post", - lambda url, data, headers: token_response, + lambda url, data, headers, verify=True: token_response, ) monkeypatch.setattr( diff --git a/sdk/python/tests/unit/permissions/auth/test_token_parser.py b/sdk/python/tests/unit/permissions/auth/test_token_parser.py index 8ac0f2b6d5e..fdec71e109a 100644 --- a/sdk/python/tests/unit/permissions/auth/test_token_parser.py +++ b/sdk/python/tests/unit/permissions/auth/test_token_parser.py @@ -50,10 +50,138 @@ def test_oidc_token_validation_success( assertpy.assert_that(user).is_type_of(User) if isinstance(user, User): assertpy.assert_that(user.username).is_equal_to("my-name") - assertpy.assert_that(user.roles.sort()).is_equal_to(["reader", "writer"].sort()) + assertpy.assert_that(sorted(user.roles)).is_equal_to( + sorted(["reader", "writer"]) + ) assertpy.assert_that(user.has_matching_role(["reader"])).is_true() assertpy.assert_that(user.has_matching_role(["writer"])).is_true() assertpy.assert_that(user.has_matching_role(["updater"])).is_false() + assertpy.assert_that(user.groups).is_equal_to([]) + assertpy.assert_that(user.namespaces).is_equal_to([]) + + +@patch( + "feast.permissions.auth.oidc_token_parser.OAuth2AuthorizationCodeBearer.__call__" +) +@patch("feast.permissions.auth.oidc_token_parser.PyJWKClient.get_signing_key_from_jwt") +@patch("feast.permissions.auth.oidc_token_parser.jwt.decode") +@patch("feast.permissions.oidc_service.OIDCDiscoveryService._fetch_discovery_data") +def test_oidc_token_missing_roles_key_returns_empty( + mock_discovery_data, mock_jwt, mock_signing_key, mock_oauth2, oidc_config +): + signing_key = MagicMock() + signing_key.key = "a-key" + mock_signing_key.return_value = signing_key + + mock_discovery_data.return_value = { + "authorization_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/auth", + "token_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/token", + "jwks_uri": "https://localhost:8080/realms/master/protocol/openid-connect/certs", + } + + user_data = { + "preferred_username": "my-name", + "resource_access": {_CLIENT_ID: {}}, + } + mock_jwt.return_value = user_data + + access_token = "aaa-bbb-ccc" + token_parser = OidcTokenParser(auth_config=oidc_config) + user = asyncio.run( + token_parser.user_details_from_access_token(access_token=access_token) + ) + + assertpy.assert_that(user).is_type_of(User) + if isinstance(user, User): + assertpy.assert_that(user.username).is_equal_to("my-name") + assertpy.assert_that(user.roles).is_equal_to([]) + + +@patch( + "feast.permissions.auth.oidc_token_parser.OAuth2AuthorizationCodeBearer.__call__" +) +@patch("feast.permissions.auth.oidc_token_parser.PyJWKClient.get_signing_key_from_jwt") +@patch("feast.permissions.auth.oidc_token_parser.jwt.decode") +@patch("feast.permissions.oidc_service.OIDCDiscoveryService._fetch_discovery_data") +def test_oidc_token_extracts_groups( + mock_discovery_data, mock_jwt, mock_signing_key, mock_oauth2, oidc_config +): + signing_key = MagicMock() + signing_key.key = "a-key" + mock_signing_key.return_value = signing_key + + mock_discovery_data.return_value = { + "authorization_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/auth", + "token_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/token", + "jwks_uri": "https://localhost:8080/realms/master/protocol/openid-connect/certs", + } + + user_data = { + "preferred_username": "my-name", + "resource_access": {_CLIENT_ID: {"roles": ["reader"]}}, + "groups": ["banking-admin", "data-engineers"], + } + mock_jwt.return_value = user_data + + access_token = "aaa-bbb-ccc" + token_parser = OidcTokenParser(auth_config=oidc_config) + user = asyncio.run( + token_parser.user_details_from_access_token(access_token=access_token) + ) + + assertpy.assert_that(user).is_type_of(User) + if isinstance(user, User): + assertpy.assert_that(user.groups).is_equal_to( + ["banking-admin", "data-engineers"] + ) + assertpy.assert_that(user.has_matching_group(["banking-admin"])).is_true() + assertpy.assert_that(user.has_matching_group(["unknown-group"])).is_false() + assertpy.assert_that(user.namespaces).is_equal_to([]) + + +@patch( + "feast.permissions.auth.oidc_token_parser.OAuth2AuthorizationCodeBearer.__call__" +) +@patch("feast.permissions.auth.oidc_token_parser.PyJWKClient.get_signing_key_from_jwt") +@patch("feast.permissions.auth.oidc_token_parser.jwt.decode") +@patch("feast.permissions.oidc_service.OIDCDiscoveryService._fetch_discovery_data") +def test_oidc_token_extracts_groups_and_roles( + mock_discovery_data, mock_jwt, mock_signing_key, mock_oauth2, oidc_config +): + signing_key = MagicMock() + signing_key.key = "a-key" + mock_signing_key.return_value = signing_key + + mock_discovery_data.return_value = { + "authorization_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/auth", + "token_endpoint": "https://localhost:8080/realms/master/protocol/openid-connect/token", + "jwks_uri": "https://localhost:8080/realms/master/protocol/openid-connect/certs", + } + + user_data = { + "preferred_username": "my-name", + "resource_access": {_CLIENT_ID: {"roles": ["reader", "writer"]}}, + "groups": ["banking-admin", "data-engineers"], + } + mock_jwt.return_value = user_data + + access_token = "aaa-bbb-ccc" + token_parser = OidcTokenParser(auth_config=oidc_config) + user = asyncio.run( + token_parser.user_details_from_access_token(access_token=access_token) + ) + + assertpy.assert_that(user).is_type_of(User) + if isinstance(user, User): + assertpy.assert_that(user.username).is_equal_to("my-name") + assertpy.assert_that(sorted(user.roles)).is_equal_to( + sorted(["reader", "writer"]) + ) + assertpy.assert_that(user.groups).is_equal_to( + ["banking-admin", "data-engineers"] + ) + assertpy.assert_that(user.has_matching_role(["reader"])).is_true() + assertpy.assert_that(user.has_matching_group(["banking-admin"])).is_true() @patch( @@ -131,8 +259,8 @@ async def mock_oath2(self, request): assertpy.assert_that(user).is_type_of(User) if isinstance(user, User): assertpy.assert_that(user.username).is_equal_to("my-name") - assertpy.assert_that(user.roles.sort()).is_equal_to( - ["reader", "writer"].sort() + assertpy.assert_that(sorted(user.roles)).is_equal_to( + sorted(["reader", "writer"]) ) assertpy.assert_that(user.has_matching_role(["reader"])).is_true() assertpy.assert_that(user.has_matching_role(["writer"])).is_true() @@ -175,7 +303,7 @@ def test_k8s_token_validation_success( assertpy.assert_that(user).is_type_of(User) if isinstance(user, User): assertpy.assert_that(user.username).is_equal_to(f"{sa_namespace}:{sa_name}") - assertpy.assert_that(user.roles.sort()).is_equal_to(roles.sort()) + assertpy.assert_that(sorted(user.roles)).is_equal_to(sorted(roles)) for r in roles: assertpy.assert_that(user.has_matching_role([r])).is_true() assertpy.assert_that(user.has_matching_role(["foo"])).is_false() @@ -259,7 +387,91 @@ def test_k8s_inter_server_comm( assertpy.assert_that(user).is_type_of(User) if isinstance(user, User): assertpy.assert_that(user.username).is_equal_to(f"{sa_namespace}:{sa_name}") - assertpy.assert_that(user.roles.sort()).is_equal_to(roles.sort()) + assertpy.assert_that(sorted(user.roles)).is_equal_to(sorted(roles)) for r in roles: assertpy.assert_that(user.has_matching_role([r])).is_true() assertpy.assert_that(user.has_matching_role(["foo"])).is_false() + + +# --------------------------------------------------------------------------- +# OidcTokenParser — SA token routing +# --------------------------------------------------------------------------- + + +@patch("feast.permissions.auth.oidc_token_parser.jwt.decode") +@patch("feast.permissions.oidc_service.OIDCDiscoveryService._fetch_discovery_data") +def test_oidc_parser_handles_sa_token_via_token_review( + mock_discovery_data, mock_jwt_decode, oidc_config +): + """When a token contains kubernetes.io claim, _handle_sa_token is called (not the OIDC JWKS path).""" + mock_discovery_data.return_value = { + "authorization_endpoint": "https://localhost:8080/auth", + "token_endpoint": "https://localhost:8080/token", + "jwks_uri": "https://localhost:8080/certs", + } + + mock_jwt_decode.return_value = { + "kubernetes.io": {"namespace": "feast"}, + "sub": "system:serviceaccount:feast:feast", + } + + sa_user = User( + username="system:serviceaccount:feast:feast", + roles=[], + groups=[], + namespaces=["feast"], + ) + + token_parser = OidcTokenParser(auth_config=oidc_config) + + with patch.object( + token_parser, + "_validate_k8s_sa_token_and_extract_namespace", + return_value=sa_user, + ) as mock_handle: + user = asyncio.run( + token_parser.user_details_from_access_token(access_token="sa-token") + ) + mock_handle.assert_called_once_with("sa-token") + + assertpy.assert_that(user.username).is_equal_to("system:serviceaccount:feast:feast") + assertpy.assert_that(user.namespaces).is_equal_to(["feast"]) + assertpy.assert_that(user.roles).is_equal_to([]) + assertpy.assert_that(user.groups).is_equal_to([]) + + +@patch( + "feast.permissions.auth.oidc_token_parser.OAuth2AuthorizationCodeBearer.__call__" +) +@patch("feast.permissions.auth.oidc_token_parser.PyJWKClient.get_signing_key_from_jwt") +@patch("feast.permissions.auth.oidc_token_parser.jwt.decode") +@patch("feast.permissions.oidc_service.OIDCDiscoveryService._fetch_discovery_data") +def test_oidc_parser_routes_keycloak_token_normally( + mock_discovery_data, mock_jwt_decode, mock_signing_key, mock_oauth2, oidc_config +): + """When a token does NOT contain kubernetes.io claim, it should follow the OIDC path.""" + signing_key = MagicMock() + signing_key.key = "a-key" + mock_signing_key.return_value = signing_key + + mock_discovery_data.return_value = { + "authorization_endpoint": "https://localhost:8080/auth", + "token_endpoint": "https://localhost:8080/token", + "jwks_uri": "https://localhost:8080/certs", + } + + keycloak_payload = { + "preferred_username": "testuser", + "resource_access": {_CLIENT_ID: {"roles": ["reader"]}}, + "groups": ["data-team"], + } + mock_jwt_decode.return_value = keycloak_payload + + token_parser = OidcTokenParser(auth_config=oidc_config) + user = asyncio.run( + token_parser.user_details_from_access_token(access_token="keycloak-jwt") + ) + + assertpy.assert_that(user.username).is_equal_to("testuser") + assertpy.assert_that(user.roles).is_equal_to(["reader"]) + assertpy.assert_that(user.groups).is_equal_to(["data-team"]) diff --git a/sdk/python/tests/permissions/test_groups_namespaces_auth.py b/sdk/python/tests/unit/permissions/test_groups_namespaces_auth.py similarity index 100% rename from sdk/python/tests/permissions/test_groups_namespaces_auth.py rename to sdk/python/tests/unit/permissions/test_groups_namespaces_auth.py diff --git a/sdk/python/tests/unit/permissions/test_oidc_token_passthrough.py b/sdk/python/tests/unit/permissions/test_oidc_token_passthrough.py new file mode 100644 index 00000000000..e0766ad6b0e --- /dev/null +++ b/sdk/python/tests/unit/permissions/test_oidc_token_passthrough.py @@ -0,0 +1,431 @@ +""" +Tests for OIDC client-side token passthrough feature. + +Covers: + - Config validation (OidcClientAuthConfig) + - Token manager (OidcAuthClientManager.get_token) + - Routing (RepoConfig.auth_config property) +""" + +import os +from unittest.mock import MagicMock, patch + +import pytest + +from feast.permissions.auth_model import OidcClientAuthConfig +from feast.permissions.client.oidc_authentication_client_manager import ( + OidcAuthClientManager, +) +from feast.repo_config import RepoConfig + +# --------------------------------------------------------------------------- +# Config validation +# --------------------------------------------------------------------------- + + +class TestOidcClientAuthConfigValidation: + def test_bare_oidc_valid(self): + cfg = OidcClientAuthConfig(type="oidc") + assert cfg.token_env_var is None + assert cfg.auth_discovery_url is None + assert cfg.client_id is None + + def test_token_alone_valid(self): + cfg = OidcClientAuthConfig(type="oidc", token="eyJhbGciOiJSUzI1NiJ9.test") + assert cfg.token == "eyJhbGciOiJSUzI1NiJ9.test" + + def test_token_env_var_alone_valid(self): + cfg = OidcClientAuthConfig(type="oidc", token_env_var="MY_VAR") + assert cfg.token_env_var == "MY_VAR" + + def test_token_plus_custom_env_var_invalid(self): + with pytest.raises(ValueError, match="Only one of"): + OidcClientAuthConfig( + type="oidc", + token="eyJtoken", + token_env_var="MY_VAR", + ) + + def test_client_secret_without_discovery_url_invalid(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + OidcClientAuthConfig( + type="oidc", + client_secret="my-secret", # pragma: allowlist secret + ) + + def test_full_client_credentials_valid(self): + cfg = OidcClientAuthConfig( + type="oidc", + client_secret="my-secret", # pragma: allowlist secret + auth_discovery_url="https://idp.example.com/.well-known/openid-configuration", + client_id="feast-client", + ) + assert cfg.client_secret == "my-secret" # pragma: allowlist secret + + def test_full_ropg_valid(self): + cfg = OidcClientAuthConfig( + type="oidc", + username="user1", + password="pass1", # pragma: allowlist secret + client_secret="my-secret", # pragma: allowlist secret + auth_discovery_url="https://idp.example.com/.well-known/openid-configuration", + client_id="feast-client", + ) + assert cfg.username == "user1" + + def test_ropg_without_discovery_url_invalid(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + OidcClientAuthConfig( + type="oidc", + username="user1", + password="pass1", # pragma: allowlist secret + client_secret="my-secret", # pragma: allowlist secret + ) + + def test_username_without_client_secret_invalid(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + OidcClientAuthConfig( + type="oidc", + username="user1", + password="pass1", # pragma: allowlist secret + ) + + def test_token_plus_client_secret_invalid(self): + with pytest.raises(ValueError, match="Only one of"): + OidcClientAuthConfig( + type="oidc", + token="jwt", + client_secret="secret", # pragma: allowlist secret + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + + def test_token_env_var_with_discovery_url_invalid(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + OidcClientAuthConfig( + type="oidc", + token_env_var="MY_VAR", + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + + def test_token_with_discovery_url_invalid(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + OidcClientAuthConfig( + type="oidc", + token="eyJ.test", + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + + +# --------------------------------------------------------------------------- +# Token manager +# --------------------------------------------------------------------------- + + +class TestOidcAuthClientManagerGetToken: + def _make_manager(self, **kwargs) -> OidcAuthClientManager: + cfg = OidcClientAuthConfig(type="oidc", **kwargs) + return OidcAuthClientManager(cfg) + + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_token_returned_directly(self, mock_discovery_cls): + mgr = self._make_manager(token="my-static-jwt") + assert mgr.get_token() == "my-static-jwt" + mock_discovery_cls.assert_not_called() + + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value=None, + ) + def test_no_token_source_raises(self, _mock_sa): + mgr = self._make_manager() + with pytest.raises(PermissionError, match="No OIDC token source configured"): + mgr.get_token() + + @patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "env-jwt-value"}) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_explicit_feast_env_var(self, mock_discovery_cls): + mgr = self._make_manager(token_env_var="FEAST_OIDC_TOKEN") + assert mgr.get_token() == "env-jwt-value" + mock_discovery_cls.assert_not_called() + + @patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "fallback-jwt"}) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_bare_config_falls_back_to_well_known_env(self, mock_discovery_cls): + mgr = self._make_manager() + assert mgr.get_token() == "fallback-jwt" + mock_discovery_cls.assert_not_called() + + @patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "should-not-win"}, clear=False) + @patch("feast.permissions.client.oidc_authentication_client_manager.requests") + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_network_config_not_overridden_by_well_known_env( + self, mock_discovery_cls, mock_requests + ): + mock_discovery_instance = MagicMock() + mock_discovery_instance.get_token_url.return_value = "https://idp/token" + mock_discovery_cls.return_value = mock_discovery_instance + + mock_response = MagicMock() + mock_response.status_code = 200 + mock_response.json.return_value = {"access_token": "idp-token"} + mock_requests.post.return_value = mock_response + + mgr = self._make_manager( + client_secret="secret", # pragma: allowlist secret + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + assert mgr.get_token() == "idp-token" + + @patch.dict(os.environ, {"CUSTOM_TOKEN_VAR": "custom-env-jwt"}) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_custom_env_var_read(self, mock_discovery_cls): + mgr = self._make_manager(token_env_var="CUSTOM_TOKEN_VAR") + assert mgr.get_token() == "custom-env-jwt" + mock_discovery_cls.assert_not_called() + + @patch.dict(os.environ, {}, clear=False) + @patch("feast.permissions.client.oidc_authentication_client_manager.requests") + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_fallthrough_to_client_credentials(self, mock_discovery_cls, mock_requests): + os.environ.pop("FEAST_OIDC_TOKEN", None) + + mock_discovery_instance = MagicMock() + mock_discovery_instance.get_token_url.return_value = "https://idp/token" + mock_discovery_cls.return_value = mock_discovery_instance + + mock_response = MagicMock() + mock_response.status_code = 200 + mock_response.json.return_value = {"access_token": "network-token"} + mock_requests.post.return_value = mock_response + + mgr = self._make_manager( + client_secret="secret", # pragma: allowlist secret + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + assert mgr.get_token() == "network-token" + mock_discovery_cls.assert_called_once() + + @patch.dict(os.environ, {}, clear=False) + @patch("feast.permissions.client.oidc_authentication_client_manager.requests") + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_ropg_flow(self, mock_discovery_cls, mock_requests): + os.environ.pop("FEAST_OIDC_TOKEN", None) + + mock_discovery_instance = MagicMock() + mock_discovery_instance.get_token_url.return_value = "https://idp/token" + mock_discovery_cls.return_value = mock_discovery_instance + + mock_response = MagicMock() + mock_response.status_code = 200 + mock_response.json.return_value = {"access_token": "ropg-token"} + mock_requests.post.return_value = mock_response + + mgr = self._make_manager( + username="user1", + password="pass1", # pragma: allowlist secret + client_secret="secret", # pragma: allowlist secret + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + assert mgr.get_token() == "ropg-token" + + call_args = mock_requests.post.call_args + assert call_args[1]["data"]["grant_type"] == "password" + assert call_args[1]["data"]["username"] == "user1" + + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_token_takes_priority_over_env_var(self, mock_discovery_cls): + with patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "env-token"}): + mgr = self._make_manager(token="config-token") + assert mgr.get_token() == "config-token" + mock_discovery_cls.assert_not_called() + + @patch.dict(os.environ, {}, clear=False) + def test_configured_env_var_missing_raises(self): + os.environ.pop("MY_CUSTOM_VAR", None) + mgr = self._make_manager(token_env_var="MY_CUSTOM_VAR") + with pytest.raises(PermissionError, match="token_env_var='MY_CUSTOM_VAR'"): + mgr.get_token() + + @patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "stale-token"}, clear=False) + def test_configured_env_var_missing_does_not_fall_through(self): + os.environ.pop("MY_CUSTOM_VAR", None) + mgr = self._make_manager(token_env_var="MY_CUSTOM_VAR") + with pytest.raises(PermissionError, match="token_env_var='MY_CUSTOM_VAR'"): + mgr.get_token() + + # --- SA token file fallback tests --- + + @patch.dict(os.environ, {}, clear=False) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value="sa-jwt-from-file", + ) + def test_sa_token_file_read(self, _mock_sa): + os.environ.pop("FEAST_OIDC_TOKEN", None) + mgr = self._make_manager() + assert mgr.get_token() == "sa-jwt-from-file" + + @patch.dict(os.environ, {}, clear=False) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value=None, + ) + def test_sa_token_file_missing_raises(self, _mock_sa): + os.environ.pop("FEAST_OIDC_TOKEN", None) + mgr = self._make_manager() + with pytest.raises(PermissionError, match="No OIDC token source configured"): + mgr.get_token() + + @patch.dict(os.environ, {"FEAST_OIDC_TOKEN": "env-token"}, clear=False) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value="sa-jwt-from-file", + ) + def test_feast_env_takes_priority_over_sa_token(self, _mock_sa): + mgr = self._make_manager() + assert mgr.get_token() == "env-token" + _mock_sa.assert_not_called() + + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value="sa-jwt-from-file", + ) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_explicit_token_skips_sa_file(self, mock_discovery_cls, _mock_sa): + mgr = self._make_manager(token="my-explicit-token") + assert mgr.get_token() == "my-explicit-token" + _mock_sa.assert_not_called() + + @patch.dict(os.environ, {}, clear=False) + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OidcAuthClientManager._read_sa_token", + return_value="sa-jwt-from-file", + ) + @patch("feast.permissions.client.oidc_authentication_client_manager.requests") + @patch( + "feast.permissions.client.oidc_authentication_client_manager.OIDCDiscoveryService" + ) + def test_client_secret_skips_sa_file( + self, mock_discovery_cls, mock_requests, _mock_sa + ): + os.environ.pop("FEAST_OIDC_TOKEN", None) + + mock_discovery_instance = MagicMock() + mock_discovery_instance.get_token_url.return_value = "https://idp/token" + mock_discovery_cls.return_value = mock_discovery_instance + + mock_response = MagicMock() + mock_response.status_code = 200 + mock_response.json.return_value = {"access_token": "network-token"} + mock_requests.post.return_value = mock_response + + mgr = self._make_manager( + client_secret="secret", # pragma: allowlist secret + auth_discovery_url="https://idp/.well-known/openid-configuration", + client_id="feast-client", + ) + assert mgr.get_token() == "network-token" + _mock_sa.assert_not_called() + + +# --------------------------------------------------------------------------- +# Routing (RepoConfig.auth_config property) +# --------------------------------------------------------------------------- + + +class TestOidcClientRouting: + def _make_repo_config(self, auth_dict: dict) -> RepoConfig: + return RepoConfig( + project="test_project", + registry="data/registry.db", + provider="local", + auth=auth_dict, + ) + + def test_bare_oidc_routes_to_client(self): + rc = self._make_repo_config({"type": "oidc"}) + assert isinstance(rc.auth_config, OidcClientAuthConfig) + + def test_token_routes_to_client(self): + rc = self._make_repo_config({"type": "oidc", "token": "x"}) + assert isinstance(rc.auth_config, OidcClientAuthConfig) + assert rc.auth_config.token == "x" + + def test_token_env_var_routes_to_client(self): + rc = self._make_repo_config({"type": "oidc", "token_env_var": "MY_VAR"}) + assert isinstance(rc.auth_config, OidcClientAuthConfig) + assert rc.auth_config.token_env_var == "MY_VAR" + + def test_server_config_routes_to_oidc_auth_config(self): + from feast.permissions.auth_model import OidcAuthConfig + + rc = self._make_repo_config( + { + "type": "oidc", + "auth_discovery_url": "https://idp/.well-known/openid-configuration", + "client_id": "feast-server", + } + ) + assert isinstance(rc.auth_config, OidcAuthConfig) + assert type(rc.auth_config) is OidcAuthConfig + + def test_ropg_routes_to_client(self): + rc = self._make_repo_config( + { + "type": "oidc", + "auth_discovery_url": "https://idp/.well-known/openid-configuration", + "client_id": "feast-client", + "client_secret": "secret", # pragma: allowlist secret + "username": "user1", + "password": "pass1", # pragma: allowlist secret + } + ) + assert isinstance(rc.auth_config, OidcClientAuthConfig) + + def test_incomplete_ropg_routes_to_client_with_actionable_error(self): + with pytest.raises( + ValueError, match="Incomplete configuration for 'client_credentials'" + ): + self._make_repo_config( + { + "type": "oidc", + "auth_discovery_url": "https://idp/.well-known/openid-configuration", + "client_id": "feast-client", + "username": "user1", + "password": "pass1", # pragma: allowlist secret + } + ).auth_config diff --git a/sdk/python/tests/unit/test_aggregation_ops.py b/sdk/python/tests/unit/test_aggregation_ops.py index 9a22da0ecec..fd4f147f5d8 100644 --- a/sdk/python/tests/unit/test_aggregation_ops.py +++ b/sdk/python/tests/unit/test_aggregation_ops.py @@ -1,8 +1,10 @@ from datetime import timedelta +import pandas as pd import pytest from feast.aggregation import Aggregation, aggregation_specs_to_agg_ops +from feast.aggregation.tiling.base import get_ir_metadata_for_aggregation class DummyAggregation: @@ -96,3 +98,40 @@ def test_aggregation_round_trip_with_name(): restored = Aggregation.from_proto(proto) assert restored.name == "sum_seconds_watched_per_ad_1d" assert restored == agg + + +def test_count_distinct_agg_ops(): + """aggregation_specs_to_agg_ops maps count_distinct to the nunique pandas function.""" + agg_specs = [DummyAggregation(function="count_distinct", column="item_id")] + + agg_ops = aggregation_specs_to_agg_ops( + agg_specs, + time_window_unsupported_error_message="no windows", + ) + + assert agg_ops == {"count_distinct_item_id": ("nunique", "item_id")} + + +def test_count_distinct_result(): + """count_distinct via nunique returns the number of unique values per group.""" + from feast.infra.compute_engines.backends.pandas_backend import PandasBackend + + agg_specs = [DummyAggregation(function="count_distinct", column="item_id")] + agg_ops = aggregation_specs_to_agg_ops( + agg_specs, + time_window_unsupported_error_message="no windows", + ) + + df = pd.DataFrame({"user": ["A", "A", "B"], "item_id": [1, 2, 1]}) + result = PandasBackend().groupby_agg(df, ["user"], agg_ops) + result = result.set_index("user") + + assert result.loc["A", "count_distinct_item_id"] == 2 + assert result.loc["B", "count_distinct_item_id"] == 1 + + +def test_count_distinct_tiling_raises(): + """get_ir_metadata_for_aggregation raises ValueError for count_distinct.""" + agg = Aggregation(column="item_id", function="count_distinct") + with pytest.raises(ValueError, match="count_distinct does not support tiling"): + get_ir_metadata_for_aggregation(agg, "count_distinct_item_id") diff --git a/sdk/python/tests/unit/test_arrow_error_decorator.py b/sdk/python/tests/unit/test_arrow_error_decorator.py index fc350d34c0a..af753ad8f00 100644 --- a/sdk/python/tests/unit/test_arrow_error_decorator.py +++ b/sdk/python/tests/unit/test_arrow_error_decorator.py @@ -1,8 +1,15 @@ +from unittest.mock import MagicMock, patch + import pyarrow.flight as fl import pytest +from pydantic import ValidationError -from feast.arrow_error_handler import arrow_client_error_handling_decorator -from feast.errors import PermissionNotFoundException +from feast.arrow_error_handler import ( + _get_exception_data, + arrow_client_error_handling_decorator, +) +from feast.errors import FeatureViewNotFoundException, PermissionNotFoundException +from feast.infra.offline_stores.remote import RemoteOfflineStoreConfig permissionError = PermissionNotFoundException("dummy_name", "dummy_project") @@ -31,3 +38,194 @@ def test_rest_error_handling_with_feast_exception(error, expected_raised_error): match=str(expected_raised_error), ): decorated_method(error) + + +class TestArrowClientRetry: + @patch("feast.arrow_error_handler.time.sleep") + def test_retries_on_flight_unavailable_error(self, mock_sleep): + client = MagicMock() + client._connection_retries = 3 + call_count = 0 + + @arrow_client_error_handling_decorator + def flaky_method(self_arg): + nonlocal call_count + call_count += 1 + if call_count < 3: + raise fl.FlightUnavailableError("Connection refused") + return "success" + + result = flaky_method(client) + assert result == "success" + assert call_count == 3 + assert mock_sleep.call_count == 2 + + @patch("feast.arrow_error_handler.time.sleep") + def test_raises_after_max_retries_exhausted(self, mock_sleep): + client = MagicMock() + client._connection_retries = 3 + + @arrow_client_error_handling_decorator + def always_unavailable(self_arg): + raise fl.FlightUnavailableError("Connection refused") + + with pytest.raises(fl.FlightUnavailableError, match="Connection refused"): + always_unavailable(client) + assert mock_sleep.call_count == 3 + + @patch("feast.arrow_error_handler.time.sleep") + def test_respects_connection_retries_from_client(self, mock_sleep): + client = MagicMock() + client._connection_retries = 1 + call_count = 0 + + @arrow_client_error_handling_decorator + def method_on_client(self_arg): + nonlocal call_count + call_count += 1 + raise fl.FlightUnavailableError("Connection refused") + + with pytest.raises(fl.FlightUnavailableError): + method_on_client(client) + + assert call_count == 2 # 1 initial + 1 retry + assert mock_sleep.call_count == 1 + + @patch("feast.arrow_error_handler.time.sleep") + def test_no_retry_on_non_transient_errors(self, mock_sleep): + client = MagicMock() + client._connection_retries = 3 + call_count = 0 + + @arrow_client_error_handling_decorator + def method_with_error(self_arg): + nonlocal call_count + call_count += 1 + raise fl.FlightError("Permanent error") + + with pytest.raises(fl.FlightError, match="Permanent error"): + method_with_error(client) + + assert call_count == 1 + mock_sleep.assert_not_called() + + @patch("feast.arrow_error_handler.time.sleep") + def test_exponential_backoff_timing(self, mock_sleep): + client = MagicMock() + client._connection_retries = 3 + + @arrow_client_error_handling_decorator + def always_unavailable(self_arg): + raise fl.FlightUnavailableError("Connection refused") + + with pytest.raises(fl.FlightUnavailableError): + always_unavailable(client) + + wait_times = [call.args[0] for call in mock_sleep.call_args_list] + assert wait_times == [0.5, 1.0, 2.0] + + @patch("feast.arrow_error_handler.time.sleep") + def test_zero_retries_disables_retry(self, mock_sleep): + client = MagicMock() + client._connection_retries = 0 + call_count = 0 + + @arrow_client_error_handling_decorator + def method_on_client(self_arg): + nonlocal call_count + call_count += 1 + raise fl.FlightUnavailableError("Connection refused") + + with pytest.raises(fl.FlightUnavailableError): + method_on_client(client) + + assert call_count == 1 + mock_sleep.assert_not_called() + + @patch("feast.arrow_error_handler.time.sleep") + def test_no_retry_for_standalone_stream_functions(self, mock_sleep): + """Standalone functions (write_table, read_all) where args[0] is a + writer/reader should not retry since broken streams can't be reused.""" + writer = MagicMock(spec=[]) # no _connection_retries attribute + call_count = 0 + + @arrow_client_error_handling_decorator + def write_table(w): + nonlocal call_count + call_count += 1 + raise fl.FlightUnavailableError("stream broken") + + with pytest.raises(fl.FlightUnavailableError, match="stream broken"): + write_table(writer) + + assert call_count == 1 + mock_sleep.assert_not_called() + + @patch("feast.arrow_error_handler.time.sleep") + def test_negative_connection_retries_treated_as_zero(self, mock_sleep): + """Negative _connection_retries must not skip function execution.""" + client = MagicMock() + client._connection_retries = -1 + call_count = 0 + + @arrow_client_error_handling_decorator + def method_on_client(self_arg): + nonlocal call_count + call_count += 1 + return "ok" + + result = method_on_client(client) + assert result == "ok" + assert call_count == 1 + mock_sleep.assert_not_called() + + def test_config_rejects_negative_connection_retries(self): + with pytest.raises(ValidationError): + RemoteOfflineStoreConfig(host="localhost", connection_retries=-1) + + +class TestGetExceptionData: + def test_non_string_input_returns_empty(self): + assert _get_exception_data(12345) == "" + assert _get_exception_data(None) == "" + assert _get_exception_data(b"bytes") == "" + + def test_no_flight_error_prefix_returns_empty(self): + assert _get_exception_data("some random error") == "" + + def test_flight_error_prefix_without_json_returns_empty(self): + assert _get_exception_data("Flight error: no json here") == "" + + def test_extracts_json_from_flight_error(self): + fv_error = FeatureViewNotFoundException("my_view", "my_project") + error_str = f"Flight error: {fv_error.to_error_detail()}" + result = _get_exception_data(error_str) + assert '"class": "FeatureViewNotFoundException"' in result + assert '"module": "feast.errors"' in result + + def test_extracts_json_with_trailing_text(self): + fv_error = FeatureViewNotFoundException("my_view", "my_project") + error_str = ( + f"Flight error: {fv_error.to_error_detail()}. " + "gRPC client debug context: some extra info" + ) + result = _get_exception_data(error_str) + assert '"class": "FeatureViewNotFoundException"' in result + assert '"module": "feast.errors"' in result + + def test_extracts_json_with_grpc_debug_context_containing_braces(self): + fv_error = FeatureViewNotFoundException("my_view", "my_project") + error_str = ( + f"Flight error: {fv_error.to_error_detail()}. " + "gRPC client debug context: UNKNOWN:Error received from peer " + 'ipv4:127.0.0.1:59930 {grpc_message:"Flight error: ...", ' + 'grpc_status:2, created_time:"2026-03-17T17:32:07"}' + ) + result = _get_exception_data(error_str) + assert '"class": "FeatureViewNotFoundException"' in result + assert '"module": "feast.errors"' in result + from feast.errors import FeastError + + reconstructed = FeastError.from_error_detail(result) + assert reconstructed is not None + assert "my_view" in str(reconstructed) diff --git a/sdk/python/tests/unit/test_demos.py b/sdk/python/tests/unit/test_demos.py new file mode 100644 index 00000000000..52d61b353a2 --- /dev/null +++ b/sdk/python/tests/unit/test_demos.py @@ -0,0 +1,360 @@ +"""Unit tests for feast.demos — demo notebook generation.""" + +import json +import pathlib +import textwrap + +import pytest + +from feast.demos import ( + _extract_store_info, + _find_feature_store_yamls, + _is_operator_client, + copy_demo_notebooks, +) + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +_LOCAL_YAML = textwrap.dedent("""\ + project: local_proj + provider: local + registry: + path: data/registry.db + registry_type: file + offline_store: + type: file + online_store: + type: sqlite + path: data/online_store.db + entity_key_serialization_version: 3 +""") + +_OPERATOR_YAML = textwrap.dedent("""\ + project: remote_proj + provider: local + offline_store: + host: feast-offline.svc.cluster.local + port: 80 + type: remote + online_store: + path: http://feast-online.svc.cluster.local:80 + type: remote + registry: + path: feast-registry.svc.cluster.local:80 + registry_type: remote + auth: + type: oidc + entity_key_serialization_version: 3 +""") + +_VECTOR_YAML = textwrap.dedent("""\ + project: vec_proj + provider: local + registry: + path: data/registry.db + registry_type: file + offline_store: + type: file + online_store: + type: pgvector + vector_enabled: true + embedding_dim: 512 + entity_key_serialization_version: 3 +""") + + +def _write(tmp_path: pathlib.Path, rel: str, content: str) -> pathlib.Path: + p = tmp_path / rel + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text(content) + return p + + +def _sections(nb: dict) -> list[str]: + """Return the first line of every markdown cell that starts with #.""" + return [ + "".join(cell["source"]).splitlines()[0] + for cell in nb["cells"] + if cell["cell_type"] == "markdown" and "".join(cell["source"]).startswith("#") + ] + + +# --------------------------------------------------------------------------- +# _extract_store_info +# --------------------------------------------------------------------------- + + +class TestExtractStoreInfo: + def test_local_defaults(self): + info = _extract_store_info({}) + assert info["project"] == "my_feast_project" + assert info["provider"] == "local" + assert info["online_store_type"] == "sqlite" + assert info["offline_store_type"] == "file" + assert info["registry_type"] == "file" + assert info["auth_type"] == "no_auth" + assert info["vector_enabled"] is False + assert info["embedding_dim"] is None + + def test_operator_client_yaml(self): + config = { + "project": "sample", + "provider": "local", + "offline_store": {"type": "remote", "host": "h", "port": 80}, + "online_store": {"type": "remote", "path": "http://h:80"}, + "registry": {"registry_type": "remote", "path": "h:80"}, + "auth": {"type": "oidc"}, + } + info = _extract_store_info(config) + assert info["registry_type"] == "remote" + assert info["online_store_type"] == "remote" + assert info["offline_store_type"] == "remote" + assert info["auth_type"] == "oidc" + + def test_registry_type_key_takes_priority_over_type(self): + config = {"registry": {"registry_type": "remote", "type": "file"}} + info = _extract_store_info(config) + assert info["registry_type"] == "remote" + + def test_registry_type_fallback_to_type(self): + config = {"registry": {"type": "snowflake"}} + info = _extract_store_info(config) + assert info["registry_type"] == "snowflake" + + def test_string_registry_path_stays_file(self): + info = _extract_store_info({"registry": "data/registry.db"}) + assert info["registry_type"] == "file" + + def test_vector_enabled(self): + config = { + "online_store": { + "type": "pgvector", + "vector_enabled": True, + "embedding_dim": 512, + } + } + info = _extract_store_info(config) + assert info["vector_enabled"] is True + assert info["embedding_dim"] == 512 + + def test_online_store_as_string(self): + info = _extract_store_info({"online_store": "Redis"}) + assert info["online_store_type"] == "redis" + + def test_offline_store_as_string(self): + info = _extract_store_info({"offline_store": "BigQuery"}) + assert info["offline_store_type"] == "bigquery" + + +# --------------------------------------------------------------------------- +# _is_operator_client +# --------------------------------------------------------------------------- + + +class TestIsOperatorClient: + def _info(self, registry="remote", online="remote", offline="remote"): + return { + "registry_type": registry, + "online_store_type": online, + "offline_store_type": offline, + } + + def test_all_remote_is_operator(self): + assert _is_operator_client(self._info()) is True + + def test_local_registry_not_operator(self): + assert _is_operator_client(self._info(registry="file")) is False + + def test_local_online_not_operator(self): + assert _is_operator_client(self._info(online="sqlite")) is False + + def test_local_offline_not_operator(self): + assert _is_operator_client(self._info(offline="file")) is False + + +# --------------------------------------------------------------------------- +# _find_feature_store_yamls +# --------------------------------------------------------------------------- + + +class TestFindFeatureStoreYamls: + def test_direct(self, tmp_path): + _write(tmp_path, "feature_store.yaml", "project: p") + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 1 + assert found[0].name == "feature_store.yaml" + + def test_feast_config_root(self, tmp_path): + _write(tmp_path, "feast-config/feature_store.yaml", "project: p") + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 1 + + def test_feast_config_multiple_files(self, tmp_path): + _write(tmp_path, "feast-config/rag.yaml", "project: rag") + _write(tmp_path, "feast-config/rec.yml", "project: rec") + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 2 + + def test_feast_config_any_extension(self, tmp_path): + _write(tmp_path, "feast-config/project_a.yaml", "project: a") + _write(tmp_path, "feast-config/project_b", "project: b") + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 2 + + def test_feast_config_ignores_directories(self, tmp_path): + _write(tmp_path, "feast-config/valid.yaml", "project: p") + (tmp_path / "feast-config" / "subdir").mkdir() + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 1 + + def test_multiple_sources(self, tmp_path): + _write(tmp_path, "feature_store.yaml", "project: root") + _write(tmp_path, "feast-config/a.yaml", "project: a") + _write(tmp_path, "feast-config/b", "project: b") + found = _find_feature_store_yamls(tmp_path) + assert len(found) == 3 + + def test_no_yaml_returns_empty(self, tmp_path): + assert _find_feature_store_yamls(tmp_path) == [] + + +# --------------------------------------------------------------------------- +# copy_demo_notebooks — file generation +# --------------------------------------------------------------------------- + + +class TestCopyDemoNotebooks: + def test_generates_notebooks(self, tmp_path): + _write(tmp_path, "feature_store.yaml", _LOCAL_YAML) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + + assert (out / "local_proj" / "01_feature_store_overview.ipynb").exists() + assert (out / "local_proj" / "02_historical_features_training.ipynb").exists() + assert (out / "local_proj" / "03_online_features_serving.ipynb").exists() + + def test_valid_notebook_json(self, tmp_path): + _write(tmp_path, "feature_store.yaml", _LOCAL_YAML) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + + nb = json.loads( + (out / "local_proj" / "01_feature_store_overview.ipynb").read_text() + ) + assert nb["nbformat"] == 4 + assert isinstance(nb["cells"], list) + + def test_raises_if_output_exists(self, tmp_path): + _write(tmp_path, "feature_store.yaml", _LOCAL_YAML) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + + with pytest.raises(FileExistsError): + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + + def test_overwrite_flag(self, tmp_path): + _write(tmp_path, "feature_store.yaml", _LOCAL_YAML) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + copy_demo_notebooks( + output_dir=str(out), repo_path=str(tmp_path), overwrite=True + ) + + def test_no_yaml_returns_without_creating_output(self, tmp_path): + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + assert not out.exists() + + def test_multiple_projects(self, tmp_path): + _write( + tmp_path, + "feast-config/proj_a.yaml", + "project: proj_a\nprovider: local\n", + ) + _write( + tmp_path, + "feast-config/proj_b.yaml", + "project: proj_b\nprovider: local\n", + ) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + assert (out / "proj_a").is_dir() + assert (out / "proj_b").is_dir() + + +# --------------------------------------------------------------------------- +# Notebook content — section headings +# --------------------------------------------------------------------------- + + +class TestNotebookContent: + def _notebooks(self, tmp_path, yaml_content): + _write(tmp_path, "feature_store.yaml", yaml_content) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + project = _extract_store_info(__import__("yaml").safe_load(yaml_content))[ + "project" + ] + return { + name: json.loads((out / project / name).read_text()) + for name in [ + "01_feature_store_overview.ipynb", + "02_historical_features_training.ipynb", + "03_online_features_serving.ipynb", + ] + } + + def test_local_overview_has_apply_section(self, tmp_path): + nbs = self._notebooks(tmp_path, _LOCAL_YAML) + sections = _sections(nbs["01_feature_store_overview.ipynb"]) + assert any("Apply Feature Definitions" in s for s in sections) + + def test_remote_overview_has_registry_sync(self, tmp_path): + nbs = self._notebooks(tmp_path, _OPERATOR_YAML) + sections = _sections(nbs["01_feature_store_overview.ipynb"]) + assert any("Registry Sync" in s for s in sections) + + def test_historical_no_apply_section(self, tmp_path): + nbs = self._notebooks(tmp_path, _LOCAL_YAML) + sections = _sections(nbs["02_historical_features_training.ipynb"]) + assert not any("Apply" in s for s in sections) + + def test_online_no_apply_section(self, tmp_path): + nbs = self._notebooks(tmp_path, _LOCAL_YAML) + sections = _sections(nbs["03_online_features_serving.ipynb"]) + assert not any("Apply" in s for s in sections) + + def test_vector_notebook_has_vector_section(self, tmp_path): + nbs = self._notebooks(tmp_path, _VECTOR_YAML) + sections = _sections(nbs["03_online_features_serving.ipynb"]) + assert any("Vector" in s for s in sections) + + def test_non_vector_notebook_no_vector_section(self, tmp_path): + nbs = self._notebooks(tmp_path, _LOCAL_YAML) + sections = _sections(nbs["03_online_features_serving.ipynb"]) + assert not any("Vector" in s for s in sections) + + def test_auth_section_present_for_oidc(self, tmp_path): + nbs = self._notebooks(tmp_path, _OPERATOR_YAML) + sections = _sections(nbs["03_online_features_serving.ipynb"]) + assert any("Authentication" in s for s in sections) + + def test_auth_section_absent_for_no_auth(self, tmp_path): + nbs = self._notebooks(tmp_path, _LOCAL_YAML) + sections = _sections(nbs["03_online_features_serving.ipynb"]) + assert not any("Authentication" in s for s in sections) + + def test_path_setup_cell_contains_yaml_path(self, tmp_path): + _write(tmp_path, "feature_store.yaml", _LOCAL_YAML) + out = tmp_path / "out" + copy_demo_notebooks(output_dir=str(out), repo_path=str(tmp_path)) + nb = json.loads( + (out / "local_proj" / "01_feature_store_overview.ipynb").read_text() + ) + code_sources = [ + "".join(c["source"]) for c in nb["cells"] if c["cell_type"] == "code" + ] + yaml_path = str((tmp_path / "feature_store.yaml").resolve()) + assert any(yaml_path in src for src in code_sources) diff --git a/sdk/python/tests/unit/test_doc_embedder.py b/sdk/python/tests/unit/test_doc_embedder.py new file mode 100644 index 00000000000..10f72c82d02 --- /dev/null +++ b/sdk/python/tests/unit/test_doc_embedder.py @@ -0,0 +1,657 @@ +import os +from unittest.mock import MagicMock, Mock, patch + +import numpy as np +import pandas as pd +import pytest + +from feast.chunker import BaseChunker, ChunkingConfig, TextChunker +from feast.doc_embedder import ( + DocEmbedder, + SchemaTransformFn, + default_schema_transform_fn, +) +from feast.embedder import BaseEmbedder, EmbeddingConfig, MultiModalEmbedder + + +@pytest.fixture +def sample_documents_df(): + """Small DataFrame with 3 documents of varying lengths.""" + return pd.DataFrame( + { + "id": ["doc1", "doc2", "doc3"], + "text": [ + " ".join([f"word{i}" for i in range(150)]), + " ".join([f"term{i}" for i in range(200)]), + " ".join([f"item{i}" for i in range(50)]), + ], + "type": ["article", "paper", "note"], + } + ) + + +class TestTextChunker: + def test_basic_chunking(self): + """Given ~200 words, returns chunks with correct keys and count.""" + chunker = TextChunker() + text = " ".join([f"word{i}" for i in range(200)]) + + chunks = chunker.load_parse_and_chunk( + source=text, source_id="doc1", source_column="text" + ) + + assert len(chunks) > 0 + for chunk in chunks: + assert "chunk_id" in chunk + assert "original_id" in chunk + assert "text" in chunk + assert "chunk_index" in chunk + assert chunk["original_id"] == "doc1" + + assert len(chunks) == 3 + assert chunks[0]["chunk_id"] == "doc1_0" + assert chunks[1]["chunk_id"] == "doc1_1" + assert chunks[2]["chunk_id"] == "doc1_2" + assert chunks[0]["chunk_index"] == 0 + assert chunks[2]["chunk_index"] == 2 + + def test_overlap(self): + """Consecutive chunks share exactly chunk_overlap words.""" + config = ChunkingConfig( + chunk_size=10, chunk_overlap=3, min_chunk_size=3, max_chunk_chars=None + ) + chunker = TextChunker(config=config) + text = " ".join([f"w{i}" for i in range(20)]) + + chunks = chunker.load_parse_and_chunk( + source=text, source_id="doc1", source_column="text" + ) + assert len(chunks) >= 2 + + words_0 = chunks[0]["text"].split() + words_1 = chunks[1]["text"].split() + + assert words_0[-3:] == words_1[:3] + + def test_min_chunk_size_filters_small_trailing(self): + """Trailing chunk smaller than min_chunk_size is dropped.""" + config = ChunkingConfig( + chunk_size=10, chunk_overlap=0, min_chunk_size=5, max_chunk_chars=None + ) + chunker = TextChunker(config=config) + text = " ".join([f"w{i}" for i in range(13)]) + + chunks = chunker.load_parse_and_chunk( + source=text, source_id="doc1", source_column="text" + ) + + assert len(chunks) == 1 + + def test_max_chunk_chars_truncation(self): + """Chunks exceeding max_chunk_chars are truncated.""" + config = ChunkingConfig( + chunk_size=100, chunk_overlap=0, min_chunk_size=1, max_chunk_chars=50 + ) + chunker = TextChunker(config=config) + text = " ".join([f"longword{i}" for i in range(200)]) + + chunks = chunker.load_parse_and_chunk( + source=text, source_id="doc1", source_column="text" + ) + + assert len(chunks) > 0 + for chunk in chunks: + assert len(chunk["text"]) <= 50 + + def test_empty_text_returns_no_chunks(self): + """Empty string produces zero chunks.""" + chunker = TextChunker() + + chunks = chunker.load_parse_and_chunk( + source="", source_id="doc1", source_column="text" + ) + + assert chunks == [] + + def test_chunk_dataframe(self, sample_documents_df): + """Chunking a multi-row DataFrame returns a flattened DataFrame.""" + chunker = TextChunker() + + result = chunker.chunk_dataframe( + df=sample_documents_df, + id_column="id", + source_column="text", + type_column="type", + ) + + assert isinstance(result, pd.DataFrame) + assert "chunk_id" in result.columns + assert "original_id" in result.columns + assert "text" in result.columns + assert "chunk_index" in result.columns + assert len(result) >= len(sample_documents_df) + assert set(result["original_id"].unique()) == {"doc1", "doc2", "doc3"} + + +def test_base_chunker_cannot_instantiate(): + """BaseChunker is abstract and cannot be instantiated directly.""" + with pytest.raises(TypeError): + BaseChunker() + + +def test_base_embedder_cannot_instantiate(): + """BaseEmbedder is abstract and cannot be instantiated directly.""" + with pytest.raises(TypeError): + BaseEmbedder() + + +class TestMultiModalEmbedder: + def test_supported_modalities(self): + """After init, supported_modalities returns text and image.""" + embedder = MultiModalEmbedder() + modalities = embedder.supported_modalities + + assert "text" in modalities + assert "image" in modalities + + def test_unsupported_modality_raises(self): + """Calling embed with unsupported modality raises ValueError.""" + embedder = MultiModalEmbedder() + + with pytest.raises(ValueError, match="Unsupported modality: 'video'"): + embedder.embed(["test"], "video") + + def test_text_embed_mocked(self): + """Text embedding calls encode with correct batch_size and show_progress.""" + embedder = MultiModalEmbedder() + + mock_model = MagicMock() + mock_model.encode.return_value = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) + embedder._text_model = mock_model + + result = embedder.embed(["hello", "world"], "text") + + mock_model.encode.assert_called_once_with( + ["hello", "world"], + batch_size=64, + show_progress_bar=True, + ) + assert result.shape == (2, 3) + + def test_text_embed_custom_config(self): + """Text embedding respects custom EmbeddingConfig values.""" + config = EmbeddingConfig(batch_size=16, show_progress=False) + embedder = MultiModalEmbedder(config=config) + + mock_model = MagicMock() + mock_model.encode.return_value = np.array([[0.1, 0.2]]) + embedder._text_model = mock_model + + embedder.embed(["hello"], "text") + + mock_model.encode.assert_called_once_with( + ["hello"], + batch_size=16, + show_progress_bar=False, + ) + + def test_lazy_loading(self): + """Models are None until first accessed.""" + embedder = MultiModalEmbedder() + + assert embedder._text_model is None + assert embedder._image_model is None + assert embedder._image_processor is None + + def test_get_embedding_dim_text(self): + """get_embedding_dim for text delegates to text_model.""" + embedder = MultiModalEmbedder() + mock_model = MagicMock() + mock_model.get_sentence_embedding_dimension.return_value = 384 + embedder._text_model = mock_model + + assert embedder.get_embedding_dim("text") == 384 + mock_model.get_sentence_embedding_dimension.assert_called_once() + + def test_get_embedding_dim_unknown_modality(self): + """get_embedding_dim returns None for unrecognized modalities.""" + embedder = MultiModalEmbedder() + + assert embedder.get_embedding_dim("audio") is None + + def test_embed_dataframe(self): + """embed_dataframe adds embedding columns via column_mapping.""" + embedder = MultiModalEmbedder() + embedder.embed = Mock(return_value=np.array([[0.1, 0.2], [0.3, 0.4]])) + + df = pd.DataFrame({"text": ["hello", "world"], "id": [1, 2]}) + result = embedder.embed_dataframe( + df, column_mapping={"text": ("text", "text_embedding")} + ) + + assert "text_embedding" in result.columns + assert len(result) == 2 + embedder.embed.assert_called_once_with(["hello", "world"], "text") + + +def test_schema_transform_fn_protocol_check(): + """A matching function is recognized as SchemaTransformFn.""" + + def my_fn(df: pd.DataFrame) -> pd.DataFrame: + return df + + assert isinstance(my_fn, SchemaTransformFn) + + +def test_default_schema_transform_fn_output(): + """default_schema_transform_fn transforms columns correctly.""" + input_df = pd.DataFrame( + { + "chunk_id": ["c1", "c2"], + "text": ["hello", "world"], + "text_embedding": [[0.1, 0.2], [0.3, 0.4]], + "original_id": ["doc1", "doc1"], + } + ) + + result = default_schema_transform_fn(input_df) + + assert list(result.columns) == [ + "passage_id", + "text", + "embedding", + "event_timestamp", + "source_id", + ] + assert result["passage_id"].tolist() == ["c1", "c2"] + assert result["text"].tolist() == ["hello", "world"] + assert result["embedding"].tolist() == [[0.1, 0.2], [0.3, 0.4]] + assert result["source_id"].tolist() == ["doc1", "doc1"] + assert len(result["event_timestamp"]) == 2 + + +class TestDocEmbedder: + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + def test_init_no_feature_view(self, mock_load_config, mock_apply_total, tmp_path): + """With create_feature_view=False, generate_repo_file is not called.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + + with patch("feast.doc_embedder.generate_repo_file") as mock_gen: + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + feature_view_name="test_view", + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=False, + ) + + mock_gen.assert_not_called() + assert doc_embedder.repo_path == str(tmp_path) + assert doc_embedder.feature_view_name == "test_view" + assert doc_embedder.chunker is mock_chunker + assert doc_embedder.embedder is mock_embedder + assert doc_embedder.schema_transform_fn is default_schema_transform_fn + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + def test_init_creates_feature_view( + self, mock_load_config, mock_apply_total, tmp_path + ): + """With create_feature_view=True, generate_repo_file and apply_repo are called.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + mock_embedder.get_embedding_dim.return_value = None + + with patch("feast.doc_embedder.generate_repo_file") as mock_gen: + DocEmbedder( + repo_path=str(tmp_path), + feature_view_name="test_view", + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=True, + ) + + mock_gen.assert_called_once_with( + repo_path=str(tmp_path), + feature_view_name="test_view", + vector_length=384, + ) + mock_load_config.assert_called_once() + mock_apply_total.assert_called_once() + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + def test_init_creates_feature_view_with_explicit_vector_length( + self, mock_load_config, mock_apply_total, tmp_path + ): + """Explicit vector_length overrides auto-detection.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + + with patch("feast.doc_embedder.generate_repo_file") as mock_gen: + DocEmbedder( + repo_path=str(tmp_path), + feature_view_name="test_view", + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=True, + vector_length=256, + ) + + mock_gen.assert_called_once_with( + repo_path=str(tmp_path), + feature_view_name="test_view", + vector_length=256, + ) + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + def test_init_creates_feature_view_auto_detects_vector_length( + self, mock_load_config, mock_apply_total, tmp_path + ): + """Auto-detected vector_length from embedder is used when not explicitly set.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + mock_embedder.get_embedding_dim.return_value = 512 + + with patch("feast.doc_embedder.generate_repo_file") as mock_gen: + DocEmbedder( + repo_path=str(tmp_path), + feature_view_name="test_view", + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=True, + ) + + mock_gen.assert_called_once_with( + repo_path=str(tmp_path), + feature_view_name="test_view", + vector_length=512, + ) + mock_embedder.get_embedding_dim.assert_called_once_with("text") + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + @patch("feast.feature_store.FeatureStore") + def test_embed_documents_full_chain( + self, mock_fs_cls, mock_load_config, mock_apply_total, tmp_path + ): + """embed_documents wires chunk -> embed -> schema_transform -> save correctly.""" + mock_chunker = MagicMock(spec=BaseChunker) + chunked_df = pd.DataFrame( + { + "chunk_id": ["doc1_0", "doc1_1"], + "original_id": ["doc1", "doc1"], + "text": ["chunk text 1", "chunk text 2"], + "chunk_index": [0, 1], + } + ) + mock_chunker.chunk_dataframe.return_value = chunked_df + + mock_embedder = MagicMock(spec=BaseEmbedder) + embedded_df = chunked_df.copy() + embedded_df["text_embedding"] = [[0.1, 0.2], [0.3, 0.4]] + mock_embedder.embed_dataframe.return_value = embedded_df + + transformed_df = pd.DataFrame( + { + "passage_id": ["doc1_0", "doc1_1"], + "text": ["chunk text 1", "chunk text 2"], + "embedding": [[0.1, 0.2], [0.3, 0.4]], + "source_id": ["doc1", "doc1"], + } + ) + logical_fn_tracker = MagicMock() + + def mock_logical_fn(df: pd.DataFrame) -> pd.DataFrame: + logical_fn_tracker(df) + return transformed_df + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=mock_chunker, + embedder=mock_embedder, + schema_transform_fn=mock_logical_fn, + create_feature_view=False, + ) + + input_df = pd.DataFrame( + { + "id": ["doc1"], + "text": ["some long document text"], + "type": ["article"], + } + ) + + result = doc_embedder.embed_documents( + documents=input_df, + id_column="id", + source_column="text", + type_column="type", + ) + + mock_chunker.chunk_dataframe.assert_called_once() + chunk_kwargs = mock_chunker.chunk_dataframe.call_args[1] + assert chunk_kwargs["id_column"] == "id" + assert chunk_kwargs["source_column"] == "text" + assert chunk_kwargs["type_column"] == "type" + + mock_embedder.embed_dataframe.assert_called_once() + embed_args = mock_embedder.embed_dataframe.call_args + pd.testing.assert_frame_equal(embed_args[0][0], chunked_df) + assert embed_args[1]["column_mapping"] == {"text": ("text", "text_embedding")} + + logical_fn_tracker.assert_called_once() + pd.testing.assert_frame_equal(logical_fn_tracker.call_args[0][0], embedded_df) + + mock_fs_cls.return_value.write_to_online_store.assert_called_once() + save_kwargs = mock_fs_cls.return_value.write_to_online_store.call_args[1] + assert save_kwargs["feature_view_name"] == "text_feature_view" + + pd.testing.assert_frame_equal(result, transformed_df) + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + @patch("feast.feature_store.FeatureStore") + def test_embed_documents_default_column_mapping( + self, mock_fs_cls, mock_load_config, mock_apply_total, tmp_path + ): + """When column_mapping=None, default mapping is used.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_chunker.chunk_dataframe.return_value = pd.DataFrame( + { + "chunk_id": ["c1"], + "original_id": ["d1"], + "text": ["t"], + "chunk_index": [0], + } + ) + + mock_embedder = MagicMock(spec=BaseEmbedder) + mock_embedder.embed_dataframe.return_value = pd.DataFrame( + { + "chunk_id": ["c1"], + "original_id": ["d1"], + "text": ["t"], + "chunk_index": [0], + "text_embedding": [[0.1]], + } + ) + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=False, + ) + + doc_embedder.embed_documents( + documents=pd.DataFrame({"id": ["d1"], "text": ["t"]}), + id_column="id", + source_column="text", + column_mapping=None, + ) + + embed_call = mock_embedder.embed_dataframe.call_args + assert embed_call[1]["column_mapping"] == {"text": ("text", "text_embedding")} + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + @patch("feast.feature_store.FeatureStore") + def test_embed_documents_custom_column_mapping( + self, mock_fs_cls, mock_load_config, mock_apply_total, tmp_path + ): + """Custom column_mapping is forwarded to the embedder.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_chunker.chunk_dataframe.return_value = pd.DataFrame( + { + "chunk_id": ["c1"], + "original_id": ["d1"], + "content": ["t"], + "chunk_index": [0], + } + ) + + mock_embedder = MagicMock(spec=BaseEmbedder) + mock_embedder.embed_dataframe.return_value = pd.DataFrame( + { + "chunk_id": ["c1"], + "original_id": ["d1"], + "content": ["t"], + "chunk_index": [0], + "content_embedding": [[0.1]], + } + ) + + def mock_logical_fn(df: pd.DataFrame) -> pd.DataFrame: + return pd.DataFrame({"passage_id": ["c1"], "embedding": [[0.1]]}) + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=mock_chunker, + embedder=mock_embedder, + schema_transform_fn=mock_logical_fn, + create_feature_view=False, + ) + + custom_mapping = ("text", "content_embedding") + doc_embedder.embed_documents( + documents=pd.DataFrame({"id": ["d1"], "content": ["t"]}), + id_column="id", + source_column="content", + column_mapping=custom_mapping, + ) + + embed_call = mock_embedder.embed_dataframe.call_args + assert embed_call[1]["column_mapping"] == { + "content": ("text", "content_embedding") + } + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + def test_apply_repo_restores_cwd( + self, mock_load_config, mock_apply_total, tmp_path + ): + """apply_repo restores os.getcwd() even if apply_total changes it.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=False, + ) + + cwd_before = os.getcwd() + mock_apply_total.side_effect = lambda **kwargs: os.chdir(str(tmp_path)) + + doc_embedder.apply_repo() + + assert os.getcwd() == cwd_before + + @patch("feast.repo_operations.apply_total") + @patch("feast.repo_config.load_repo_config") + @patch("feast.feature_store.FeatureStore") + def test_save_to_online_store( + self, mock_fs_cls, mock_load_config, mock_apply_total, tmp_path + ): + """save_to_online_store creates FeatureStore and writes data.""" + mock_chunker = MagicMock(spec=BaseChunker) + mock_embedder = MagicMock(spec=BaseEmbedder) + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=mock_chunker, + embedder=mock_embedder, + create_feature_view=False, + ) + + test_df = pd.DataFrame({"col": [1, 2]}) + doc_embedder.save_to_online_store(df=test_df, feature_view_name="my_view") + + mock_fs_cls.assert_called_with(repo_path=str(tmp_path)) + mock_fs_cls.return_value.write_to_online_store.assert_called_once_with( + feature_view_name="my_view", + df=test_df, + ) + + +@patch("feast.repo_operations.apply_total") +@patch("feast.repo_config.load_repo_config") +@patch("feast.feature_store.FeatureStore") +def test_end_to_end_pipeline(mock_fs_cls, mock_load_config, mock_apply_total, tmp_path): + """Full pipeline: real TextChunker + mocked embedder + default schema transform.""" + chunker = TextChunker( + config=ChunkingConfig( + chunk_size=10, + chunk_overlap=2, + min_chunk_size=3, + max_chunk_chars=None, + ) + ) + + mock_embedder = MagicMock(spec=BaseEmbedder) + + def fake_embed_dataframe(df, column_mapping): + df = df.copy() + for _src_col, (_modality, out_col) in column_mapping.items(): + df[out_col] = [[0.1, 0.2, 0.3]] * len(df) + return df + + mock_embedder.embed_dataframe.side_effect = fake_embed_dataframe + + doc_embedder = DocEmbedder( + repo_path=str(tmp_path), + chunker=chunker, + embedder=mock_embedder, + schema_transform_fn=default_schema_transform_fn, + create_feature_view=False, + ) + + documents = pd.DataFrame( + { + "id": ["doc1", "doc2"], + "text": [ + " ".join([f"word{i}" for i in range(30)]), + " ".join([f"term{i}" for i in range(25)]), + ], + } + ) + + result = doc_embedder.embed_documents( + documents=documents, + id_column="id", + source_column="text", + ) + + assert "passage_id" in result.columns + assert "text" in result.columns + assert "embedding" in result.columns + assert "event_timestamp" in result.columns + assert "source_id" in result.columns + assert len(result) > 2 + assert set(result["source_id"].unique()) == {"doc1", "doc2"} + mock_fs_cls.return_value.write_to_online_store.assert_called_once() diff --git a/sdk/python/tests/unit/test_feature_resolution_cache.py b/sdk/python/tests/unit/test_feature_resolution_cache.py new file mode 100644 index 00000000000..f77a4c1e0ac --- /dev/null +++ b/sdk/python/tests/unit/test_feature_resolution_cache.py @@ -0,0 +1,171 @@ +"""Tests for the feature resolution cache in feast.utils._get_cached_request_context.""" + +from datetime import datetime, timedelta, timezone +from unittest.mock import MagicMock, patch + +import pytest + +import feast.utils as utils + + +@pytest.fixture(autouse=True) +def _clear_cache(): + """Reset the module-level cache before each test.""" + with utils._feature_resolution_cache_lock: + utils._feature_resolution_cache.clear() + utils._feature_resolution_registry_ts = None + yield + with utils._feature_resolution_cache_lock: + utils._feature_resolution_cache.clear() + utils._feature_resolution_registry_ts = None + + +def _make_registry(ts: datetime, ttl_seconds: int = 600, cache_valid: bool = True): + reg = MagicMock() + reg.cached_registry_proto_created = ts + reg.cached_registry_proto_ttl = timedelta(seconds=ttl_seconds) + reg.is_cache_valid.return_value = cache_valid + return reg + + +def _make_context(): + """Return a plausible fake context tuple matching _get_online_request_context output.""" + return ( + ["fv:feat1"], # feature_refs + [], # requested_on_demand_feature_views + {}, # entity_name_to_join_key_map + {}, # entity_type_map + {"user_id"}, # join_keys_set + [("fv_table", ["feat1"])], # grouped_refs + {"feat1"}, # requested_result_row_names + set(), # needed_request_data + False, # entityless_case + ) + + +class TestFeatureResolutionCache: + @patch("feast.utils._get_online_request_context") + def test_second_call_uses_cache(self, mock_ctx): + """Identical feature requests within the same registry generation + should only call _get_online_request_context once.""" + mock_ctx.return_value = _make_context() + now = datetime.now(tz=timezone.utc) + registry = _make_registry(now, ttl_seconds=600) + features = ["fv:feat1"] + + utils._get_cached_request_context(registry, "proj", features, False) + utils._get_cached_request_context(registry, "proj", features, False) + + mock_ctx.assert_called_once() + + @patch("feast.utils._get_online_request_context") + def test_different_features_are_separate_cache_entries(self, mock_ctx): + """Different feature lists should be cached independently.""" + mock_ctx.return_value = _make_context() + now = datetime.now(tz=timezone.utc) + registry = _make_registry(now, ttl_seconds=600) + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + utils._get_cached_request_context(registry, "proj", ["fv:feat2"], False) + + assert mock_ctx.call_count == 2 + + @patch("feast.utils._get_online_request_context") + def test_cache_cleared_on_registry_refresh(self, mock_ctx): + """When registry.cached_registry_proto_created changes, the cache + must be cleared and _get_online_request_context called again.""" + mock_ctx.return_value = _make_context() + t1 = datetime.now(tz=timezone.utc) + t2 = t1 + timedelta(seconds=30) + + registry = _make_registry(t1, ttl_seconds=600) + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + assert mock_ctx.call_count == 1 + + registry.cached_registry_proto_created = t2 + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + assert mock_ctx.call_count == 2 + + @patch("feast.utils._get_online_request_context") + def test_cache_bypassed_when_registry_ttl_expired(self, mock_ctx): + """If the registry's own cache has expired (TTL), the feature + resolution cache must NOT be used even if the timestamp matches.""" + mock_ctx.return_value = _make_context() + past = datetime.now(tz=timezone.utc) - timedelta(seconds=120) + registry = _make_registry(past, ttl_seconds=60, cache_valid=False) + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + + assert mock_ctx.call_count == 2 + + @patch("feast.utils._get_online_request_context") + def test_cache_works_with_infinite_ttl(self, mock_ctx): + """TTL of 0 means infinite cache — should cache normally.""" + mock_ctx.return_value = _make_context() + past = datetime.now(tz=timezone.utc) - timedelta(hours=24) + registry = _make_registry(past, ttl_seconds=0) + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + + mock_ctx.assert_called_once() + + @patch("feast.utils._get_online_request_context") + def test_no_cache_without_registry_timestamp(self, mock_ctx): + """Registries without cached_registry_proto_created should bypass + caching entirely.""" + mock_ctx.return_value = _make_context() + registry = MagicMock(spec=[]) + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + + assert mock_ctx.call_count == 2 + + @patch("feast.utils._get_online_request_context") + def test_returned_result_row_names_is_mutable_copy(self, mock_ctx): + """requested_result_row_names is stored as frozenset in cache; + each call to _prepare_entities_to_read_from_online_store should + get a fresh mutable copy so mutations don't leak between requests.""" + mock_ctx.return_value = _make_context() + now = datetime.now(tz=timezone.utc) + registry = _make_registry(now, ttl_seconds=600) + + r1 = utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + r2 = utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + + result_row_names_1 = r1[6] + result_row_names_2 = r2[6] + assert isinstance(result_row_names_1, frozenset) + assert result_row_names_1 == result_row_names_2 + + @patch("feast.utils._get_online_request_context") + def test_feature_service_cached_separately(self, mock_ctx): + """FeatureService objects should be cached by name.""" + mock_ctx.return_value = _make_context() + now = datetime.now(tz=timezone.utc) + registry = _make_registry(now, ttl_seconds=600) + + fs = MagicMock() + fs.name = "credit_scoring_v1" + + utils._get_cached_request_context(registry, "proj", fs, False) + utils._get_cached_request_context(registry, "proj", fs, False) + + mock_ctx.assert_called_once() + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + assert mock_ctx.call_count == 2 + + @patch("feast.utils._get_online_request_context") + def test_full_feature_names_flag_is_cache_key(self, mock_ctx): + """full_feature_names=True vs False should be different cache entries.""" + mock_ctx.return_value = _make_context() + now = datetime.now(tz=timezone.utc) + registry = _make_registry(now, ttl_seconds=600) + + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], False) + utils._get_cached_request_context(registry, "proj", ["fv:feat1"], True) + + assert mock_ctx.call_count == 2 diff --git a/sdk/python/tests/unit/test_feature_server.py b/sdk/python/tests/unit/test_feature_server.py index c271fad7fad..0fef1aea463 100644 --- a/sdk/python/tests/unit/test_feature_server.py +++ b/sdk/python/tests/unit/test_feature_server.py @@ -24,7 +24,13 @@ from feast.errors import PushSourceNotFoundException from feast.feature_server import get_app from feast.online_response import OnlineResponse -from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesResponse +from feast.protos.feast.serving.ServingService_pb2 import ( + FeatureList, + FieldStatus, + GetOnlineFeaturesResponse, + GetOnlineFeaturesResponseMetadata, +) +from feast.protos.feast.types.Value_pb2 import Value from feast.utils import _utc_now from tests.foo_provider import FooProvider from tests.utils.cli_repo_creator import CliRunner, get_example_repo @@ -664,3 +670,82 @@ def load_artifacts(app: FastAPI): assert lookup_tables["sentiment_labels"]["LABEL_1"] == "neutral" assert lookup_tables["sentiment_labels"]["LABEL_2"] == "positive" assert lookup_tables["emoji_sentiment"]["😊"] == "positive" + + +def _build_online_response_with_features(): + """Build a GetOnlineFeaturesResponse with real feature data.""" + feature_names = ["driver_id", "driver_lat", "driver_long"] + proto = GetOnlineFeaturesResponse( + metadata=GetOnlineFeaturesResponseMetadata( + feature_names=FeatureList(val=feature_names), + ), + results=[ + GetOnlineFeaturesResponse.FeatureVector( + values=[Value(int64_val=123)], + statuses=[FieldStatus.PRESENT], + ), + GetOnlineFeaturesResponse.FeatureVector( + values=[Value(double_val=42.0)], + statuses=[FieldStatus.PRESENT], + ), + GetOnlineFeaturesResponse.FeatureVector( + values=[Value(double_val=-73.5)], + statuses=[FieldStatus.PRESENT], + ), + ], + status=True, + ) + return OnlineResponse(proto) + + +@pytest.mark.parametrize("async_online_read", [True, False]) +def test_get_online_features_non_empty_response(async_online_read, mock_fs_factory): + """Non-empty responses must pass FastAPI response_model validation (no 500).""" + fs = mock_fs_factory(online_read=async_online_read) + response_obj = _build_online_response_with_features() + fs.get_online_features = MagicMock(return_value=response_obj) + fs.get_online_features_async = AsyncMock(return_value=response_obj) + + client = TestClient(get_app(fs)) + resp = client.post("/get-online-features", json=get_online_features_body()) + assert resp.status_code == 200 + + body = resp.json() + assert body["metadata"]["feature_names"] == [ + "driver_id", + "driver_lat", + "driver_long", + ] + assert len(body["results"]) == 3 + assert body["results"][0]["values"] == [123] + assert body["results"][0]["statuses"] == ["PRESENT"] + + +def test_metadata_model_accepts_raw_proto_dict(): + """OnlineFeaturesMetadataResponse must accept the un-patched MessageToDict + format where feature_names is ``{"val": [...]}}`` instead of a flat list.""" + from feast.feature_server import ( + OnlineFeaturesMetadataResponse, + OnlineFeaturesResponse, + ) + + meta = OnlineFeaturesMetadataResponse.model_validate( + {"feature_names": {"val": ["feat_a", "feat_b"]}} + ) + assert meta.feature_names == ["feat_a", "feat_b"] + + meta_flat = OnlineFeaturesMetadataResponse.model_validate( + {"feature_names": ["feat_a", "feat_b"]} + ) + assert meta_flat.feature_names == ["feat_a", "feat_b"] + + full = OnlineFeaturesResponse.model_validate( + { + "metadata": {"feature_names": {"val": ["x", "y"]}}, + "results": [ + {"values": [1], "statuses": ["PRESENT"], "event_timestamps": []} + ], + } + ) + assert full.metadata is not None + assert full.metadata.feature_names == ["x", "y"] diff --git a/sdk/python/tests/unit/test_feature_server_utils.py b/sdk/python/tests/unit/test_feature_server_utils.py new file mode 100644 index 00000000000..80dccaebafa --- /dev/null +++ b/sdk/python/tests/unit/test_feature_server_utils.py @@ -0,0 +1,694 @@ +# Copyright 2025 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Unit tests for feature_server_utils.py + +Tests the optimized convert_response_to_dict function to ensure it matches +the output format of MessageToDict with proto_json.patch() applied. + +Related issue: https://github.com/feast-dev/feast/issues/6013 +""" + +import base64 +import json +import time + +import pytest +from google.protobuf.json_format import MessageToDict +from google.protobuf.timestamp_pb2 import Timestamp + +import feast.proto_json as proto_json +from feast.feature_server_utils import ( + _STATUS_NAMES, + _metadata_to_dict, + _timestamp_to_str, + _value_to_native, + convert_response_to_dict, +) +from feast.protos.feast.serving.ServingService_pb2 import ( + FieldStatus, + GetOnlineFeaturesResponse, + GetOnlineFeaturesResponseMetadata, +) +from feast.protos.feast.types.Value_pb2 import ( + BoolList, + BytesList, + DoubleList, + FloatList, + Int32List, + Int64List, + Int64Set, + Map, + RepeatedValue, + StringList, + StringSet, + Value, + ZonedTimestamp, +) + + +class TestValueToNative: + """Tests for _value_to_native function (matches proto_json.patch() format).""" + + def test_null_value(self): + v = Value() + result = _value_to_native(v) + assert result is None + + def test_explicit_null_val(self): + v = Value(null_val=0) + result = _value_to_native(v) + assert result is None + + def test_double_val(self): + v = Value(double_val=3.14159) + result = _value_to_native(v) + assert result == 3.14159 + + def test_float_val(self): + v = Value(float_val=2.5) + result = _value_to_native(v) + assert result == 2.5 + + def test_int64_val(self): + v = Value(int64_val=9223372036854775807) + result = _value_to_native(v) + assert result == 9223372036854775807 + + def test_int32_val(self): + v = Value(int32_val=42) + result = _value_to_native(v) + assert result == 42 + + def test_string_val(self): + v = Value(string_val="hello feast") + result = _value_to_native(v) + assert result == "hello feast" + + def test_bool_val(self): + v = Value(bool_val=True) + result = _value_to_native(v) + assert result is True + + def test_bytes_val(self): + data = b"\x00\x01\x02\x03" + v = Value(bytes_val=data) + result = _value_to_native(v) + assert result == base64.b64encode(data).decode("ascii") + + def test_double_list_val(self): + v = Value(double_list_val=DoubleList(val=[1.1, 2.2, 3.3])) + result = _value_to_native(v) + assert result == [1.1, 2.2, 3.3] + + def test_float_list_val(self): + v = Value(float_list_val=FloatList(val=[1.5, 2.5])) + result = _value_to_native(v) + assert result == [1.5, 2.5] + + def test_int64_list_val(self): + v = Value(int64_list_val=Int64List(val=[100, 200, 300])) + result = _value_to_native(v) + assert result == [100, 200, 300] + + def test_int32_list_val(self): + v = Value(int32_list_val=Int32List(val=[1, 2, 3])) + result = _value_to_native(v) + assert result == [1, 2, 3] + + def test_string_list_val(self): + v = Value(string_list_val=StringList(val=["a", "b", "c"])) + result = _value_to_native(v) + assert result == ["a", "b", "c"] + + def test_bool_list_val(self): + v = Value(bool_list_val=BoolList(val=[True, False, True])) + result = _value_to_native(v) + assert result == [True, False, True] + + def test_unix_timestamp_val(self): + v = Value(unix_timestamp_val=1609459200) + result = _value_to_native(v) + assert result == 1609459200 + + def test_bytes_list_val(self): + v = Value(bytes_list_val=BytesList(val=[b"\x00\x01", b"\x02\x03"])) + result = _value_to_native(v) + assert result == [ + base64.b64encode(b"\x00\x01").decode("ascii"), + base64.b64encode(b"\x02\x03").decode("ascii"), + ] + + def test_unix_timestamp_list_val(self): + v = Value(unix_timestamp_list_val=Int64List(val=[1609459200, 1609545600])) + result = _value_to_native(v) + assert result == [1609459200, 1609545600] + + def test_string_set_val(self): + v = Value(string_set_val=StringSet(val=["x", "y", "z"])) + result = _value_to_native(v) + assert set(result) == {"x", "y", "z"} + + def test_int64_set_val(self): + v = Value(int64_set_val=Int64Set(val=[10, 20, 30])) + result = _value_to_native(v) + assert set(result) == {10, 20, 30} + + def test_list_val_nested_values(self): + inner = RepeatedValue() + inner.val.append(Value(int64_val=1)) + inner.val.append(Value(string_val="a")) + inner.val.append(Value()) + v = Value(list_val=inner) + result = _value_to_native(v) + assert result == [1, "a", None] + + def test_set_val_nested_values(self): + inner = RepeatedValue() + inner.val.append(Value(bool_val=True)) + inner.val.append(Value(double_val=3.14)) + v = Value(set_val=inner) + result = _value_to_native(v) + assert result == [True, 3.14] + + def test_map_val(self): + m = Map() + m.val["key1"].CopyFrom(Value(int64_val=42)) + m.val["key2"].CopyFrom(Value(string_val="hello")) + v = Value(map_val=m) + result = _value_to_native(v) + assert result == {"key1": 42, "key2": "hello"} + + def test_map_val_nested_null(self): + m = Map() + m.val["present"].CopyFrom(Value(int32_val=7)) + m.val["missing"].CopyFrom(Value()) + v = Value(map_val=m) + result = _value_to_native(v) + assert result["present"] == 7 + assert result["missing"] is None + + def test_json_val(self): + v = Value(json_val='{"foo": 1}') + result = _value_to_native(v) + assert result == '{"foo": 1}' + + def test_zoned_timestamp_val(self): + # 2026-06-09T16:00:00Z viewed in America/Los_Angeles (= 09:00 -07:00). + v = Value( + zoned_timestamp_val=ZonedTimestamp( + unix_timestamp=1781020800, zone="America/Los_Angeles" + ) + ) + result = _value_to_native(v) + # Rendered as an ISO 8601 string in the stored zone, and JSON-serializable. + assert isinstance(result, str) + assert result == "2026-06-09T09:00:00-07:00" + json.dumps(result) + + def test_zoned_timestamp_val_utc(self): + v = Value( + zoned_timestamp_val=ZonedTimestamp(unix_timestamp=1781020800, zone="") + ) + result = _value_to_native(v) + assert result == "2026-06-09T16:00:00+00:00" + json.dumps(result) + + +class TestTimestampToStr: + """Tests for _timestamp_to_str function.""" + + def test_zero_timestamp(self): + ts = Timestamp(seconds=0, nanos=0) + result = _timestamp_to_str(ts) + assert result == "1970-01-01T00:00:00Z" + + def test_valid_timestamp(self): + ts = Timestamp(seconds=1609459200, nanos=0) + result = _timestamp_to_str(ts) + assert result == "2021-01-01T00:00:00Z" + + def test_timestamp_with_millis(self): + ts = Timestamp(seconds=1609459200, nanos=500000000) + result = _timestamp_to_str(ts) + assert result == "2021-01-01T00:00:00.500Z" + + def test_timestamp_with_micros(self): + ts = Timestamp(seconds=1609459200, nanos=123456000) + result = _timestamp_to_str(ts) + assert result == "2021-01-01T00:00:00.123456Z" + + def test_timestamp_with_nanos(self): + ts = Timestamp(seconds=1609459200, nanos=123456789) + result = _timestamp_to_str(ts) + assert result == "2021-01-01T00:00:00.123456789Z" + + def test_timestamp_high_nanos_no_float_rounding(self): + ts = Timestamp(seconds=1609459200, nanos=999999999) + result = _timestamp_to_str(ts) + assert result == "2021-01-01T00:00:00.999999999Z" + + +class TestMetadataToDict: + """Tests for _metadata_to_dict function (matches proto_json.patch() format).""" + + def test_empty_metadata(self): + metadata = GetOnlineFeaturesResponseMetadata() + result = _metadata_to_dict(metadata) + assert result == {} + + def test_metadata_with_feature_names(self): + metadata = GetOnlineFeaturesResponseMetadata() + metadata.feature_names.val.extend(["feature1", "feature2", "feature3"]) + result = _metadata_to_dict(metadata) + assert result == {"feature_names": ["feature1", "feature2", "feature3"]} + + +class TestConvertResponseToDict: + """Tests for the main convert_response_to_dict function.""" + + def test_empty_response(self): + response = GetOnlineFeaturesResponse() + result = convert_response_to_dict(response) + assert result == {"results": []} + + def test_single_feature_vector(self): + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(string_val="test")) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + + assert len(result["results"]) == 1 + assert result["results"][0]["values"] == ["test"] + assert result["results"][0]["statuses"] == ["PRESENT"] + + def test_multiple_feature_vectors(self): + response = GetOnlineFeaturesResponse() + + fv1 = response.results.add() + fv1.values.append(Value(int64_val=100)) + fv1.statuses.append(FieldStatus.PRESENT) + + fv2 = response.results.add() + fv2.values.append(Value(double_val=3.14)) + fv2.statuses.append(FieldStatus.NOT_FOUND) + + result = convert_response_to_dict(response) + + assert len(result["results"]) == 2 + assert result["results"][0]["values"] == [100] + assert result["results"][0]["statuses"] == ["PRESENT"] + assert result["results"][1]["values"] == [3.14] + assert result["results"][1]["statuses"] == ["NOT_FOUND"] + + def test_response_with_metadata(self): + response = GetOnlineFeaturesResponse() + response.metadata.feature_names.val.extend(["driver_id", "driver_rating"]) + + fv = response.results.add() + fv.values.append(Value(int64_val=123)) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + + assert "metadata" in result + assert result["metadata"]["feature_names"] == ["driver_id", "driver_rating"] + + def test_response_with_timestamps(self): + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(string_val="test")) + fv.statuses.append(FieldStatus.PRESENT) + ts = fv.event_timestamps.add() + ts.seconds = 1609459200 + + result = convert_response_to_dict(response) + + assert len(result["results"][0]["event_timestamps"]) == 1 + assert "2021-01-01" in result["results"][0]["event_timestamps"][0] + + def test_all_status_types(self): + response = GetOnlineFeaturesResponse() + fv = response.results.add() + + for status in [ + FieldStatus.INVALID, + FieldStatus.PRESENT, + FieldStatus.NULL_VALUE, + FieldStatus.NOT_FOUND, + FieldStatus.OUTSIDE_MAX_AGE, + ]: + fv.values.append(Value(int32_val=1)) + fv.statuses.append(status) + + result = convert_response_to_dict(response) + + expected_statuses = [ + "INVALID", + "PRESENT", + "NULL_VALUE", + "NOT_FOUND", + "OUTSIDE_MAX_AGE", + ] + assert result["results"][0]["statuses"] == expected_statuses + + def test_status_field_included_when_true(self): + response = GetOnlineFeaturesResponse() + response.status = True + result = convert_response_to_dict(response) + assert result.get("status") is True + + def test_status_field_omitted_when_false(self): + response = GetOnlineFeaturesResponse() + result = convert_response_to_dict(response) + assert "status" not in result + + def test_null_values_become_none(self): + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value()) + fv.values.append(Value(null_val=0)) + fv.statuses.extend([FieldStatus.NULL_VALUE, FieldStatus.NULL_VALUE]) + + result = convert_response_to_dict(response) + + assert result["results"][0]["values"] == [None, None] + + def test_list_values_are_native_lists(self): + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(int64_list_val=Int64List(val=[1, 2, 3]))) + fv.values.append(Value(string_list_val=StringList(val=["a", "b"]))) + fv.statuses.extend([FieldStatus.PRESENT, FieldStatus.PRESENT]) + + result = convert_response_to_dict(response) + + assert result["results"][0]["values"] == [[1, 2, 3], ["a", "b"]] + + +class TestConvertResponseToDictConsistency: + """Tests ensuring convert_response_to_dict matches MessageToDict with patch.""" + + @pytest.fixture(autouse=True) + def setup_proto_json_patch(self): + proto_json.patch() + + def _build_complex_response( + self, num_features: int = 10 + ) -> GetOnlineFeaturesResponse: + response = GetOnlineFeaturesResponse() + feature_names = [f"feature_{i}" for i in range(num_features)] + response.metadata.feature_names.val.extend(feature_names) + + for i in range(num_features): + fv = response.results.add() + if i % 4 == 0: + fv.values.append(Value(int64_val=i * 100)) + elif i % 4 == 1: + fv.values.append(Value(double_val=i * 0.1)) + elif i % 4 == 2: + fv.values.append(Value(string_val=f"value_{i}")) + else: + fv.values.append(Value()) + fv.statuses.append(FieldStatus.PRESENT) + + return response + + def test_values_match_patched_message_to_dict(self): + """Ensure value serialization matches proto_json.patch() format.""" + response = self._build_complex_response(8) + + fast_result = convert_response_to_dict(response) + standard_result = MessageToDict(response, preserving_proto_field_name=True) + + assert set(fast_result.keys()) == set(standard_result.keys()) + assert len(fast_result["results"]) == len(standard_result["results"]) + + for i in range(len(fast_result["results"])): + fast_values = fast_result["results"][i]["values"] + standard_values = standard_result["results"][i]["values"] + assert fast_values == standard_values, f"Mismatch at result {i}" + + def test_metadata_matches_patched_format(self): + """Ensure metadata format matches proto_json.patch() format.""" + response = self._build_complex_response(5) + + fast_result = convert_response_to_dict(response) + standard_result = MessageToDict(response, preserving_proto_field_name=True) + + if "metadata" in standard_result: + assert "metadata" in fast_result + assert ( + fast_result["metadata"]["feature_names"] + == standard_result["metadata"]["feature_names"] + ) + + def test_float_val_precision_matches_message_to_dict(self): + """float32 storage causes truncation; both paths must return identical values.""" + response = GetOnlineFeaturesResponse() + fv = response.results.add() + # 3.14 is not exactly representable as float32; both implementations + # should return the same truncated float64 representation + fv.values.append(Value(float_val=3.14)) + fv.statuses.append(FieldStatus.PRESENT) + + fast_result = convert_response_to_dict(response) + standard_result = MessageToDict(response, preserving_proto_field_name=True) + + assert ( + fast_result["results"][0]["values"] + == standard_result["results"][0]["values"] + ) + + def test_double_val_precision(self): + """double_val is returned as a Python float (shortest round-trip form). + + The upstream code passed float_precision=18 to MessageToDict, which forced 18 + significant digits for doubles. Our implementation returns native Python floats + serialized by json.dumps using Python 3.1+ shortest-round-trip representation + (~15–17 sig digits). The value is identical when round-tripped through float64; + the only difference is how many trailing digits appear in the JSON string. + This is an intentional trade-off for speed and is safe for all ML feature values. + """ + import struct + + # Use a value with many significant digits + pi = 3.141592653589793 + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(double_val=pi)) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + value = result["results"][0]["values"][0] + + # Value must round-trip correctly through json.dumps + assert value == pi + round_tripped = json.loads(json.dumps(value)) + assert round_tripped == pi + # Verify it encodes as the same float64 bit pattern + assert struct.pack("d", value) == struct.pack("d", pi) + + def test_set_types_return_flat_list(self): + """set types (string_set_val, int64_set_val, etc.) return flat lists. + + Note: proto_json.patch() does not explicitly handle _set_ types — they fall + through to the else branch and return the raw proto object, which MessageToDict + then serializes as {"val": [...]}. Our implementation normalizes these to flat + lists, which is more useful for API consumers and consistent with list types. + """ + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(string_set_val=StringSet(val=["a", "b", "c"]))) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + values = result["results"][0]["values"] + assert isinstance(values[0], list), "set type should be a flat list" + assert set(values[0]) == {"a", "b", "c"} + + def test_bytes_val_is_base64_encoded(self): + """bytes_val is base64-encoded so JSONResponse can serialize it. + + This intentionally differs from proto_json.patch() which returns raw bytes. + Raw bytes are not JSON-serializable; base64 is the standard protobuf JSON + encoding for bytes fields and is safe for all HTTP clients. + """ + response = GetOnlineFeaturesResponse() + fv = response.results.add() + data = b"\x00\x01\x02\xff" + fv.values.append(Value(bytes_val=data)) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + encoded = result["results"][0]["values"][0] + + assert encoded == base64.b64encode(data).decode("ascii") + # Must be JSON-serializable + assert json.dumps(encoded) + + +class TestJsonSerializability: + """Ensure convert_response_to_dict output is always JSON-serializable.""" + + def test_complex_types_are_json_serializable(self): + """map_val, list_val, set_val must not leave proto objects in the output.""" + response = GetOnlineFeaturesResponse() + fv = response.results.add() + + # map_val + m = Map() + m.val["k"].CopyFrom(Value(int64_val=1)) + fv.values.append(Value(map_val=m)) + + # list_val (RepeatedValue) + inner = RepeatedValue() + inner.val.append(Value(string_val="a")) + fv.values.append(Value(list_val=inner)) + + # int64_set_val + fv.values.append(Value(int64_set_val=Int64Set(val=[10, 20]))) + + fv.statuses.extend( + [FieldStatus.PRESENT, FieldStatus.PRESENT, FieldStatus.PRESENT] + ) + + result = convert_response_to_dict(response) + # must not raise + serialized = json.dumps(result) + assert serialized # non-empty + + +class TestProtobufCompatibility: + """Regression tests for protobuf >= 7.34.0 compatibility (issue #6435). + + protobuf 7.34.0 removed the float_precision kwarg from MessageToDict. + convert_response_to_dict must never call MessageToDict, so it is immune + to this breaking change regardless of the installed protobuf version. + """ + + def test_no_message_to_dict_dependency(self): + """convert_response_to_dict must not call MessageToDict internally.""" + import unittest.mock as mock + + response = GetOnlineFeaturesResponse() + fv = response.results.add() + fv.values.append(Value(double_val=3.141592653589793)) + fv.values.append(Value(int64_val=42)) + fv.values.append(Value(string_val="hello")) + fv.statuses.extend( + [FieldStatus.PRESENT, FieldStatus.PRESENT, FieldStatus.PRESENT] + ) + response.metadata.feature_names.val.extend(["f1", "f2", "f3"]) + + with mock.patch( + "google.protobuf.json_format.MessageToDict", + side_effect=AssertionError("MessageToDict must not be called"), + ): + result = convert_response_to_dict(response) + + assert len(result["results"]) == 1 + assert result["results"][0]["values"] == [3.141592653589793, 42, "hello"] + assert result["metadata"]["feature_names"] == ["f1", "f2", "f3"] + + def test_double_precision_without_float_precision_kwarg(self): + """Doubles must round-trip without the removed float_precision kwarg.""" + values = [ + 1e-300, + 1.7976931348623157e308, + 2.2250738585072014e-308, + 0.1 + 0.2, + ] + response = GetOnlineFeaturesResponse() + fv = response.results.add() + for v in values: + fv.values.append(Value(double_val=v)) + fv.statuses.append(FieldStatus.PRESENT) + + result = convert_response_to_dict(response) + for i, expected in enumerate(values): + actual = result["results"][0]["values"][i] + assert actual == expected, f"Mismatch at index {i}: {actual} != {expected}" + round_tripped = json.loads(json.dumps(actual)) + assert round_tripped == expected + + +class TestPerformance: + """Performance tests to validate the optimization claim.""" + + def _build_large_response( + self, num_entities: int = 50, num_features: int = 100 + ) -> GetOnlineFeaturesResponse: + response = GetOnlineFeaturesResponse() + feature_names = [f"feature_{i}" for i in range(num_features)] + response.metadata.feature_names.val.extend(feature_names) + + for i in range(num_features): + fv = response.results.add() + for j in range(num_entities): + if i % 4 == 0: + fv.values.append(Value(int64_val=j * 100 + i)) + elif i % 4 == 1: + fv.values.append(Value(double_val=j * 0.1 + i)) + elif i % 4 == 2: + fv.values.append(Value(string_val=f"entity_{j}_feature_{i}")) + else: + fv.values.append(Value(bool_val=j % 2 == 0)) + fv.statuses.append(FieldStatus.PRESENT) + + return response + + @pytest.mark.slow + def test_faster_than_message_to_dict(self): + """Verify convert_response_to_dict is faster than MessageToDict.""" + proto_json.patch() + response = self._build_large_response(num_entities=50, num_features=100) + iterations = 100 + + for _ in range(10): + convert_response_to_dict(response) + MessageToDict(response, preserving_proto_field_name=True) + + start = time.process_time() + for _ in range(iterations): + convert_response_to_dict(response) + fast_time = time.process_time() - start + + start = time.process_time() + for _ in range(iterations): + MessageToDict(response, preserving_proto_field_name=True) + standard_time = time.process_time() - start + + speedup = standard_time / fast_time + print(f"\nPerformance: fast={fast_time:.3f}s, standard={standard_time:.3f}s") + print(f"Speedup: {speedup:.2f}x") + + assert speedup >= 1.5, f"Expected at least 1.5x speedup, got {speedup:.2f}x" + + +class TestStatusNames: + """Tests for the status name mapping.""" + + def test_all_status_codes_mapped(self): + assert 0 in _STATUS_NAMES # INVALID + assert 1 in _STATUS_NAMES # PRESENT + assert 2 in _STATUS_NAMES # NULL_VALUE + assert 3 in _STATUS_NAMES # NOT_FOUND + assert 4 in _STATUS_NAMES # OUTSIDE_MAX_AGE + + def test_unknown_status_returns_invalid(self): + assert _STATUS_NAMES.get(999, "INVALID") == "INVALID" diff --git a/sdk/python/tests/unit/test_feature_view_state.py b/sdk/python/tests/unit/test_feature_view_state.py new file mode 100644 index 00000000000..3af91b3b469 --- /dev/null +++ b/sdk/python/tests/unit/test_feature_view_state.py @@ -0,0 +1,433 @@ +import copy +from datetime import datetime, timedelta +from tempfile import mkstemp + +import pytest + +from feast.data_format import AvroFormat, ParquetFormat +from feast.data_source import KafkaSource +from feast.entity import Entity +from feast.feature_store import FeatureStore +from feast.feature_view import FeatureView, FeatureViewState +from feast.field import Field +from feast.infra.offline_stores.file_source import FileSource +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.on_demand_feature_view import OnDemandFeatureView +from feast.protos.feast.core.FeatureView_pb2 import FeatureView as FeatureViewProto +from feast.protos.feast.core.FeatureView_pb2 import ( + FeatureViewMeta as FeatureViewMetaProto, +) +from feast.protos.feast.core.FeatureView_pb2 import ( + FeatureViewSpec as FeatureViewSpecProto, +) +from feast.repo_config import RepoConfig +from feast.stream_feature_view import StreamFeatureView +from feast.types import Float32, Int64 + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _kafka_source(): + return KafkaSource( + name="kafka", + timestamp_field="event_timestamp", + kafka_bootstrap_servers="localhost:9092", + message_format=AvroFormat(""), + topic="topic", + batch_source=_batch_source(), + ) + + +def _batch_source(): + return FileSource( + file_format=ParquetFormat(), + path="file://feast/*", + timestamp_field="ts_col", + created_timestamp_column="timestamp", + ) + + +def _simple_feature_view(name="test_fv", enabled=True): + return FeatureView( + name=name, + entities=[], + schema=[Field(name="f1", dtype=Float32)], + source=_batch_source(), + ttl=timedelta(days=1), + enabled=enabled, + ) + + +@pytest.fixture +def local_feature_store(): + _, registry_path = mkstemp() + _, online_store_path = mkstemp() + return FeatureStore( + config=RepoConfig( + registry=registry_path, + project="default", + provider="local", + online_store=SqliteOnlineStoreConfig(path=online_store_path), + entity_key_serialization_version=3, + ) + ) + + +# --------------------------------------------------------------------------- +# FeatureViewState enum +# --------------------------------------------------------------------------- + + +class TestFeatureViewState: + def test_state_values(self): + assert FeatureViewState.STATE_UNSPECIFIED == 0 + assert FeatureViewState.CREATED == 1 + assert FeatureViewState.GENERATED == 2 + assert FeatureViewState.MATERIALIZING == 3 + assert FeatureViewState.AVAILABLE_ONLINE == 4 + + def test_from_proto_valid(self): + assert FeatureViewState.from_proto(0) == FeatureViewState.STATE_UNSPECIFIED + assert FeatureViewState.from_proto(4) == FeatureViewState.AVAILABLE_ONLINE + + def test_from_proto_invalid_falls_back(self): + assert FeatureViewState.from_proto(999) == FeatureViewState.STATE_UNSPECIFIED + + def test_to_proto_round_trip(self): + for state in FeatureViewState: + assert FeatureViewState.from_proto(state.to_proto()) == state + + def test_valid_transitions(self): + """Verify that valid transitions are accepted.""" + assert FeatureViewState.STATE_UNSPECIFIED.can_transition_to( + FeatureViewState.CREATED + ) + assert FeatureViewState.CREATED.can_transition_to(FeatureViewState.GENERATED) + assert FeatureViewState.GENERATED.can_transition_to( + FeatureViewState.MATERIALIZING + ) + assert FeatureViewState.MATERIALIZING.can_transition_to( + FeatureViewState.AVAILABLE_ONLINE + ) + assert FeatureViewState.MATERIALIZING.can_transition_to( + FeatureViewState.GENERATED + ) + assert FeatureViewState.AVAILABLE_ONLINE.can_transition_to( + FeatureViewState.MATERIALIZING + ) + + def test_invalid_transitions(self): + """Verify that invalid transitions are rejected.""" + assert not FeatureViewState.STATE_UNSPECIFIED.can_transition_to( + FeatureViewState.AVAILABLE_ONLINE + ) + assert not FeatureViewState.CREATED.can_transition_to( + FeatureViewState.MATERIALIZING + ) + assert not FeatureViewState.CREATED.can_transition_to( + FeatureViewState.AVAILABLE_ONLINE + ) + assert not FeatureViewState.GENERATED.can_transition_to( + FeatureViewState.AVAILABLE_ONLINE + ) + assert not FeatureViewState.AVAILABLE_ONLINE.can_transition_to( + FeatureViewState.CREATED + ) + + +# --------------------------------------------------------------------------- +# FeatureView enabled / state defaults +# --------------------------------------------------------------------------- + + +class TestFeatureViewDefaults: + def test_default_enabled_is_true(self): + fv = _simple_feature_view() + assert fv.enabled is True + + def test_default_state_is_unspecified(self): + fv = _simple_feature_view() + assert fv.state == FeatureViewState.STATE_UNSPECIFIED + + def test_enabled_false(self): + fv = _simple_feature_view(enabled=False) + assert fv.enabled is False + + +# --------------------------------------------------------------------------- +# Proto serialization round-trips +# --------------------------------------------------------------------------- + + +class TestFeatureViewProtoRoundTrip: + def test_enabled_true_round_trip(self): + fv = _simple_feature_view(enabled=True) + proto = fv.to_proto() + assert proto.spec.disabled is False + restored = FeatureView.from_proto(proto) + assert restored.enabled is True + + def test_enabled_false_round_trip(self): + fv = _simple_feature_view(enabled=False) + proto = fv.to_proto() + assert proto.spec.disabled is True + restored = FeatureView.from_proto(proto) + assert restored.enabled is False + + def test_state_round_trip(self): + fv = _simple_feature_view() + fv.state = FeatureViewState.AVAILABLE_ONLINE + proto = fv.to_proto() + assert proto.meta.state == FeatureViewState.AVAILABLE_ONLINE.value + restored = FeatureView.from_proto(proto) + assert restored.state == FeatureViewState.AVAILABLE_ONLINE + + def test_state_unspecified_not_written_to_proto(self): + fv = _simple_feature_view() + assert fv.state == FeatureViewState.STATE_UNSPECIFIED + proto = fv.to_proto() + assert proto.meta.state == 0 + + def test_backward_compat_old_proto_without_disabled_field(self): + """Old protos without `disabled` field default to False -> enabled=True.""" + spec = FeatureViewSpecProto() + spec.name = "legacy_fv" + proto = FeatureViewProto(spec=spec, meta=FeatureViewMetaProto()) + fv = FeatureView.from_proto(proto) + assert fv.enabled is True + + def test_backward_compat_old_proto_without_state_field(self): + """Old protos without `state` field default to 0 -> STATE_UNSPECIFIED.""" + spec = FeatureViewSpecProto() + spec.name = "legacy_fv" + proto = FeatureViewProto(spec=spec, meta=FeatureViewMetaProto()) + fv = FeatureView.from_proto(proto) + assert fv.state == FeatureViewState.STATE_UNSPECIFIED + + def test_all_states_round_trip(self): + for state in FeatureViewState: + fv = _simple_feature_view() + fv.state = state + restored = FeatureView.from_proto(fv.to_proto()) + assert restored.state == state + + +# --------------------------------------------------------------------------- +# copy.copy preserves enabled/state +# --------------------------------------------------------------------------- + + +class TestCopyPreservesState: + def test_feature_view_copy(self): + fv = _simple_feature_view(enabled=False) + fv.state = FeatureViewState.GENERATED + copied = copy.copy(fv) + assert copied.enabled is False + assert copied.state == FeatureViewState.GENERATED + + def test_on_demand_feature_view_copy(self): + source_fv = _simple_feature_view() + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[source_fv], + schema=[Field(name="out", dtype=Float32)], + mode="python", + udf=lambda features: {"out": [1.0]}, + enabled=False, + ) + odfv.state = FeatureViewState.GENERATED + copied = copy.copy(odfv) + assert copied.enabled is False + assert copied.state == FeatureViewState.GENERATED + + def test_stream_feature_view_copy(self): + sfv = StreamFeatureView( + name="test_sfv", + entities=[], + schema=[Field(name="f1", dtype=Float32)], + source=_kafka_source(), + ttl=timedelta(days=1), + ) + sfv.enabled = False + sfv.state = FeatureViewState.AVAILABLE_ONLINE + copied = copy.copy(sfv) + assert copied.enabled is False + assert copied.state == FeatureViewState.AVAILABLE_ONLINE + + +# --------------------------------------------------------------------------- +# OnDemandFeatureView enabled / state +# --------------------------------------------------------------------------- + + +class TestOnDemandFeatureViewState: + def test_default_enabled(self): + source_fv = _simple_feature_view() + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[source_fv], + schema=[Field(name="out", dtype=Float32)], + mode="python", + udf=lambda features: {"out": [1.0]}, + ) + assert odfv.enabled is True + assert odfv.state == FeatureViewState.STATE_UNSPECIFIED + + def test_disabled(self): + source_fv = _simple_feature_view() + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[source_fv], + schema=[Field(name="out", dtype=Float32)], + mode="python", + udf=lambda features: {"out": [1.0]}, + enabled=False, + ) + assert odfv.enabled is False + + def test_proto_disabled_field(self): + """Verify the proto disabled field is set correctly without full round-trip.""" + source_fv = _simple_feature_view() + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[source_fv], + schema=[Field(name="out", dtype=Float32)], + mode="python", + udf=lambda features: {"out": [1.0]}, + enabled=False, + ) + odfv.state = FeatureViewState.AVAILABLE_ONLINE + proto = odfv.to_proto() + assert proto.spec.disabled is True + assert proto.meta.state == FeatureViewState.AVAILABLE_ONLINE.value + + +# --------------------------------------------------------------------------- +# StreamFeatureView enabled / state +# --------------------------------------------------------------------------- + + +class TestStreamFeatureViewState: + def test_proto_round_trip(self): + sfv = StreamFeatureView( + name="test_sfv", + entities=[], + schema=[Field(name="f1", dtype=Float32)], + source=_kafka_source(), + ttl=timedelta(days=1), + ) + sfv.enabled = False + sfv.state = FeatureViewState.MATERIALIZING + proto = sfv.to_proto() + assert proto.spec.disabled is True + restored = StreamFeatureView.from_proto(proto) + assert restored.enabled is False + assert restored.state == FeatureViewState.MATERIALIZING + + +# --------------------------------------------------------------------------- +# Registry apply preserves enabled/state +# --------------------------------------------------------------------------- + + +class TestRegistryEnabledState: + def test_apply_and_retrieve_enabled(self, local_feature_store): + store = local_feature_store + fv = _simple_feature_view(enabled=True) + store.apply([fv]) + retrieved = store.get_feature_view("test_fv") + assert retrieved.enabled is True + store.teardown() + + def test_apply_and_retrieve_disabled(self, local_feature_store): + store = local_feature_store + fv = _simple_feature_view(enabled=False) + store.apply([fv]) + retrieved = store.get_feature_view("test_fv") + assert retrieved.enabled is False + store.teardown() + + def test_toggle_enabled_via_registry(self, local_feature_store): + store = local_feature_store + fv = _simple_feature_view(enabled=True) + store.apply([fv]) + + # Disable it + fv.enabled = False + store.registry.apply_feature_view(fv, store.project) + retrieved = store.get_feature_view("test_fv") + assert retrieved.enabled is False + + # Re-enable it + fv.enabled = True + store.registry.apply_feature_view(fv, store.project) + retrieved = store.get_feature_view("test_fv") + assert retrieved.enabled is True + store.teardown() + + def test_state_persists_through_registry(self, local_feature_store): + store = local_feature_store + fv = _simple_feature_view() + fv.state = FeatureViewState.GENERATED + store.apply([fv]) + + # State should be updated via registry apply + fv.state = FeatureViewState.AVAILABLE_ONLINE + store.registry.apply_feature_view(fv, store.project) + retrieved = store.get_feature_view("test_fv") + assert retrieved.state == FeatureViewState.AVAILABLE_ONLINE + store.teardown() + + def test_reapply_does_not_reset_state(self, local_feature_store): + """feast apply with a default-state FV must not reset an existing state.""" + store = local_feature_store + fv = _simple_feature_view() + store.apply([fv]) + + # Simulate materialization having moved state to AVAILABLE_ONLINE + fv.state = FeatureViewState.AVAILABLE_ONLINE + store.registry.apply_feature_view(fv, store.project) + retrieved = store.get_feature_view("test_fv") + assert retrieved.state == FeatureViewState.AVAILABLE_ONLINE + + # Re-apply with a fresh FV (default STATE_UNSPECIFIED) — should preserve state + fresh_fv = _simple_feature_view() + assert fresh_fv.state == FeatureViewState.STATE_UNSPECIFIED + store.apply([fresh_fv]) + retrieved = store.get_feature_view("test_fv") + assert retrieved.state == FeatureViewState.AVAILABLE_ONLINE + store.teardown() + + +# --------------------------------------------------------------------------- +# Materialization blocks disabled feature views +# --------------------------------------------------------------------------- + + +class TestMaterializationDisabledBlocking: + def test_materialize_disabled_fv_by_name_raises(self, local_feature_store): + store = local_feature_store + entity = Entity(name="entity_1", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + schema=[ + Field(name="f1", dtype=Float32), + Field(name="entity_id", dtype=Int64), + ], + source=_batch_source(), + ttl=timedelta(days=1), + online=True, + enabled=False, + ) + store.apply([entity, fv]) + + with pytest.raises(ValueError, match="disabled"): + store.materialize( + feature_views=["test_fv"], + start_date=datetime.utcnow() - timedelta(hours=1), + end_date=datetime.utcnow(), + ) + store.teardown() diff --git a/sdk/python/tests/unit/test_feature_view_versioning.py b/sdk/python/tests/unit/test_feature_view_versioning.py new file mode 100644 index 00000000000..80c2bc808ea --- /dev/null +++ b/sdk/python/tests/unit/test_feature_view_versioning.py @@ -0,0 +1,558 @@ +import pytest + +from feast.utils import _parse_feature_ref, _strip_version_from_ref +from feast.version_utils import ( + generate_version_id, + normalize_version_string, + parse_version, + version_tag, +) + + +class TestParseVersion: + def test_latest_string(self): + is_latest, num = parse_version("latest") + assert is_latest is True + assert num == 0 + + def test_empty_string(self): + is_latest, num = parse_version("") + assert is_latest is True + assert num == 0 + + def test_latest_case_insensitive(self): + is_latest, num = parse_version("Latest") + assert is_latest is True + + def test_v_format(self): + is_latest, num = parse_version("v2") + assert is_latest is False + assert num == 2 + + def test_version_format(self): + is_latest, num = parse_version("version3") + assert is_latest is False + assert num == 3 + + def test_case_insensitive_v(self): + is_latest, num = parse_version("V5") + assert is_latest is False + assert num == 5 + + def test_case_insensitive_version(self): + is_latest, num = parse_version("Version10") + assert is_latest is False + assert num == 10 + + def test_v0(self): + is_latest, num = parse_version("v0") + assert is_latest is False + assert num == 0 + + def test_invalid_format(self): + with pytest.raises(ValueError, match="Invalid version string"): + parse_version("abc") + + def test_invalid_format_no_number(self): + with pytest.raises(ValueError, match="Invalid version string"): + parse_version("v") + + def test_invalid_format_negative(self): + with pytest.raises(ValueError, match="Invalid version string"): + parse_version("v-1") + + +class TestNormalizeVersionString: + def test_empty_to_latest(self): + assert normalize_version_string("") == "latest" + + def test_latest_unchanged(self): + assert normalize_version_string("latest") == "latest" + + def test_v2_canonical(self): + assert normalize_version_string("v2") == "v2" + + def test_version2_to_v2(self): + assert normalize_version_string("version2") == "v2" + + def test_V3_to_v3(self): + assert normalize_version_string("V3") == "v3" + + +class TestVersionTag: + def test_simple(self): + assert version_tag(0) == "v0" + assert version_tag(5) == "v5" + assert version_tag(100) == "v100" + + +class TestGenerateVersionId: + def test_is_uuid(self): + vid = generate_version_id() + assert len(vid) == 36 + assert vid.count("-") == 4 + + def test_unique(self): + v1 = generate_version_id() + v2 = generate_version_id() + assert v1 != v2 + + +class TestFeatureViewVersionField: + def test_feature_view_default_version(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + assert fv.version == "latest" + assert fv.current_version_number is None + + def test_feature_view_explicit_version(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v2", + ) + assert fv.version == "v2" + + def test_feature_view_proto_roundtrip(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v3", + ) + fv.current_version_number = 3 + + proto = fv.to_proto() + assert proto.spec.version == "v3" + assert proto.meta.current_version_number == 3 + + fv2 = FeatureView.from_proto(proto) + assert fv2.version == "v3" + assert fv2.current_version_number == 3 + + def test_feature_view_proto_roundtrip_v0(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v0", + ) + fv.current_version_number = 0 + + proto = fv.to_proto() + assert proto.spec.version == "v0" + assert proto.meta.current_version_number == 0 + + fv2 = FeatureView.from_proto(proto) + assert fv2.version == "v0" + assert fv2.current_version_number == 0 + + def test_feature_view_proto_roundtrip_latest_zero(self): + """version='latest' with current_version_number=None is preserved as + None through proto roundtrip (proto default 0 without spec.version + is treated as None for backward compatibility).""" + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + # default version="latest", current_version_number=None + ) + assert fv.current_version_number is None + + proto = fv.to_proto() + fv2 = FeatureView.from_proto(proto) + assert fv2.version == "latest" + # Proto default 0 without spec.version is treated as None + assert fv2.current_version_number is None + + def test_feature_view_equality_with_version(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv1 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v2", + ) + fv2 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="version2", + ) + # v2 and version2 should be equivalent + assert fv1 == fv2 + + def test_feature_view_inequality_different_version(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv1 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="latest", + ) + fv2 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v2", + ) + assert fv1 != fv2 + + def test_feature_view_empty_version_equals_latest(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv1 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + fv2 = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="latest", + ) + assert fv1 == fv2 + + def test_feature_view_copy_preserves_version(self): + import copy + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + version="v5", + ) + fv_copy = copy.copy(fv) + assert fv_copy.version == "v5" + + +class TestOnDemandFeatureViewVersionField: + def test_odfv_default_version(self): + from feast.data_source import RequestSource + from feast.field import Field + from feast.on_demand_feature_view import OnDemandFeatureView + from feast.types import Float32 + + request_source = RequestSource( + name="vals_to_add", + schema=[ + Field(name="val_to_add", dtype=Float32), + Field(name="val_to_add_2", dtype=Float32), + ], + ) + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[request_source], + schema=[Field(name="output", dtype=Float32)], + feature_transformation=_dummy_transformation(), + mode="python", + ) + assert odfv.version == "latest" + + def test_odfv_proto_roundtrip(self): + from feast.data_source import RequestSource + from feast.field import Field + from feast.on_demand_feature_view import OnDemandFeatureView + from feast.types import Float32 + + request_source = RequestSource( + name="vals_to_add", + schema=[ + Field(name="val_to_add", dtype=Float32), + Field(name="val_to_add_2", dtype=Float32), + ], + ) + odfv = OnDemandFeatureView( + name="test_odfv", + sources=[request_source], + schema=[Field(name="output", dtype=Float32)], + feature_transformation=_dummy_transformation(), + mode="python", + version="v1", + ) + odfv.current_version_number = 1 + + proto = odfv.to_proto() + assert proto.spec.version == "v1" + assert proto.meta.current_version_number == 1 + + odfv2 = OnDemandFeatureView.from_proto(proto) + assert odfv2.version == "v1" + assert odfv2.current_version_number == 1 + + +class TestParseFeatureRef: + def test_bare_ref(self): + fv, version, feat = _parse_feature_ref("driver_stats:trips") + assert fv == "driver_stats" + assert version is None + assert feat == "trips" + + def test_versioned_ref(self): + fv, version, feat = _parse_feature_ref("driver_stats@v2:trips") + assert fv == "driver_stats" + assert version == 2 + assert feat == "trips" + + def test_latest_ref(self): + fv, version, feat = _parse_feature_ref("driver_stats@latest:trips") + assert fv == "driver_stats" + assert version is None + assert feat == "trips" + + def test_v0_ref(self): + fv, version, feat = _parse_feature_ref("driver_stats@v0:trips") + assert fv == "driver_stats" + assert version == 0 + assert feat == "trips" + + def test_uppercase_v(self): + fv, version, feat = _parse_feature_ref("driver_stats@V3:trips") + assert fv == "driver_stats" + assert version == 3 + assert feat == "trips" + + def test_invalid_no_colon(self): + with pytest.raises(ValueError, match="Invalid feature reference"): + _parse_feature_ref("driver_stats_trips") + + def test_unrecognized_version_falls_back(self): + """Unrecognized version format falls back to treating full fv_part as the name.""" + fv, version, feat = _parse_feature_ref("driver_stats@abc:trips") + assert fv == "driver_stats@abc" + assert version is None + assert feat == "trips" + + def test_empty_version(self): + fv, version, feat = _parse_feature_ref("driver_stats@:trips") + assert fv == "driver_stats" + assert version is None + assert feat == "trips" + + def test_at_sign_in_fv_name_falls_back_gracefully(self): + """Legacy FV name with @ falls back to treating whole pre-colon string as name.""" + fv, version, feat = _parse_feature_ref("my@weird:feature") + assert fv == "my@weird" + assert version is None + assert feat == "feature" + + def test_at_sign_with_valid_version_still_parses(self): + """A valid @v suffix still parses as a version.""" + fv, version, feat = _parse_feature_ref("stats@v2:trips") + assert fv == "stats" + assert version == 2 + assert feat == "trips" + + +class TestEnsureValidRejectsReservedChars: + def test_at_sign_in_name_raises(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="my@weird_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + with pytest.raises(ValueError, match="must not contain '@'"): + fv.ensure_valid() + + def test_colon_in_name_raises(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="my:weird_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + with pytest.raises(ValueError, match="must not contain ':'"): + fv.ensure_valid() + + def test_valid_name_passes(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="driver_stats", + entities=[entity], + ttl=timedelta(days=1), + ) + fv.ensure_valid() # Should not raise + + +class TestStripVersionFromRef: + def test_bare_ref(self): + assert _strip_version_from_ref("driver_stats:trips") == "driver_stats:trips" + + def test_versioned_ref(self): + assert _strip_version_from_ref("driver_stats@v2:trips") == "driver_stats:trips" + + def test_latest_ref(self): + assert ( + _strip_version_from_ref("driver_stats@latest:trips") == "driver_stats:trips" + ) + + +class TestTableId: + def test_no_version(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + from feast.infra.online_stores.sqlite import _table_id + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + assert _table_id("my_project", fv) == "my_project_test_fv" + + def test_v0_no_suffix(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + from feast.infra.online_stores.sqlite import _table_id + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + fv.current_version_number = 0 + assert _table_id("my_project", fv) == "my_project_test_fv" + + def test_v1_with_suffix(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + from feast.infra.online_stores.sqlite import _table_id + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + fv.current_version_number = 1 + assert ( + _table_id("my_project", fv, enable_versioning=True) + == "my_project_test_fv_v1" + ) + + def test_v5_with_suffix(self): + from datetime import timedelta + + from feast.entity import Entity + from feast.feature_view import FeatureView + from feast.infra.online_stores.sqlite import _table_id + + entity = Entity(name="entity_id", join_keys=["entity_id"]) + fv = FeatureView( + name="test_fv", + entities=[entity], + ttl=timedelta(days=1), + ) + fv.current_version_number = 5 + assert ( + _table_id("my_project", fv, enable_versioning=True) + == "my_project_test_fv_v5" + ) + + +class TestValidateFeatureRefsVersioned: + def test_versioned_refs_no_collision_with_full_names(self): + from feast.utils import _validate_feature_refs + + # Different versions of the same feature should not collide with full names + refs = ["driver_stats@v1:trips", "driver_stats@v2:trips"] + _validate_feature_refs(refs, full_feature_names=True) # Should not raise + + def test_versioned_refs_collision_without_full_names(self): + from feast.errors import FeatureNameCollisionError + from feast.utils import _validate_feature_refs + + # Same feature name from different versions collides without full names + refs = ["driver_stats@v1:trips", "driver_stats@v2:trips"] + with pytest.raises(FeatureNameCollisionError): + _validate_feature_refs(refs, full_feature_names=False) + + +def _dummy_transformation(): + from feast.transformation.python_transformation import PythonTransformation + + def identity(features_df): + return features_df + + return PythonTransformation( + udf=identity, + udf_string="def identity(features_df):\n return features_df\n", + ) diff --git a/sdk/python/tests/unit/test_feature_views.py b/sdk/python/tests/unit/test_feature_views.py index 3427cfdfc4b..1f3fd043485 100644 --- a/sdk/python/tests/unit/test_feature_views.py +++ b/sdk/python/tests/unit/test_feature_views.py @@ -542,3 +542,58 @@ def simple_udf(df: pd.DataFrame) -> pd.DataFrame: assert deserialized.feature_transformation is not None, ( "Expected transformation to be present" ) + + +def test_feature_view_org_field(): + """Test that the optional `org` field is stored, serialized, and round-trips correctly.""" + file_source = FileSource(name="my-file-source", path="test.parquet") + + # org is optional — defaults to empty string + fv_no_org = FeatureView( + name="fv-no-org", + entities=[], + schema=[Field(name="feature1", dtype=Float32)], + source=file_source, + ) + assert fv_no_org.org == "" + + # org can be set explicitly + fv_with_org = FeatureView( + name="fv-with-org", + entities=[], + schema=[Field(name="feature1", dtype=Float32)], + source=file_source, + org="ads", + ) + assert fv_with_org.org == "ads" + + # org is serialized to proto + proto = fv_with_org.to_proto() + assert proto.spec.org == "ads" + + # org survives a proto round-trip + roundtripped = FeatureView.from_proto(proto) + assert roundtripped.org == "ads" + + # a view without org round-trips to empty string + proto_no_org = fv_no_org.to_proto() + assert proto_no_org.spec.org == "" + roundtripped_no_org = FeatureView.from_proto(proto_no_org) + assert roundtripped_no_org.org == "" + + # equality respects org + fv_org_a = FeatureView( + name="fv-eq", + entities=[], + schema=[Field(name="feature1", dtype=Float32)], + source=file_source, + org="ads", + ) + fv_org_b = FeatureView( + name="fv-eq", + entities=[], + schema=[Field(name="feature1", dtype=Float32)], + source=file_source, + org="search", + ) + assert fv_org_a != fv_org_b diff --git a/sdk/python/tests/unit/test_grpc_server_write_protos.py b/sdk/python/tests/unit/test_grpc_server_write_protos.py new file mode 100644 index 00000000000..31c3e5c84c8 --- /dev/null +++ b/sdk/python/tests/unit/test_grpc_server_write_protos.py @@ -0,0 +1,159 @@ +import pytest + +from feast.infra.contrib.grpc_server import parse_typed +from feast.protos.feast.serving.GrpcServer_pb2 import ( + PushRequest, + WriteToOnlineStoreRequest, +) +from feast.protos.feast.types.Value_pb2 import ( + Int64List, + Map, + Null, + StringSet, + Value, +) + + +def test_push_request_string_features(): + request = PushRequest( + features={"driver_id": "1001", "conv_rate": "0.5"}, + stream_feature_view="driver_stats", + to="online", + ) + assert request.features["driver_id"] == "1001" + assert request.features["conv_rate"] == "0.5" + assert len(request.typed_features) == 0 + + +def test_push_request_typed_features(): + request = PushRequest( + typed_features={ + "driver_id": Value(int64_val=1001), + "conv_rate": Value(float_val=0.5), + "active": Value(bool_val=True), + "label": Value(string_val="fast"), + }, + stream_feature_view="driver_stats", + to="online", + ) + assert request.typed_features["driver_id"].int64_val == 1001 + assert request.typed_features["conv_rate"].float_val == pytest.approx(0.5) + assert request.typed_features["active"].bool_val is True + assert request.typed_features["label"].string_val == "fast" + assert len(request.features) == 0 + + +def test_push_request_typed_features_val_case(): + """WhichOneof('val') returns the correct field name for each value type.""" + cases = [ + (Value(int32_val=1), "int32_val"), + (Value(int64_val=2), "int64_val"), + (Value(float_val=1.0), "float_val"), + (Value(double_val=2.0), "double_val"), + (Value(bool_val=True), "bool_val"), + (Value(string_val="x"), "string_val"), + ] + for value, expected_case in cases: + assert value.WhichOneof("val") == expected_case + + +def test_write_to_online_store_request_string_features(): + request = WriteToOnlineStoreRequest( + features={"driver_id": "1001", "avg_daily_trips": "10"}, + feature_view_name="driver_hourly_stats", + ) + assert request.features["driver_id"] == "1001" + assert request.features["avg_daily_trips"] == "10" + assert len(request.typed_features) == 0 + + +def test_write_to_online_store_request_typed_features(): + request = WriteToOnlineStoreRequest( + typed_features={ + "driver_id": Value(int64_val=1001), + "avg_daily_trips": Value(int32_val=10), + "conv_rate": Value(float_val=0.42), + }, + feature_view_name="driver_hourly_stats", + ) + assert request.typed_features["driver_id"].int64_val == 1001 + assert request.typed_features["avg_daily_trips"].int32_val == 10 + assert request.typed_features["conv_rate"].float_val == pytest.approx(0.42) + assert len(request.features) == 0 + + +def test_push_request_string_and_typed_features_are_independent(): + """Setting features does not affect typed_features and vice versa.""" + r1 = PushRequest( + features={"driver_id": "1001"}, stream_feature_view="s", to="online" + ) + r2 = PushRequest( + typed_features={"driver_id": Value(int64_val=1001)}, + stream_feature_view="s", + to="online", + ) + assert len(r1.typed_features) == 0 + assert len(r2.features) == 0 + + +def test_write_to_online_store_string_and_typed_features_are_independent(): + r1 = WriteToOnlineStoreRequest( + features={"driver_id": "1001"}, feature_view_name="fv" + ) + r2 = WriteToOnlineStoreRequest( + typed_features={"driver_id": Value(int64_val=1001)}, feature_view_name="fv" + ) + assert len(r1.typed_features) == 0 + assert len(r2.features) == 0 + + +def test_parse_typed_null_val_becomes_none(): + """Value(null_val=NULL) must produce None in the DataFrame, not the integer 0.""" + df = parse_typed( + { + "present": Value(int64_val=42), + "missing": Value(null_val=Null.NULL), + } + ) + assert df["present"].iloc[0] == 42 + assert df["missing"].iloc[0] is None + + +def test_parse_typed_unset_val_becomes_none(): + """A Value with no oneof field set (WhichOneof returns None) must also produce None.""" + df = parse_typed({"empty": Value()}) + assert df["empty"].iloc[0] is None + + +def test_parse_typed_list_val_unwrapped_to_python_list(): + """Compound list values are unwrapped from their protobuf wrapper to a plain list.""" + df = parse_typed( + { + "ids": Value(int64_list_val=Int64List(val=[1, 2, 3])), + } + ) + assert df["ids"].iloc[0] == [1, 2, 3] + + +def test_parse_typed_set_val_unwrapped_to_python_list(): + """Compound set values are unwrapped from their protobuf wrapper to a plain list.""" + df = parse_typed( + { + "tags": Value(string_set_val=StringSet(val=["a", "b"])), + } + ) + assert sorted(df["tags"].iloc[0]) == ["a", "b"] + + +def test_parse_typed_map_val_unwrapped_to_python_dict(): + """Map values are unwrapped from their protobuf Map wrapper to a plain dict.""" + df = parse_typed( + { + "scores": Value( + map_val=Map(val={"x": Value(float_val=1.0), "y": Value(float_val=2.0)}) + ), + } + ) + result = df["scores"].iloc[0] + assert isinstance(result, dict) + assert set(result.keys()) == {"x", "y"} diff --git a/sdk/python/tests/unit/test_image_utils.py b/sdk/python/tests/unit/test_image_utils.py index e635b477ce6..f54077f08cf 100644 --- a/sdk/python/tests/unit/test_image_utils.py +++ b/sdk/python/tests/unit/test_image_utils.py @@ -17,10 +17,7 @@ import pytest from PIL import Image -pytest.importorskip("torch") -pytest.importorskip("timm") -pytest.importorskip("sklearn") - +import feast.image_utils as image_utils from feast.image_utils import ( ImageFeatureExtractor, combine_embeddings, @@ -28,6 +25,36 @@ validate_image_format, ) +torch = pytest.importorskip("torch") +pytest.importorskip("timm") +pytest.importorskip("sklearn") + + +@pytest.fixture(autouse=True) +def mock_timm_model(monkeypatch): + class DummyModel: + def eval(self): + return self + + def __call__(self, input_tensor): + batch_size = input_tensor.shape[0] + return torch.arange(1, 5, dtype=torch.float32).repeat(batch_size, 1) + + def create_model(*_args, **_kwargs): + return DummyModel() + + def create_transform(**_config): + def transform(_image): + return torch.ones((3, 224, 224), dtype=torch.float32) + + return transform + + monkeypatch.setattr(image_utils.timm, "create_model", create_model) + monkeypatch.setattr( + image_utils, "resolve_data_config", lambda *_args, **_kwargs: {} + ) + monkeypatch.setattr(image_utils, "create_transform", create_transform) + class TestImageFeatureExtractor: """Test ImageFeatureExtractor functionality.""" diff --git a/sdk/python/tests/unit/test_label_view.py b/sdk/python/tests/unit/test_label_view.py new file mode 100644 index 00000000000..77a752dba12 --- /dev/null +++ b/sdk/python/tests/unit/test_label_view.py @@ -0,0 +1,419 @@ +from datetime import timedelta + +import pytest + +from feast.data_source import PushSource +from feast.entity import Entity +from feast.feature_service import FeatureService +from feast.field import Field +from feast.infra.offline_stores.file_source import FileSource +from feast.labeling import ConflictPolicy, LabelView +from feast.protos.feast.core.LabelView_pb2 import ( + ConflictResolutionPolicy as ConflictResolutionPolicyProto, +) +from feast.protos.feast.core.LabelView_pb2 import LabelView as LabelViewProto +from feast.types import Float32, String +from feast.value_type import ValueType + + +def _sample_label_view() -> LabelView: + interaction = Entity( + name="interaction", + join_keys=["interaction_id"], + value_type=ValueType.STRING, + ) + label_push = PushSource( + name="label_push", + batch_source=FileSource(path="labels.parquet", timestamp_field="ts"), + ) + return LabelView( + name="interaction_labels", + source=label_push, + entities=[interaction], + schema=[ + Field(name="interaction_id", dtype=String), + Field(name="reward_label", dtype=String), + Field(name="safety_score", dtype=Float32), + Field(name="labeler", dtype=String), + ], + labeler_field="labeler", + conflict_policy=ConflictPolicy.LAST_WRITE_WINS, + reference_feature_view="interaction_history", + ttl=timedelta(days=90), + online=True, + description="Mutable reward labels", + tags={"team": "safety"}, + owner="safety@example.com", + ) + + +class TestLabelViewCreation: + def test_basic_creation(self): + lv = _sample_label_view() + assert lv.name == "interaction_labels" + assert lv.entities == ["interaction"] + assert len(lv.features) == 3 + assert len(lv.entity_columns) == 1 + assert lv.labeler_field == "labeler" + assert lv.conflict_policy == ConflictPolicy.LAST_WRITE_WINS + assert lv.reference_feature_view == "interaction_history" + assert lv.ttl == timedelta(days=90) + assert lv.online is True + assert lv.description == "Mutable reward labels" + assert lv.tags == {"team": "safety"} + assert lv.owner == "safety@example.com" + + def test_default_values(self): + entity = Entity(name="item", join_keys=["item_id"], value_type=ValueType.STRING) + lv = LabelView( + name="minimal_labels", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="quality_label", dtype=String), + ], + ) + assert lv.labeler_field == "labeler" + assert lv.conflict_policy == ConflictPolicy.LAST_WRITE_WINS + assert lv.reference_feature_view == "" + assert lv.ttl == timedelta(days=0) + assert lv.online is True + + def test_conflicting_entity_join_keys_raises(self): + e1 = Entity(name="e1", join_keys=["shared_key"]) + e2 = Entity(name="e2", join_keys=["shared_key"]) + with pytest.raises(ValueError, match="share a join key"): + LabelView( + name="bad", + entities=[e1, e2], + schema=[Field(name="shared_key", dtype=String)], + ) + + def test_feature_columns_exclude_entity_columns(self): + lv = _sample_label_view() + feature_names = {f.name for f in lv.features} + entity_names = {f.name for f in lv.entity_columns} + assert feature_names == {"reward_label", "safety_score", "labeler"} + assert entity_names == {"interaction_id"} + assert feature_names.isdisjoint(entity_names) + + +class TestLabelViewProtoRoundtrip: + def test_to_proto(self): + lv = _sample_label_view() + proto = lv.to_proto() + assert isinstance(proto, LabelViewProto) + assert proto.spec.name == "interaction_labels" + assert list(proto.spec.entities) == ["interaction"] + assert len(proto.spec.features) == 3 + assert len(proto.spec.entity_columns) == 1 + assert proto.spec.labeler_field == "labeler" + assert ( + proto.spec.conflict_policy == ConflictResolutionPolicyProto.LAST_WRITE_WINS + ) + assert proto.spec.reference_feature_view == "interaction_history" + assert proto.spec.online is True + assert proto.spec.description == "Mutable reward labels" + assert dict(proto.spec.tags) == {"team": "safety"} + assert proto.spec.owner == "safety@example.com" + + def test_from_proto_roundtrip(self): + lv = _sample_label_view() + proto = lv.to_proto() + lv2 = LabelView.from_proto(proto) + + assert lv2.name == lv.name + assert lv2.entities == lv.entities + assert sorted(f.name for f in lv2.features) == sorted( + f.name for f in lv.features + ) + assert sorted(f.name for f in lv2.entity_columns) == sorted( + f.name for f in lv.entity_columns + ) + assert lv2.labeler_field == lv.labeler_field + assert lv2.conflict_policy == lv.conflict_policy + assert lv2.reference_feature_view == lv.reference_feature_view + assert lv2.ttl == lv.ttl + assert lv2.online == lv.online + assert lv2.description == lv.description + assert lv2.tags == lv.tags + assert lv2.owner == lv.owner + + def test_all_conflict_policies_roundtrip(self): + entity = Entity(name="item", join_keys=["item_id"], value_type=ValueType.STRING) + for policy in ConflictPolicy: + lv = LabelView( + name=f"lv_{policy.name}", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="label", dtype=String), + ], + conflict_policy=policy, + ) + proto = lv.to_proto() + lv2 = LabelView.from_proto(proto) + assert lv2.conflict_policy == policy + + +class TestLabelViewCopyAndEquality: + def test_copy(self): + lv = _sample_label_view() + lv_copy = lv.__copy__() + assert lv_copy == lv + assert lv_copy is not lv + assert lv_copy.features is not lv.features + + def test_equality_detects_differences(self): + lv1 = _sample_label_view() + lv2 = _sample_label_view() + assert lv1 == lv2 + + lv2_mod = lv2.__copy__() + lv2_mod.labeler_field = "annotator" + assert lv1 != lv2_mod + + def test_equality_type_check(self): + lv = _sample_label_view() + with pytest.raises(TypeError): + lv == "not a label view" + + def test_hash_by_name(self): + lv1 = _sample_label_view() + lv2 = _sample_label_view() + assert hash(lv1) == hash(lv2) + + +class TestLabelViewValidation: + def test_ensure_valid_raises_on_empty_name(self): + entity = Entity(name="e", join_keys=["eid"], value_type=ValueType.STRING) + lv = LabelView( + name="", + entities=[entity], + schema=[Field(name="eid", dtype=String)], + ) + with pytest.raises(ValueError, match="needs a name"): + lv.ensure_valid() + + def test_ensure_valid_raises_on_no_entities(self): + lv = LabelView.__new__(LabelView) + lv.name = "test" + lv.entities = [] + lv.features = [] + lv.entity_columns = [] + lv.tags = {} + with pytest.raises(ValueError, match="no entities"): + lv.ensure_valid() + + +class TestLabelViewProtoClass: + def test_proto_class_property(self): + lv = _sample_label_view() + assert lv.proto_class == LabelViewProto + + +class TestLabelViewInFeatureService: + def test_label_view_in_feature_service(self): + lv = _sample_label_view() + fs = FeatureService( + name="training_service", + features=[lv], + ) + assert len(fs.feature_view_projections) == 1 + assert fs.feature_view_projections[0].name == "interaction_labels" + + +class TestLabelViewRegistryRoundtrip: + """Tests that LabelView can be applied/retrieved from the file-based registry proto.""" + + def test_registry_proto_roundtrip(self): + from feast.infra.registry.proto_registry_utils import ( + get_label_view, + list_label_views, + ) + from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto + + lv = _sample_label_view() + proto = lv.to_proto() + proto.spec.project = "test_project" + + registry = RegistryProto() + registry.label_views.append(proto) + + # list + views = list_label_views(registry, "test_project", None) + assert len(views) == 1 + assert views[0].name == "interaction_labels" + assert views[0].labeler_field == "labeler" + assert views[0].conflict_policy == ConflictPolicy.LAST_WRITE_WINS + + # get + lv_got = get_label_view(registry, "interaction_labels", "test_project") + assert lv_got.name == "interaction_labels" + + def test_registry_proto_get_not_found(self): + from feast.errors import FeatureViewNotFoundException + from feast.infra.registry.proto_registry_utils import get_label_view + from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto + + registry = RegistryProto() + with pytest.raises(FeatureViewNotFoundException): + get_label_view(registry, "nonexistent", "test_project") + + def test_list_all_feature_views_includes_label_views(self): + from feast.infra.registry.proto_registry_utils import list_all_feature_views + from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto + + lv = _sample_label_view() + proto = lv.to_proto() + proto.spec.project = "test_project" + + registry = RegistryProto() + registry.label_views.append(proto) + + all_views = list_all_feature_views(registry, "test_project", None) + assert any(isinstance(v, LabelView) for v in all_views) + + def test_get_any_feature_view_finds_label_view(self): + from feast.infra.registry.proto_registry_utils import get_any_feature_view + from feast.protos.feast.core.Registry_pb2 import Registry as RegistryProto + + lv = _sample_label_view() + proto = lv.to_proto() + proto.spec.project = "test_project" + + registry = RegistryProto() + registry.label_views.append(proto) + + found = get_any_feature_view(registry, "interaction_labels", "test_project") + assert isinstance(found, LabelView) + assert found.name == "interaction_labels" + + def test_repo_contents_includes_label_views(self): + from feast.repo_contents import RepoContents + + lv = _sample_label_view() + rc = RepoContents( + projects=[], + data_sources=[], + feature_views=[], + on_demand_feature_views=[], + stream_feature_views=[], + label_views=[lv], + entities=[], + feature_services=[], + permissions=[], + ) + reg_proto = rc.to_registry_proto() + assert len(reg_proto.label_views) == 1 + assert reg_proto.label_views[0].spec.name == "interaction_labels" + + def test_feast_object_type_label_view(self): + from feast.infra.registry.registry import FeastObjectType + + assert FeastObjectType.LABEL_VIEW.value == "label view" + + +class TestLabelViewBatchSourceProperty: + """Tests for the batch_source / stream_source compatibility properties.""" + + def test_batch_source_from_push_source(self): + lv = _sample_label_view() + assert lv.batch_source is not None + assert isinstance(lv.batch_source, FileSource) + + def test_stream_source_from_push_source(self): + lv = _sample_label_view() + assert lv.stream_source is not None + assert isinstance(lv.stream_source, PushSource) + + def test_batch_source_from_file_source(self): + entity = Entity(name="item", join_keys=["item_id"], value_type=ValueType.STRING) + fs = FileSource(path="data.parquet", timestamp_field="ts") + lv = LabelView( + name="file_labels", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="label", dtype=String), + ], + source=fs, + ) + assert lv.batch_source is fs + assert lv.stream_source is None + + def test_batch_source_none_when_no_source(self): + entity = Entity(name="item", join_keys=["item_id"], value_type=ValueType.STRING) + lv = LabelView( + name="no_source_labels", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="label", dtype=String), + ], + ) + assert lv.batch_source is None + assert lv.stream_source is None + + +class TestLabelViewFeatureStoreIntegration: + """Tests for FeatureStore integration without needing a real store.""" + + def test_label_view_in_feature_views_list_includes_type(self): + from feast.feature_view import FeatureView as FV + from feast.on_demand_feature_view import OnDemandFeatureView as ODFV + + lv = _sample_label_view() + assert not isinstance(lv, FV) + assert not isinstance(lv, ODFV) + + def test_validate_feature_views_catches_name_conflict(self): + from feast.feature_store import _validate_feature_views + + entity = Entity(name="item", join_keys=["item_id"], value_type=ValueType.STRING) + lv1 = LabelView( + name="my_view", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="label", dtype=String), + ], + ) + lv2 = LabelView( + name="MY_VIEW", + entities=[entity], + schema=[ + Field(name="item_id", dtype=String), + Field(name="label", dtype=String), + ], + ) + from feast.errors import ConflictingFeatureViewNames + + with pytest.raises(ConflictingFeatureViewNames): + _validate_feature_views([lv1, lv2]) + + def test_materialization_task_accepts_label_view(self): + from datetime import datetime + + from feast.infra.common.materialization_job import MaterializationTask + + lv = _sample_label_view() + task = MaterializationTask( + project="test", + feature_view=lv, + start_time=datetime(2025, 1, 1), + end_time=datetime(2025, 1, 2), + ) + assert task.feature_view.name == "interaction_labels" + + +class TestConflictPolicy: + def test_proto_roundtrip(self): + for policy in ConflictPolicy: + proto_val = policy.to_proto() + assert ConflictPolicy.from_proto(proto_val) == policy + + def test_enum_values(self): + assert ConflictPolicy.LAST_WRITE_WINS.value == "last_write_wins" + assert ConflictPolicy.LABELER_PRIORITY.value == "labeler_priority" + assert ConflictPolicy.MAJORITY_VOTE.value == "majority_vote" diff --git a/sdk/python/tests/unit/test_metrics.py b/sdk/python/tests/unit/test_metrics.py index ba014064669..6099fabb46c 100644 --- a/sdk/python/tests/unit/test_metrics.py +++ b/sdk/python/tests/unit/test_metrics.py @@ -18,29 +18,40 @@ import pytest from feast.metrics import ( + emit_offline_audit_log, + emit_online_audit_log, feature_freshness_seconds, materialization_duration_seconds, - materialization_total, + materialization_result_total, + offline_store_request_latency_seconds, + offline_store_request_total, + offline_store_row_count, online_features_entity_count, online_features_request_count, + online_features_status_total, + online_store_read_duration_seconds, push_request_count, request_count, request_latency, + track_feature_statuses, track_materialization, track_online_features_entities, + track_online_store_read, track_push, track_request_latency, + track_transformation, + track_write_transformation, + transformation_duration_seconds, update_feature_freshness, + write_transformation_duration_seconds, ) -@pytest.fixture(autouse=True) -def _enable_metrics(): - """Enable all metric categories for each test, then restore.""" +def _all_enabled_flags(): + """Return a _MetricsFlags with every category enabled.""" import feast.metrics as m - original = m._config - m._config = m._MetricsFlags( + return m._MetricsFlags( enabled=True, resource=True, request=True, @@ -48,7 +59,18 @@ def _enable_metrics(): push=True, materialization=True, freshness=True, + offline_features=True, + audit_logging=True, ) + + +@pytest.fixture(autouse=True) +def _enable_metrics(): + """Enable all metric categories for each test, then restore.""" + import feast.metrics as m + + original = m._config + m._config = _all_enabled_flags() yield m._config = original @@ -201,12 +223,12 @@ def test_track_push_noop_when_disabled(self): def test_track_materialization_noop_when_disabled(self): self._all_off() - before = materialization_total.labels( + before = materialization_result_total.labels( feature_view="fv_disabled", status="success" )._value.get() track_materialization("fv_disabled", success=True, duration_seconds=1.0) assert ( - materialization_total.labels( + materialization_result_total.labels( feature_view="fv_disabled", status="success" )._value.get() == before @@ -267,12 +289,12 @@ def test_online_features_disabled_but_materialization_enabled(self): assert online_features_request_count._value.get() == before_of # materialization should still record - before_mat = materialization_total.labels( + before_mat = materialization_result_total.labels( feature_view="fv_gran", status="success" )._value.get() track_materialization("fv_gran", success=True, duration_seconds=1.0) assert ( - materialization_total.labels( + materialization_result_total.labels( feature_view="fv_gran", status="success" )._value.get() == before_mat + 1 @@ -298,7 +320,7 @@ def test_only_resource_enabled(self): before_push = push_request_count.labels( push_source="x", mode="offline" )._value.get() - before_mat = materialization_total.labels( + before_mat = materialization_result_total.labels( feature_view="fv_res", status="success" )._value.get() @@ -315,7 +337,7 @@ def test_only_resource_enabled(self): == before_push ) assert ( - materialization_total.labels( + materialization_result_total.labels( feature_view="fv_res", status="success" )._value.get() == before_mat @@ -429,6 +451,71 @@ def test_records_entity_count(self): assert online_features_entity_count._sum.get() >= before_count + 42 +class TestTrackFeatureStatuses: + def test_increments_present_and_not_found(self): + before_present = online_features_status_total.labels( + feature_view="fv_status", status="present" + )._value.get() + before_not_found = online_features_status_total.labels( + feature_view="fv_status", status="not_found" + )._value.get() + + track_feature_statuses("fv_status", present_count=3, not_found_count=2) + + assert ( + online_features_status_total.labels( + feature_view="fv_status", status="present" + )._value.get() + == before_present + 3 + ) + assert ( + online_features_status_total.labels( + feature_view="fv_status", status="not_found" + )._value.get() + == before_not_found + 2 + ) + + @patch("feast.metrics.track_feature_statuses") + def test_populate_response_passes_correct_counts(self, mock_track): + """Integration: _populate_response_from_feature_data computes and + forwards the right present/not_found counts. + + 3 entities, 2 features each: + Entity 0 — both present (2 PRESENT) + Entity 1 — missing (2 NOT_FOUND) + Entity 2 — partial (1 PRESENT, 1 NOT_FOUND) + """ + from feast.protos.feast.serving.ServingService_pb2 import ( + GetOnlineFeaturesResponse, + ) + from feast.protos.feast.types.Value_pb2 import Value as ValueProto + from feast.utils import _populate_response_from_feature_data + + now = datetime.now(tz=timezone.utc) + val = ValueProto(int64_val=1) + table = MagicMock() + table.name = "driver_fv" + table.projection.name_to_use.return_value = "driver_fv" + table.projection.name_alias = None + table.projection.name = "driver_fv" + + _populate_response_from_feature_data( + requested_features=["feat_a", "feat_b"], + read_rows=[ + (now, {"feat_a": val, "feat_b": val}), + (None, None), + (now, {"feat_a": val}), + ], + indexes=([0], [1], [2]), + online_features_response=GetOnlineFeaturesResponse(), + full_feature_names=False, + table=table, + output_len=3, + ) + + mock_track.assert_called_once_with("driver_fv", 3, 3) + + class TestTrackPush: def test_increments_push_counter(self): before = push_request_count.labels( @@ -445,24 +532,24 @@ def test_increments_push_counter(self): class TestTrackMaterialization: def test_success_counter(self): - before = materialization_total.labels( + before = materialization_result_total.labels( feature_view="fv1", status="success" )._value.get() track_materialization("fv1", success=True, duration_seconds=1.5) assert ( - materialization_total.labels( + materialization_result_total.labels( feature_view="fv1", status="success" )._value.get() == before + 1 ) def test_failure_counter(self): - before = materialization_total.labels( + before = materialization_result_total.labels( feature_view="fv2", status="failure" )._value.get() track_materialization("fv2", success=False, duration_seconds=0.5) assert ( - materialization_total.labels( + materialization_result_total.labels( feature_view="fv2", status="failure" )._value.get() == before + 1 @@ -487,9 +574,16 @@ def test_sets_freshness_for_materialized_views(self): minutes=5 ) + mock_sfv = MagicMock() + mock_sfv.name = "test_sfv" + mock_sfv.most_recent_end_time = datetime.now(tz=timezone.utc) - timedelta( + minutes=5 + ) + mock_store = MagicMock() mock_store.project = "test_project" mock_store.list_feature_views.return_value = [mock_fv] + mock_store.list_stream_feature_views.return_value = [mock_sfv] update_feature_freshness(mock_store) @@ -498,6 +592,11 @@ def test_sets_freshness_for_materialized_views(self): )._value.get() assert 280 < staleness < 320 + sfv_staleness = feature_freshness_seconds.labels( + feature_view="test_sfv", project="test_project" + )._value.get() + assert 280 < sfv_staleness < 320 + def test_skips_unmaterialized_views(self): mock_fv = MagicMock() mock_fv.name = "unmaterialized_fv" @@ -506,6 +605,7 @@ def test_skips_unmaterialized_views(self): mock_store = MagicMock() mock_store.project = "test_project" mock_store.list_feature_views.return_value = [mock_fv] + mock_store.list_stream_feature_views.return_value = [] update_feature_freshness(mock_store) @@ -519,6 +619,7 @@ def test_handles_naive_datetime(self): mock_store = MagicMock() mock_store.project = "test_project" mock_store.list_feature_views.return_value = [mock_fv] + mock_store.list_stream_feature_views.return_value = [] update_feature_freshness(mock_store) @@ -824,3 +925,823 @@ def test_cleanup_runs_in_owner_process(self, tmp_path): m._prometheus_mp_dir = original_dir m._owns_mp_dir = original_owns m._owner_pid = original_pid + + +class TestTrackOnlineStoreRead: + """Tests for the online store read duration metric.""" + + def test_records_duration(self): + before_sum = online_store_read_duration_seconds._sum.get() + + track_online_store_read(0.123) + + assert online_store_read_duration_seconds._sum.get() >= before_sum + 0.123 + + def test_noop_when_online_features_disabled(self): + import feast.metrics as m + + m._config = m._MetricsFlags(enabled=True, online_features=False) + + before_sum = online_store_read_duration_seconds._sum.get() + + track_online_store_read(0.5) + + assert online_store_read_duration_seconds._sum.get() == before_sum + + m._config = m._MetricsFlags( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + ) + + +class TestTrackTransformation: + """Tests for the ODFV transformation duration metric.""" + + def test_records_python_mode(self): + labels = ("my_odfv", "python") + before = transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_transformation("my_odfv", "python", 0.042) + + sample = transformation_duration_seconds._metrics[labels] + assert sample._sum.get() >= before_sum + 0.042 + + def test_records_pandas_mode(self): + labels = ("my_odfv", "pandas") + before = transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_transformation("my_odfv", "pandas", 0.15) + + sample = transformation_duration_seconds._metrics[labels] + assert sample._sum.get() >= before_sum + 0.15 + + def test_noop_when_online_features_disabled(self): + import feast.metrics as m + + m._config = m._MetricsFlags(enabled=True, online_features=False) + + labels = ("disabled_odfv", "python") + before = transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_transformation("disabled_odfv", "python", 1.0) + + sample = transformation_duration_seconds._metrics.get(labels, None) + after_sum = sample._sum.get() if sample else 0.0 + assert after_sum == before_sum + + m._config = m._MetricsFlags( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + ) + + def test_multiple_odfvs_tracked_independently(self): + labels_a = ("odfv_a", "python") + labels_b = ("odfv_b", "pandas") + before_a = transformation_duration_seconds._metrics.get(labels_a, None) + before_a_sum = before_a._sum.get() if before_a else 0.0 + before_b = transformation_duration_seconds._metrics.get(labels_b, None) + before_b_sum = before_b._sum.get() if before_b else 0.0 + + track_transformation("odfv_a", "python", 0.01) + track_transformation("odfv_b", "pandas", 0.05) + + sample_a = transformation_duration_seconds._metrics[labels_a] + sample_b = transformation_duration_seconds._metrics[labels_b] + assert sample_a._sum.get() >= before_a_sum + 0.01 + assert sample_b._sum.get() >= before_b_sum + 0.05 + + +class TestTrackWriteTransformation: + """Tests for the write-path ODFV transformation duration metric.""" + + def test_records_python_mode(self): + labels = ("write_odfv", "python") + before = write_transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_write_transformation("write_odfv", "python", 0.033) + + sample = write_transformation_duration_seconds._metrics[labels] + assert sample._sum.get() >= before_sum + 0.033 + + def test_records_pandas_mode(self): + labels = ("write_odfv", "pandas") + before = write_transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_write_transformation("write_odfv", "pandas", 0.12) + + sample = write_transformation_duration_seconds._metrics[labels] + assert sample._sum.get() >= before_sum + 0.12 + + def test_noop_when_online_features_disabled(self): + import feast.metrics as m + + m._config = m._MetricsFlags(enabled=True, online_features=False) + + labels = ("disabled_write_odfv", "python") + before = write_transformation_duration_seconds._metrics.get(labels, None) + before_sum = before._sum.get() if before else 0.0 + + track_write_transformation("disabled_write_odfv", "python", 1.0) + + sample = write_transformation_duration_seconds._metrics.get(labels, None) + after_sum = sample._sum.get() if sample else 0.0 + assert after_sum == before_sum + + m._config = m._MetricsFlags( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + ) + + def test_separate_from_read_transform_metric(self): + """Write and read transform metrics are independent histograms.""" + read_labels = ("shared_odfv", "python") + write_labels = ("shared_odfv", "python") + + read_before = transformation_duration_seconds._metrics.get(read_labels, None) + read_before_sum = read_before._sum.get() if read_before else 0.0 + write_before = write_transformation_duration_seconds._metrics.get( + write_labels, None + ) + write_before_sum = write_before._sum.get() if write_before else 0.0 + + track_transformation("shared_odfv", "python", 0.01) + track_write_transformation("shared_odfv", "python", 0.05) + + read_after = transformation_duration_seconds._metrics[read_labels] + write_after = write_transformation_duration_seconds._metrics[write_labels] + + read_delta = read_after._sum.get() - read_before_sum + write_delta = write_after._sum.get() - write_before_sum + + assert abs(read_delta - 0.01) < 0.001 + assert abs(write_delta - 0.05) < 0.001 + + +class TestOfflineStoreMetrics: + """Tests for the offline store Prometheus metrics (RED pattern).""" + + def test_request_total_increments_on_success(self): + before = offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + + offline_store_request_total.labels(method="to_arrow", status="success").inc() + + assert ( + offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + == before + 1 + ) + + def test_request_total_increments_on_error(self): + before = offline_store_request_total.labels( + method="to_arrow", status="error" + )._value.get() + + offline_store_request_total.labels(method="to_arrow", status="error").inc() + + assert ( + offline_store_request_total.labels( + method="to_arrow", status="error" + )._value.get() + == before + 1 + ) + + def test_latency_histogram_records(self): + before_sum = offline_store_request_latency_seconds.labels( + method="to_arrow" + )._sum.get() + + offline_store_request_latency_seconds.labels(method="to_arrow").observe(2.5) + + after_sum = offline_store_request_latency_seconds.labels( + method="to_arrow" + )._sum.get() + assert pytest.approx(after_sum - before_sum, abs=0.01) == 2.5 + + def test_row_count_histogram_records(self): + before_sum = offline_store_row_count.labels(method="to_arrow")._sum.get() + + offline_store_row_count.labels(method="to_arrow").observe(1000) + + after_sum = offline_store_row_count.labels(method="to_arrow")._sum.get() + assert pytest.approx(after_sum - before_sum, abs=1) == 1000 + + def test_different_methods_tracked_independently(self): + before_a = offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + before_b = offline_store_request_total.labels( + method="other", status="success" + )._value.get() + + offline_store_request_total.labels(method="to_arrow", status="success").inc() + + assert ( + offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + == before_a + 1 + ) + assert ( + offline_store_request_total.labels( + method="other", status="success" + )._value.get() + == before_b + ) + + +class TestEmitAuditLogs: + """Tests for structured JSON audit log emission.""" + + def test_emit_online_audit_log_writes_json(self): + import json + import logging + + _audit_logger = logging.getLogger("feast.audit") + with patch.object(_audit_logger, "info") as mock_info: + emit_online_audit_log( + requestor_id="user@example.com", + entity_keys=["driver_id", "customer_id"], + entity_count=10, + feature_views=["driver_fv", "order_fv"], + feature_count=5, + status="success", + latency_ms=42.0, + ) + + mock_info.assert_called_once() + logged_json = mock_info.call_args[0][0] + record = json.loads(logged_json) + + assert record["event"] == "online_feature_request" + assert record["requestor_id"] == "user@example.com" + assert record["entity_keys"] == ["driver_id", "customer_id"] + assert record["entity_count"] == 10 + assert record["feature_views"] == ["driver_fv", "order_fv"] + assert record["feature_count"] == 5 + assert record["status"] == "success" + assert record["latency_ms"] == pytest.approx(42.0) + assert "timestamp" in record + + def test_emit_online_audit_log_noop_when_disabled(self): + import logging + + import feast.metrics as m + + m._config = m._MetricsFlags(enabled=True, audit_logging=False) + _audit_logger = logging.getLogger("feast.audit") + with patch.object(_audit_logger, "info") as mock_info: + emit_online_audit_log( + requestor_id="user@example.com", + entity_keys=["driver_id"], + entity_count=1, + feature_views=["driver_fv"], + feature_count=1, + status="success", + latency_ms=10.0, + ) + mock_info.assert_not_called() + + def test_emit_offline_audit_log_writes_json(self): + import json + import logging + + _audit_logger = logging.getLogger("feast.audit") + with patch.object(_audit_logger, "info") as mock_info: + emit_offline_audit_log( + method="to_arrow", + feature_views=["driver_fv"], + feature_count=3, + row_count=500, + status="success", + start_time="2026-04-27T12:00:00+00:00", + end_time="2026-04-27T12:00:01+00:00", + duration_ms=1230.0, + ) + + mock_info.assert_called_once() + logged_json = mock_info.call_args[0][0] + record = json.loads(logged_json) + + assert record["event"] == "offline_feature_retrieval" + assert "timestamp" in record + assert record["method"] == "to_arrow" + assert record["feature_views"] == ["driver_fv"] + assert record["feature_count"] == 3 + assert record["row_count"] == 500 + assert record["status"] == "success" + assert record["duration_ms"] == pytest.approx(1230.0) + assert record["start_time"] == "2026-04-27T12:00:00+00:00" + assert record["end_time"] == "2026-04-27T12:00:01+00:00" + + def test_emit_offline_audit_log_noop_when_disabled(self): + import logging + + import feast.metrics as m + + m._config = m._MetricsFlags(enabled=True, audit_logging=False) + _audit_logger = logging.getLogger("feast.audit") + with patch.object(_audit_logger, "info") as mock_info: + emit_offline_audit_log( + method="to_arrow", + feature_views=["fv"], + feature_count=1, + row_count=10, + status="success", + start_time="t0", + end_time="t1", + duration_ms=500.0, + ) + mock_info.assert_not_called() + + def test_emit_online_audit_log_with_error_status(self): + import json + import logging + + _audit_logger = logging.getLogger("feast.audit") + with patch.object(_audit_logger, "info") as mock_info: + emit_online_audit_log( + requestor_id="unknown", + entity_keys=[], + entity_count=0, + feature_views=[], + feature_count=0, + status="error", + latency_ms=1.0, + ) + + record = json.loads(mock_info.call_args[0][0]) + assert record["status"] == "error" + + +class TestBuildMetricsFlagsOfflineAndAudit: + """Tests for the new offline_features and audit_logging flags.""" + + def test_no_config_defaults_for_new_flags(self): + from feast.metrics import build_metrics_flags + + flags = build_metrics_flags(None) + assert flags.offline_features is True + assert flags.audit_logging is False + + def test_explicit_enable(self): + from types import SimpleNamespace + + from feast.metrics import build_metrics_flags + + mc = SimpleNamespace( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + offline_features=True, + audit_logging=True, + ) + flags = build_metrics_flags(mc) + assert flags.offline_features is True + assert flags.audit_logging is True + + def test_explicit_disable(self): + from types import SimpleNamespace + + from feast.metrics import build_metrics_flags + + mc = SimpleNamespace( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + offline_features=False, + audit_logging=False, + ) + flags = build_metrics_flags(mc) + assert flags.offline_features is False + assert flags.audit_logging is False + + def test_missing_new_attrs_fall_back_to_defaults(self): + from types import SimpleNamespace + + from feast.metrics import build_metrics_flags + + mc = SimpleNamespace( + enabled=True, + resource=True, + request=True, + online_features=True, + push=True, + materialization=True, + freshness=True, + ) + flags = build_metrics_flags(mc) + assert flags.offline_features is True + assert flags.audit_logging is False + + +class TestExtractRetrievalMetadata: + """Tests for _extract_retrieval_metadata helper.""" + + def test_extracts_feature_views_and_count(self): + from feast.infra.offline_stores.offline_store import ( + RetrievalMetadata, + _extract_retrieval_metadata, + ) + + job = MagicMock() + job.metadata = RetrievalMetadata( + features=[ + "driver_fv:conv_rate", + "driver_fv:acc_rate", + "vehicle_fv:mileage", + ], + keys=["driver_id"], + ) + + fv_names, feat_count = _extract_retrieval_metadata(job) + assert feat_count == 3 + assert set(fv_names) == {"driver_fv", "vehicle_fv"} + + def test_returns_empty_when_no_metadata(self): + from feast.infra.offline_stores.offline_store import ( + _extract_retrieval_metadata, + ) + + job = MagicMock() + job.metadata = None + + fv_names, feat_count = _extract_retrieval_metadata(job) + assert fv_names == [] + assert feat_count == 0 + + def test_handles_not_implemented_metadata(self): + from feast.infra.offline_stores.offline_store import ( + _extract_retrieval_metadata, + ) + + job = MagicMock() + type(job).metadata = property( + lambda self: (_ for _ in ()).throw(NotImplementedError()) + ) + + fv_names, feat_count = _extract_retrieval_metadata(job) + assert fv_names == [] + assert feat_count == 0 + + +class TestRetrievalJobToArrowInstrumentation: + """Tests for the metrics/audit instrumentation in RetrievalJob.to_arrow().""" + + def _make_job( + self, table, on_demand_fvs=None, metadata=None, raise_on_internal=None + ): + """Create a concrete RetrievalJob subclass for testing.""" + from feast.infra.offline_stores.offline_store import RetrievalJob + + class _TestJob(RetrievalJob): + def __init__(self): + self._table = table + self._odfvs = on_demand_fvs or [] + self._metadata = metadata + self._raise = raise_on_internal + + def _to_arrow_internal(self, timeout=None): + if self._raise: + raise self._raise + return self._table + + @property + def full_feature_names(self): + return False + + @property + def on_demand_feature_views(self): + return self._odfvs + + @property + def metadata(self): + return self._metadata + + return _TestJob() + + def test_success_increments_counter_and_records_latency(self): + import pyarrow as pa + + table = pa.table({"col": [1, 2, 3]}) + job = self._make_job(table) + + before_count = offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + before_latency = offline_store_request_latency_seconds.labels( + method="to_arrow" + )._sum.get() + + result = job.to_arrow() + + assert result.num_rows == 3 + assert ( + offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + == before_count + 1 + ) + assert ( + offline_store_request_latency_seconds.labels(method="to_arrow")._sum.get() + > before_latency + ) + + def test_error_increments_error_counter(self): + job = self._make_job(None, raise_on_internal=RuntimeError("query failed")) + + before_error = offline_store_request_total.labels( + method="to_arrow", status="error" + )._value.get() + + with pytest.raises(RuntimeError, match="query failed"): + job.to_arrow() + + assert ( + offline_store_request_total.labels( + method="to_arrow", status="error" + )._value.get() + == before_error + 1 + ) + + def test_row_count_recorded_on_success(self): + import pyarrow as pa + + table = pa.table({"a": list(range(500))}) + job = self._make_job(table) + + before_sum = offline_store_row_count.labels(method="to_arrow")._sum.get() + + job.to_arrow() + + assert ( + offline_store_row_count.labels(method="to_arrow")._sum.get() + >= before_sum + 500 + ) + + def test_row_count_recorded_when_zero(self): + """Zero-row result must still record an observation so operators can + distinguish 'metric not emitted' from 'query returned 0 rows'.""" + import pyarrow as pa + + table = pa.table({"a": pa.array([], type=pa.int64())}) + job = self._make_job(table) + + hist = offline_store_row_count.labels(method="to_arrow") + before_bucket = hist._buckets[0].get() + before_sum = hist._sum.get() + before_count = offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + + job.to_arrow() + + assert hist._buckets[0].get() == before_bucket + 1 + assert hist._sum.get() == before_sum # 0 rows adds 0 to sum + assert ( + offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + == before_count + 1 + ) + + def test_metrics_skipped_when_offline_features_disabled(self): + import pyarrow as pa + + import feast.metrics as m + + m._config = m._MetricsFlags( + enabled=True, offline_features=False, audit_logging=False + ) + + table = pa.table({"col": [1, 2]}) + job = self._make_job(table) + + before_count = offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + + job.to_arrow() + + assert ( + offline_store_request_total.labels( + method="to_arrow", status="success" + )._value.get() + == before_count + ) + + def test_audit_log_emitted_on_success(self): + import pyarrow as pa + + from feast.infra.offline_stores.offline_store import RetrievalMetadata + + meta = RetrievalMetadata( + features=["driver_fv:conv_rate", "driver_fv:acc_rate"], + keys=["driver_id"], + ) + table = pa.table({"col": [1, 2, 3]}) + job = self._make_job(table, metadata=meta) + + with patch("feast.metrics.emit_offline_audit_log") as mock_audit: + job.to_arrow() + + mock_audit.assert_called_once() + call_kwargs = mock_audit.call_args[1] + assert call_kwargs["method"] == "to_arrow" + assert call_kwargs["status"] == "success" + assert call_kwargs["row_count"] == 3 + assert call_kwargs["feature_count"] == 2 + assert set(call_kwargs["feature_views"]) == {"driver_fv"} + + def test_audit_log_skipped_when_disabled(self): + import pyarrow as pa + + import feast.metrics as m + + m._config = m._MetricsFlags( + enabled=True, offline_features=True, audit_logging=False + ) + + table = pa.table({"col": [1]}) + job = self._make_job(table) + + with patch("feast.metrics.emit_offline_audit_log") as mock_audit: + job.to_arrow() + mock_audit.assert_not_called() + + def test_instrumentation_failure_does_not_mask_query_error(self): + """If metrics code itself throws, the original query error still propagates.""" + import pyarrow as pa + + table = pa.table({"col": [1]}) + job = self._make_job(table) + + with patch( + "feast.metrics._config", + new_callable=lambda: property( + lambda self: (_ for _ in ()).throw(RuntimeError("metrics broken")) + ), + ): + result = job.to_arrow() + assert result.num_rows == 1 + + +class TestParseFeatureInfo: + """Tests for _parse_feature_info in feature_server.""" + + def test_feature_ref_list(self): + from feast.feature_server import _parse_feature_info + + refs = ["driver_fv:conv_rate", "driver_fv:acc_rate", "vehicle_fv:mileage"] + fv_names, feat_count = _parse_feature_info(refs) + assert feat_count == 3 + assert set(fv_names) == {"driver_fv", "vehicle_fv"} + + def test_empty_list(self): + from feast.feature_server import _parse_feature_info + + fv_names, feat_count = _parse_feature_info([]) + assert fv_names == [] + assert feat_count == 0 + + def test_feature_service(self): + from feast.feature_server import _parse_feature_info + + proj1 = MagicMock() + proj1.name = "driver_fv" + proj1.features = [MagicMock(), MagicMock()] + proj2 = MagicMock() + proj2.name = "order_fv" + proj2.features = [MagicMock()] + + fs_svc = MagicMock() + fs_svc.feature_view_projections = [proj1, proj2] + + from feast.feature_service import FeatureService + + fs_svc.__class__ = FeatureService + + fv_names, feat_count = _parse_feature_info(fs_svc) + assert feat_count == 3 + assert fv_names == ["driver_fv", "order_fv"] + + def test_strips_version_suffix(self): + from feast.feature_server import _parse_feature_info + + refs = ["driver_fv@v2:conv_rate"] + fv_names, feat_count = _parse_feature_info(refs) + assert feat_count == 1 + assert fv_names == ["driver_fv"] + + +class TestEmitOnlineAudit: + """Tests for the _emit_online_audit helper in feature_server.""" + + def test_emits_audit_log_with_anonymous_user(self): + from feast.feature_server import GetOnlineFeaturesRequest, _emit_online_audit + + request = GetOnlineFeaturesRequest( + entities={"driver_id": [1, 2]}, + features=["driver_fv:conv_rate"], + ) + + with ( + patch("feast.feature_server.feast_metrics") as mock_metrics, + patch( + "feast.permissions.security_manager.get_security_manager", + return_value=None, + ), + ): + _emit_online_audit( + request=request, + features=request.features, + entity_count=2, + status="success", + latency_ms=15.0, + ) + + mock_metrics.emit_online_audit_log.assert_called_once() + kwargs = mock_metrics.emit_online_audit_log.call_args[1] + assert kwargs["requestor_id"] == "anonymous" + assert kwargs["entity_keys"] == ["driver_id"] + assert kwargs["entity_count"] == 2 + assert kwargs["status"] == "success" + + def test_emits_audit_log_with_authenticated_user(self): + from feast.feature_server import GetOnlineFeaturesRequest, _emit_online_audit + + request = GetOnlineFeaturesRequest( + entities={"driver_id": [1]}, + features=["driver_fv:conv_rate"], + ) + + mock_sm = MagicMock() + mock_sm.current_user.username = "jdoe" + + with ( + patch("feast.feature_server.feast_metrics") as mock_metrics, + patch( + "feast.permissions.security_manager.get_security_manager", + return_value=mock_sm, + ), + ): + _emit_online_audit( + request=request, + features=request.features, + entity_count=1, + status="success", + latency_ms=10.0, + ) + + kwargs = mock_metrics.emit_online_audit_log.call_args[1] + assert kwargs["requestor_id"] == "jdoe" + + def test_does_not_raise_on_failure(self): + from feast.feature_server import GetOnlineFeaturesRequest, _emit_online_audit + + request = GetOnlineFeaturesRequest( + entities={"driver_id": [1]}, + features=["driver_fv:conv_rate"], + ) + + with patch( + "feast.permissions.security_manager.get_security_manager", + side_effect=RuntimeError("auth broken"), + ): + _emit_online_audit( + request=request, + features=request.features, + entity_count=1, + status="error", + latency_ms=5.0, + ) diff --git a/sdk/python/tests/unit/test_offline_server.py b/sdk/python/tests/unit/test_offline_server.py index c5f309eb323..3e25e5c2061 100644 --- a/sdk/python/tests/unit/test_offline_server.py +++ b/sdk/python/tests/unit/test_offline_server.py @@ -1,347 +1,88 @@ -import os -import tempfile -from datetime import datetime, timedelta +from unittest.mock import MagicMock, patch import assertpy -import pandas as pd -import pyarrow as pa -import pyarrow.flight as flight -import pytest -from feast import FeatureStore, FeatureView, FileSource -from feast.errors import FeatureViewNotFoundException -from feast.feature_logging import FeatureServiceLoggingSource from feast.infra.offline_stores.remote import ( RemoteOfflineStore, RemoteOfflineStoreConfig, + _create_retrieval_metadata, ) -from feast.offline_server import OfflineServer, _init_auth_manager -from feast.repo_config import RepoConfig -from feast.torch_wrapper import get_torch -from tests.utils.cli_repo_creator import CliRunner +from feast.offline_server import OfflineServer -PROJECT_NAME = "test_remote_offline" - -@pytest.fixture -def empty_offline_server(environment): - store = environment.feature_store - - location = "grpc+tcp://localhost:0" - _init_auth_manager(store=store) - return OfflineServer(store=store, location=location) - - -@pytest.fixture -def arrow_client(empty_offline_server): - return flight.FlightClient(f"grpc://localhost:{empty_offline_server.port}") - - -def test_offline_server_is_alive(environment, empty_offline_server, arrow_client): - server = empty_offline_server - client = arrow_client - - assertpy.assert_that(server).is_not_none - assertpy.assert_that(server.port).is_not_equal_to(0) - - actions = list(client.list_actions()) - flights = list(client.list_flights()) - - assertpy.assert_that(actions).is_equal_to( - [ - ( - "offline_write_batch", - "Writes the specified arrow table to the data source underlying the specified feature view.", - ), - ( - "write_logged_features", - "Writes logged features to a specified destination in the offline store.", - ), - ( - "persist", - "Synchronously executes the underlying query and persists the result in the same offline store at the " - "specified destination.", - ), - ] +def test_create_retrieval_metadata_with_sql_string(): + """SQL string entity_df should produce a stub with empty keys and no timestamps.""" + sql = "SELECT driver_id, event_timestamp FROM driver_stats" + metadata = _create_retrieval_metadata( + feature_refs=["driver_hourly_stats:conv_rate"], entity_df=sql ) - assertpy.assert_that(flights).is_empty() - - -def default_store(temp_dir): - runner = CliRunner() - result = runner.run(["init", PROJECT_NAME], cwd=temp_dir) - repo_path = os.path.join(temp_dir, PROJECT_NAME, "feature_repo") - assert result.returncode == 0 - - result = runner.run(["--chdir", repo_path, "apply"], cwd=temp_dir) - assert result.returncode == 0 - - fs = FeatureStore(repo_path=repo_path) - return fs - - -def remote_feature_store(offline_server): - offline_config = RemoteOfflineStoreConfig( - type="remote", host="0.0.0.0", port=offline_server.port - ) - - registry_path = os.path.join( - str(offline_server.store.repo_path), - offline_server.store.config.registry.path, - ) - store = FeatureStore( - config=RepoConfig( - project=PROJECT_NAME, - registry=registry_path, - provider="local", - offline_store=offline_config, - entity_key_serialization_version=3, - # repo_config = - ) + assertpy.assert_that(metadata.features).is_equal_to( + ["driver_hourly_stats:conv_rate"] ) - return store - - -def test_remote_offline_store_apis(): - with tempfile.TemporaryDirectory() as temp_dir: - store = default_store(str(temp_dir)) - location = "grpc+tcp://localhost:0" - - _init_auth_manager(store=store) - server = OfflineServer(store=store, location=location) - - assertpy.assert_that(server).is_not_none - assertpy.assert_that(server.port).is_not_equal_to(0) - - fs = remote_feature_store(server) - - _test_get_historical_features_returns_data(fs) - _test_get_historical_features_to_tensor(fs) - _test_get_historical_features_returns_nan(fs) - _test_get_historical_features_to_tensor_with_nan(fs) - _test_offline_write_batch(str(temp_dir), fs) - _test_write_logged_features(str(temp_dir), fs) - _test_pull_latest_from_table_or_query(str(temp_dir), fs) - _test_pull_all_from_table_or_query(str(temp_dir), fs) - - -def test_remote_offline_store_exception_handling(): - with tempfile.TemporaryDirectory() as temp_dir: - store = default_store(str(temp_dir)) - location = "grpc+tcp://localhost:0" - - _init_auth_manager(store=store) - server = OfflineServer(store=store, location=location) - - assertpy.assert_that(server).is_not_none - assertpy.assert_that(server.port).is_not_equal_to(0) - - fs = remote_feature_store(server) - data_file = os.path.join( - temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" + assertpy.assert_that(list(metadata.keys)).is_empty() + assertpy.assert_that(metadata.min_event_timestamp).is_none() + assertpy.assert_that(metadata.max_event_timestamp).is_none() + + +def test_remote_offline_store_sql_entity_df_routing(): + """RemoteOfflineStore.get_historical_features moves SQL into api_parameters.""" + sql = "SELECT driver_id, event_timestamp FROM driver_stats" + + mock_client = MagicMock() + with patch( + "feast.infra.offline_stores.remote.build_arrow_flight_client", + return_value=mock_client, + ): + job = RemoteOfflineStore.get_historical_features( + config=MagicMock( + offline_store=RemoteOfflineStoreConfig( + type="remote", host="localhost", port=8815 + ), + auth_config=MagicMock(type="no_auth"), + ), + feature_views=[], + feature_refs=["driver_hourly_stats:conv_rate"], + entity_df=sql, + registry=MagicMock(), + project="test", + full_feature_names=False, ) - data_df = pd.read_parquet(data_file) - - with pytest.raises( - FeatureViewNotFoundException, - match="Feature view test does not exist in project test_remote_offline", - ): - RemoteOfflineStore.offline_write_batch( - fs.config, - FeatureView(name="test", source=FileSource(path="test")), - pa.Table.from_pandas(data_df), - progress=None, - ) - - -def _test_get_historical_features_returns_data(fs: FeatureStore): - entity_df = pd.DataFrame.from_dict( - { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [ - datetime(2021, 4, 12, 10, 59, 42), - datetime(2021, 4, 12, 8, 12, 10), - datetime(2021, 4, 12, 16, 40, 26), - ], - "label_driver_reported_satisfaction": [1, 5, 3], - "val_to_add": [1, 2, 3], - "val_to_add_2": [10, 20, 30], - } - ) - - features = [ - "driver_hourly_stats:conv_rate", - "driver_hourly_stats:acc_rate", - "driver_hourly_stats:avg_daily_trips", - "transformed_conv_rate:conv_rate_plus_val1", - "transformed_conv_rate:conv_rate_plus_val2", - ] - - training_df = fs.get_historical_features(entity_df, features).to_df() - - assertpy.assert_that(training_df).is_not_none() - assertpy.assert_that(len(training_df)).is_equal_to(3) - - for index, driver_id in enumerate(entity_df["driver_id"]): - assertpy.assert_that(training_df["driver_id"][index]).is_equal_to(driver_id) - for feature in features: - column_id = feature.split(":")[1] - value = training_df[column_id][index] - assertpy.assert_that(value).is_not_nan() - - -def _test_get_historical_features_to_tensor(fs: FeatureStore): - entity_df = pd.DataFrame.from_dict( - { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [ - datetime(2021, 4, 12, 10, 59, 42), - datetime(2021, 4, 12, 8, 12, 10), - datetime(2021, 4, 12, 16, 40, 26), - ], - "label_driver_reported_satisfaction": [1, 5, 3], - "val_to_add": [1, 2, 3], - "val_to_add_2": [10, 20, 30], - } - ) - - features = [ - "driver_hourly_stats:conv_rate", - "driver_hourly_stats:acc_rate", - "driver_hourly_stats:avg_daily_trips", - "transformed_conv_rate:conv_rate_plus_val1", - "transformed_conv_rate:conv_rate_plus_val2", - ] - - job = fs.get_historical_features(entity_df, features) - tensor_data = job.to_tensor() - - assertpy.assert_that(tensor_data).is_not_none() - assertpy.assert_that(tensor_data["driver_id"].shape[0]).is_equal_to(3) - torch = get_torch() - for key, values in tensor_data.items(): - if isinstance(values, torch.Tensor): - assertpy.assert_that(values.shape[0]).is_equal_to(3) - for val in values: - val_float = val.item() - assertpy.assert_that(val_float).is_instance_of((float, int)) - assertpy.assert_that(val_float).is_not_nan() - -def _test_get_historical_features_returns_nan(fs: FeatureStore): - entity_df = pd.DataFrame.from_dict( - { - "driver_id": [1, 2, 3], - "event_timestamp": [ - datetime(2021, 4, 12, 10, 59, 42), - datetime(2021, 4, 12, 8, 12, 10), - datetime(2021, 4, 12, 16, 40, 26), - ], - "label_driver_reported_satisfaction": [1, 5, 3], - "val_to_add": [1, 2, 3], - "val_to_add_2": [10, 20, 30], - } - ) - - features = [ - "driver_hourly_stats:conv_rate", - "driver_hourly_stats:acc_rate", - "driver_hourly_stats:avg_daily_trips", - "transformed_conv_rate:conv_rate_plus_val1", - "transformed_conv_rate:conv_rate_plus_val2", - ] - - training_df = fs.get_historical_features(entity_df, features).to_df() - - assertpy.assert_that(training_df).is_not_none() - assertpy.assert_that(len(training_df)).is_equal_to(3) - - for index, driver_id in enumerate(entity_df["driver_id"]): - assertpy.assert_that(training_df["driver_id"][index]).is_equal_to(driver_id) - for feature in features: - column_id = feature.split(":")[1] - value = training_df[column_id][index] - assertpy.assert_that(value).is_nan() - - -def _test_get_historical_features_to_tensor_with_nan(fs: FeatureStore): - entity_df = pd.DataFrame.from_dict( - { - "driver_id": [9991, 9992], # IDs with no matching features - "event_timestamp": [ - datetime(2021, 4, 12, 10, 59, 42), - datetime(2021, 4, 12, 10, 59, 42), - ], - } - ) - features = ["driver_hourly_stats:conv_rate"] - job = fs.get_historical_features(entity_df, features) - tensor_data = job.to_tensor() - assert "conv_rate" in tensor_data - values = tensor_data["conv_rate"] - # conv_rate is a float feature, missing values should be NaN - torch = get_torch() - for val in values: - assert isinstance(val, torch.Tensor) or torch.is_tensor(val) - assertpy.assert_that(torch.isnan(val).item()).is_true() + assertpy.assert_that(job.entity_df).is_none() + assertpy.assert_that(job.api_parameters).contains_key("entity_df_sql") + assertpy.assert_that(job.api_parameters["entity_df_sql"]).is_equal_to(sql) -def _test_offline_write_batch(temp_dir, fs: FeatureStore): - data_file = os.path.join( - temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" - ) - data_df = pd.read_parquet(data_file) - feature_view = fs.get_feature_view("driver_hourly_stats") - - RemoteOfflineStore.offline_write_batch( - fs.config, feature_view, pa.Table.from_pandas(data_df), progress=None - ) - - -def _test_write_logged_features(temp_dir, fs: FeatureStore): - data_file = os.path.join( - temp_dir, fs.project, "feature_repo/data/driver_stats.parquet" - ) - data_df = pd.read_parquet(data_file) - feature_service = fs.get_feature_service("driver_activity_v1") - - RemoteOfflineStore.write_logged_features( - config=fs.config, - data=pa.Table.from_pandas(data_df), - source=FeatureServiceLoggingSource(feature_service, fs.config.project), - logging_config=feature_service.logging_config, - registry=fs.registry, - ) +def test_offline_server_get_historical_features_passes_sql_to_store(): + """OfflineServer forwards entity_df_sql to the backing offline store.""" + sql = "SELECT driver_id, event_timestamp FROM driver_stats" + mock_job = MagicMock() + mock_offline_store = MagicMock() + mock_offline_store.get_historical_features.return_value = mock_job -def _test_pull_latest_from_table_or_query(temp_dir, fs: FeatureStore): - data_source = fs.get_data_source("driver_hourly_stats_source") + mock_store = MagicMock() + mock_store.config.project = "test" - end_date = datetime.now().replace(microsecond=0, second=0, minute=0) - start_date = end_date - timedelta(days=15) - RemoteOfflineStore.pull_latest_from_table_or_query( - config=fs.config, - data_source=data_source, - join_key_columns=[], - feature_name_columns=[], - timestamp_field="event_timestamp", - created_timestamp_column="created", - start_date=start_date, - end_date=end_date, - ).to_df() + server = MagicMock(spec=OfflineServer) + server.offline_store = mock_offline_store + server.store = mock_store + server.flights = {} + server.list_feature_views_by_name.return_value = [] + command = { + "api": "get_historical_features", + "command_id": "abc", + "feature_view_names": [], + "name_aliases": [], + "feature_refs": ["driver_hourly_stats:conv_rate"], + "project": "test", + "full_feature_names": False, + "entity_df_sql": sql, + } -def _test_pull_all_from_table_or_query(temp_dir, fs: FeatureStore): - data_source = fs.get_data_source("driver_hourly_stats_source") + result = OfflineServer.get_historical_features(server, command, key=None) - end_date = datetime.now().replace(microsecond=0, second=0, minute=0) - start_date = end_date - timedelta(days=15) - RemoteOfflineStore.pull_all_from_table_or_query( - config=fs.config, - data_source=data_source, - join_key_columns=[], - feature_name_columns=[], - timestamp_field="event_timestamp", - start_date=start_date, - end_date=end_date, - ).to_df() + assertpy.assert_that(result).is_equal_to(mock_job) + _, kwargs = mock_offline_store.get_historical_features.call_args + assertpy.assert_that(kwargs["entity_df"]).is_equal_to(sql) diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index 505146aa612..c63aaa0f435 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -17,6 +17,7 @@ import pandas as pd import pytest +from feast.aggregation import Aggregation from feast.feature_view import FeatureView from feast.field import Field from feast.infra.offline_stores.file_source import FileSource @@ -418,3 +419,332 @@ def another_transform(features_df: pd.DataFrame) -> pd.DataFrame: deserialized = OnDemandFeatureView.from_proto(proto) assert deserialized.name == CUSTOM_FUNCTION_NAME + + +def test_track_metrics_defaults_to_false(): + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="metrics-default-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + ) + assert odfv.track_metrics is False + + +def test_track_metrics_true_persists_via_proto(): + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="tracked-metrics-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + track_metrics=True, + ) + assert odfv.track_metrics is True + + proto = odfv.to_proto() + assert proto.spec.tags.get("feast:track_metrics") == "true" + + restored = OnDemandFeatureView.from_proto(proto) + assert restored.track_metrics is True + assert "feast:track_metrics" not in restored.tags, ( + "Internal feast:track_metrics tag leaked into user-facing self.tags " + "after proto round-trip" + ) + + +def test_track_metrics_proto_roundtrip_preserves_user_tags(): + """User tags must survive a proto round-trip without internal tag pollution.""" + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + user_tags = {"team": "ml-platform", "priority": "high"} + odfv = OnDemandFeatureView( + name="tagged-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + tags=user_tags, + track_metrics=True, + ) + assert odfv.tags == user_tags + + proto = odfv.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + + assert restored.tags == user_tags + assert restored.track_metrics is True + + +def test_track_metrics_false_not_stored_in_tags(): + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="no-metrics-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + track_metrics=False, + ) + proto = odfv.to_proto() + assert "feast:track_metrics" not in proto.spec.tags + + restored = OnDemandFeatureView.from_proto(proto) + assert restored.track_metrics is False + + +def test_copy_preserves_track_metrics(): + """__copy__ must carry track_metrics so FeatureService projections keep timing enabled.""" + import copy + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="tracked-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + track_metrics=True, + ) + assert odfv.track_metrics is True + + copied = copy.copy(odfv) + assert copied.track_metrics is True, ( + "__copy__ lost track_metrics; ODFV timing metrics will be silently disabled " + "when using FeatureService projections" + ) + + +def test_eq_considers_track_metrics(): + """__eq__ must distinguish ODFVs that differ only in track_metrics.""" + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[ + Field(name="feature1", dtype=Float32), + Field(name="feature2", dtype=Float32), + ], + source=file_source, + ) + common = dict( + name="eq-odfv", + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + ) + odfv_tracked = OnDemandFeatureView(**common, track_metrics=True) + odfv_untracked = OnDemandFeatureView(**common, track_metrics=False) + + assert odfv_tracked != odfv_untracked + + +def test_aggregations_valid_without_udf(): + """An ODFV with aggregations must pass ensure_valid() without a udf or feature_transformation.""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + # Must not raise + odfv.ensure_valid() + + +def test_aggregations_only_odfv_proto_roundtrip(): + """Aggregation-only ODFV must survive a proto round-trip without crashing on dill.loads(b'').""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + proto = odfv.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + assert restored.feature_transformation is None + assert len(restored.aggregations) == 1 + assert restored.aggregations[0].column == "purchase_count" + + +def test_aggregations_only_odfv_infer_features(): + """infer_features must not crash for aggregation-only ODFVs with explicit schema.""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + # Must not raise; features are taken from schema, no transformation execution needed + odfv.infer_features() + + +def test_input_schema_aggregation_no_udf(): + """ODFV with input_schema, no sources, aggregations, and no udf must validate and round-trip.""" + from datetime import timedelta + + odfv = OnDemandFeatureView( + name="input-schema-agg-odfv", + sources=None, + input_schema=[Field(name="purchase_count", dtype=Float32)], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + + odfv.ensure_valid() + odfv.infer_features() + + proto = odfv.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + assert restored.feature_transformation is None + assert len(restored.aggregations) == 1 + assert restored.input_schema == [Field(name="purchase_count", dtype=Float32)] + + +def test_on_demand_feature_view_org_field(): + """Test that the optional `org` field is stored, serialized, and round-trips correctly.""" + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="feature1", dtype=Float32)], + source=file_source, + ) + common = dict( + sources=[feature_view], + schema=[Field(name="output1", dtype=Float32)], + feature_transformation=PandasTransformation( + udf=udf1, udf_string="udf1 source code" + ), + ) + + # org defaults to empty string + odfv_no_org = OnDemandFeatureView(name="odfv-no-org", **common) + assert odfv_no_org.org == "" + + # org can be set explicitly + odfv_with_org = OnDemandFeatureView(name="odfv-with-org", org="ads", **common) + assert odfv_with_org.org == "ads" + + # org is serialized to proto + proto = odfv_with_org.to_proto() + assert proto.spec.org == "ads" + + # org survives a proto round-trip + roundtripped = OnDemandFeatureView.from_proto(proto) + assert roundtripped.org == "ads" + + # a view without org round-trips to empty string + proto_no_org = odfv_no_org.to_proto() + assert proto_no_org.spec.org == "" + roundtripped_no_org = OnDemandFeatureView.from_proto(proto_no_org) + assert roundtripped_no_org.org == "" + + # equality respects org + odfv_org_a = OnDemandFeatureView(name="odfv-eq", org="ads", **common) + odfv_org_b = OnDemandFeatureView(name="odfv-eq", org="search", **common) + assert odfv_org_a != odfv_org_b diff --git a/sdk/python/tests/unit/test_on_demand_feature_view_input_schema.py b/sdk/python/tests/unit/test_on_demand_feature_view_input_schema.py new file mode 100644 index 00000000000..fd69762ef08 --- /dev/null +++ b/sdk/python/tests/unit/test_on_demand_feature_view_input_schema.py @@ -0,0 +1,167 @@ +# Copyright 2025 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for OnDemandFeatureView input_schema support.""" + +import copy +from datetime import timedelta + +import pandas as pd +import pytest + +from feast import Entity, Field +from feast.aggregation import Aggregation +from feast.on_demand_feature_view import OnDemandFeatureView, on_demand_feature_view +from feast.types import Float64, Int64 +from feast.value_type import ValueType + +user = Entity(name="user", join_keys=["user_id"], value_type=ValueType.INT64) + + +def test_decorator_with_input_schema(): + """The @on_demand_feature_view decorator supports input_schema without sources.""" + + @on_demand_feature_view( + input_schema=[ + Field(name="txn_amount", dtype=Float64), + ], + schema=[ + Field(name="txn_count", dtype=Int64), + Field(name="total_txn_amount", dtype=Float64), + Field(name="avg_txn_amount", dtype=Float64), + ], + aggregations=[ + Aggregation( + column="txn_amount", + function="count", + name="txn_count", + time_window=timedelta(days=30), + ), + Aggregation( + column="txn_amount", + function="sum", + name="total_txn_amount", + time_window=timedelta(days=30), + ), + Aggregation( + column="txn_amount", + function="mean", + name="avg_txn_amount", + time_window=timedelta(days=30), + ), + ], + entities=[user], + ) + def compute_txn_stats(df: pd.DataFrame) -> pd.DataFrame: + return df + + assert isinstance(compute_txn_stats, OnDemandFeatureView) + assert compute_txn_stats.name == "compute_txn_stats" + assert compute_txn_stats.input_schema == [Field(name="txn_amount", dtype=Float64)] + assert len(compute_txn_stats.aggregations) == 3 + assert len(compute_txn_stats.features) == 3 + + # The internal sentinel RequestSource should be present + sentinel_name = ( + f"{OnDemandFeatureView._INPUT_SCHEMA_SOURCE_PREFIX}compute_txn_stats" + ) + assert sentinel_name in compute_txn_stats.source_request_sources + + # sources (user-visible) should be empty + assert compute_txn_stats.sources == [] + + +def test_aggregation_aliases(): + """Aggregation name and time_window params work correctly.""" + agg = Aggregation( + column="txn_amount", + function="sum", + name="total_txn_amount", + time_window=timedelta(days=30), + ) + assert agg.name == "total_txn_amount" + assert agg.time_window == timedelta(days=30) + + +def test_input_schema_proto_roundtrip(): + """An ODFV with input_schema survives a to_proto / from_proto round-trip.""" + + @on_demand_feature_view( + input_schema=[ + Field(name="txn_amount", dtype=Float64), + ], + schema=[ + Field(name="total_txn_amount", dtype=Float64), + ], + aggregations=[ + Aggregation( + column="txn_amount", + function="sum", + name="total_txn_amount", + time_window=timedelta(days=30), + ), + ], + entities=[user], + ) + def txn_view(df: pd.DataFrame) -> pd.DataFrame: + return df + + proto = txn_view.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + + assert restored.input_schema == txn_view.input_schema + assert restored.aggregations == txn_view.aggregations + sentinel_name = f"{OnDemandFeatureView._INPUT_SCHEMA_SOURCE_PREFIX}txn_view" + assert sentinel_name in restored.source_request_sources + + +def test_input_schema_copy(): + """__copy__ preserves input_schema and aggregations.""" + + @on_demand_feature_view( + input_schema=[ + Field(name="txn_amount", dtype=Float64), + ], + schema=[ + Field(name="total_txn_amount", dtype=Float64), + ], + aggregations=[ + Aggregation(column="txn_amount", function="sum", name="total_txn_amount"), + ], + entities=[user], + ) + def copy_view(df: pd.DataFrame) -> pd.DataFrame: + return df + + cloned = copy.copy(copy_view) + assert cloned.input_schema == copy_view.input_schema + assert cloned.aggregations == copy_view.aggregations + sentinel_name = f"{OnDemandFeatureView._INPUT_SCHEMA_SOURCE_PREFIX}copy_view" + assert sentinel_name in cloned.source_request_sources + + +def test_sources_required_without_input_schema(): + """Constructor raises if neither sources nor input_schema is provided.""" + with pytest.raises( + (ValueError), + ): + + def dummy(df): + return df + + OnDemandFeatureView( + name="bad_view", + schema=[Field(name="out", dtype=Float64)], + udf=dummy, + ) diff --git a/sdk/python/tests/unit/test_openlineage_client.py b/sdk/python/tests/unit/test_openlineage_client.py new file mode 100644 index 00000000000..9be050ce473 --- /dev/null +++ b/sdk/python/tests/unit/test_openlineage_client.py @@ -0,0 +1,151 @@ +# Copyright 2026 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path + +import pytest + +# --------------------------------------------------------------------------- +# Guard: skip entire module if openlineage-python is not installed +# --------------------------------------------------------------------------- +ol = pytest.importorskip( + "openlineage.client", reason="openlineage-python not installed" +) + +from openlineage.client.transport.console import ConsoleTransport # noqa: E402 +from openlineage.client.transport.transform import TransformTransport # noqa: E402 + +from feast.openlineage.client import FeastOpenLineageClient # noqa: E402 +from feast.openlineage.config import OpenLineageConfig # noqa: E402 + +_TRANSFORM_YML = """\ +transport: + type: transform + transformer_class: openlineage.client.transport.transform.JobNamespaceReplaceTransformer + transformer_properties: + new_job_namespace: new_value + transport: + type: console +""" + + +def _write_openlineage_yml(tmp_path: Path, content: str = _TRANSFORM_YML) -> str: + """Write an openlineage.yml file and return its path.""" + yml = tmp_path / "openlineage.yml" + yml.write_text(content) + return str(yml) + + +class TestDefaultConsoleTransport: + """When transport_type is None and there is no openlineage.yml, + the OpenLineage SDK should fall back to ConsoleTransport.""" + + def test_default_config_uses_console_transport( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + # Ensure no openlineage.yml is found by changing cwd to an empty dir + monkeypatch.chdir(tmp_path) + monkeypatch.delenv("OPENLINEAGE_CONFIG", raising=False) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + config = OpenLineageConfig(enabled=True) # transport_type defaults to None + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + assert isinstance(client._client.transport, ConsoleTransport) + + def test_default_from_dict_uses_console_transport( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + monkeypatch.chdir(tmp_path) + monkeypatch.delenv("OPENLINEAGE_CONFIG", raising=False) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + config = OpenLineageConfig.from_dict({"enabled": True}) + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + assert isinstance(client._client.transport, ConsoleTransport) + + +class TestTransformTransportFromYml: + def test_transform_yml_is_respected( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + yml_path = _write_openlineage_yml(tmp_path) + monkeypatch.setenv("OPENLINEAGE_CONFIG", yml_path) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + config = OpenLineageConfig(enabled=True) # transport_type=None + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + assert isinstance(client._client.transport, TransformTransport) + # The inner transport should be console + assert isinstance(client._client.transport.transport, ConsoleTransport) + + def test_transform_yml_in_cwd_is_respected( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + monkeypatch.delenv("OPENLINEAGE_CONFIG", raising=False) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + # Write openlineage.yml in the dir we'll chdir to + _write_openlineage_yml(tmp_path) + monkeypatch.chdir(tmp_path) + + config = OpenLineageConfig(enabled=True) # transport_type=None + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + assert isinstance(client._client.transport, TransformTransport) + + +class TestExplicitConfigOverridesYml: + def test_explicit_console_ignores_yml_env( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + yml_path = _write_openlineage_yml(tmp_path) + monkeypatch.setenv("OPENLINEAGE_CONFIG", yml_path) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + config = OpenLineageConfig(enabled=True, transport_type="console") + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + # Must be plain ConsoleTransport, NOT TransformTransport + assert isinstance(client._client.transport, ConsoleTransport) + assert not isinstance(client._client.transport, TransformTransport) + + def test_explicit_console_ignores_yml_in_cwd( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + monkeypatch.delenv("OPENLINEAGE_CONFIG", raising=False) + monkeypatch.delenv("OPENLINEAGE_URL", raising=False) + monkeypatch.delenv("OPENLINEAGE_DISABLED", raising=False) + + _write_openlineage_yml(tmp_path) + monkeypatch.chdir(tmp_path) + + config = OpenLineageConfig(enabled=True, transport_type="console") + client = FeastOpenLineageClient(config=config) + + assert client.is_enabled + assert isinstance(client._client.transport, ConsoleTransport) + assert not isinstance(client._client.transport, TransformTransport) diff --git a/sdk/python/tests/unit/test_precomputed_feature_vectors.py b/sdk/python/tests/unit/test_precomputed_feature_vectors.py new file mode 100644 index 00000000000..80b0b83f53f --- /dev/null +++ b/sdk/python/tests/unit/test_precomputed_feature_vectors.py @@ -0,0 +1,933 @@ +"""Tests for pre-computed feature vectors (issue #6185).""" + +from datetime import datetime, timedelta, timezone +from unittest.mock import MagicMock + +import pytest +from google.protobuf.timestamp_pb2 import Timestamp + +from feast.feature_service import FeatureService +from feast.feature_view import FeatureView +from feast.field import Field +from feast.infra.offline_stores.file_source import FileSource +from feast.on_demand_feature_view import OnDemandFeatureView +from feast.protos.feast.core.PrecomputedFeatureVector_pb2 import ( + FeatureViewTimestamp, + PrecomputedFeatureVector, +) +from feast.protos.feast.serving.ServingService_pb2 import ( + FieldStatus, + GetOnlineFeaturesResponse, +) +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.types import Float32, Int64 + + +def _make_file_source(name="src"): + return FileSource(name=name, path="test.parquet") + + +def _make_fv(name, features, source=None, ttl=None): + return FeatureView( + name=name, + entities=[], + schema=features, + source=source or _make_file_source(f"{name}_src"), + ttl=ttl or timedelta(0), + ) + + +def _make_timestamp(dt=None): + ts = Timestamp() + ts.FromDatetime(dt or datetime.now(tz=timezone.utc)) + return ts + + +def _make_vector(feature_names, values, fv_timestamps=None, precomputed_at=None): + return PrecomputedFeatureVector( + feature_names=feature_names, + values=values, + fv_timestamps=fv_timestamps or [], + precomputed_at=precomputed_at or _make_timestamp(), + ) + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Proto round-trip +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestPrecomputedFeatureVectorProto: + def test_serialize_deserialize(self): + now = _make_timestamp() + fv_ts = FeatureViewTimestamp(feature_view_name="driver_fv", event_timestamp=now) + vector = _make_vector( + feature_names=["driver_fv__trips", "driver_fv__rating"], + values=[ValueProto(int64_val=100), ValueProto(float_val=4.5)], + fv_timestamps=[fv_ts], + precomputed_at=now, + ) + + blob = vector.SerializeToString() + parsed = PrecomputedFeatureVector() + parsed.ParseFromString(blob) + + assert list(parsed.feature_names) == ["driver_fv__trips", "driver_fv__rating"] + assert parsed.values[0].int64_val == 100 + assert parsed.values[1].float_val == pytest.approx(4.5) + assert parsed.fv_timestamps[0].feature_view_name == "driver_fv" + + def test_empty_vector(self): + vector = PrecomputedFeatureVector() + blob = vector.SerializeToString() + parsed = PrecomputedFeatureVector() + parsed.ParseFromString(blob) + assert list(parsed.feature_names) == [] + assert list(parsed.values) == [] + + def test_multiple_fv_timestamps(self): + ts1 = _make_timestamp(datetime(2025, 1, 1, tzinfo=timezone.utc)) + ts2 = _make_timestamp(datetime(2025, 6, 1, tzinfo=timezone.utc)) + + vector = _make_vector( + feature_names=["fv1__a", "fv2__b"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + fv_timestamps=[ + FeatureViewTimestamp(feature_view_name="fv1", event_timestamp=ts1), + FeatureViewTimestamp(feature_view_name="fv2", event_timestamp=ts2), + ], + ) + blob = vector.SerializeToString() + parsed = PrecomputedFeatureVector() + parsed.ParseFromString(blob) + + assert len(parsed.fv_timestamps) == 2 + assert parsed.fv_timestamps[0].feature_view_name == "fv1" + assert parsed.fv_timestamps[1].feature_view_name == "fv2" + assert parsed.fv_timestamps[0].event_timestamp.seconds == ts1.seconds + assert parsed.fv_timestamps[1].event_timestamp.seconds == ts2.seconds + + def test_null_values_preserved(self): + vector = _make_vector( + feature_names=["fv1__a", "fv1__b"], + values=[ValueProto(float_val=1.0), ValueProto()], + ) + blob = vector.SerializeToString() + parsed = PrecomputedFeatureVector() + parsed.ParseFromString(blob) + + assert parsed.values[0].float_val == pytest.approx(1.0) + assert not parsed.values[1].HasField("val") + + def test_large_vector(self): + n = 100 + names = [f"fv__feat_{i}" for i in range(n)] + vals = [ValueProto(float_val=float(i)) for i in range(n)] + vector = _make_vector(feature_names=names, values=vals) + blob = vector.SerializeToString() + parsed = PrecomputedFeatureVector() + parsed.ParseFromString(blob) + + assert len(parsed.feature_names) == n + assert len(parsed.values) == n + assert parsed.values[99].float_val == pytest.approx(99.0) + + +# ═══════════════════════════════════════════════════════════════════════════════ +# FeatureService precompute_online flag +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestFeatureServicePrecomputeOnline: + def test_default_is_false(self): + fs = FeatureService(name="svc", features=[]) + assert fs.precompute_online is False + + def test_set_true(self): + fs = FeatureService(name="svc", features=[], precompute_online=True) + assert fs.precompute_online is True + + def test_to_proto_roundtrip_true(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + fs = FeatureService(name="svc", features=[fv], precompute_online=True) + proto = fs.to_proto() + assert proto.spec.precompute_online is True + restored = FeatureService.from_proto(proto) + assert restored.precompute_online is True + + def test_to_proto_roundtrip_false(self): + fs = FeatureService(name="svc", features=[], precompute_online=False) + proto = fs.to_proto() + assert proto.spec.precompute_online is False + restored = FeatureService.from_proto(proto) + assert restored.precompute_online is False + + def test_equality_includes_precompute(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + fs1 = FeatureService(name="svc", features=[fv], precompute_online=True) + fs2 = FeatureService(name="svc", features=[fv], precompute_online=False) + assert fs1 != fs2 + + def test_equality_same_precompute(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + fs1 = FeatureService(name="svc", features=[fv], precompute_online=True) + fs2 = FeatureService(name="svc", features=[fv], precompute_online=True) + assert fs1 == fs2 + + def test_proto_preserves_other_fields(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + fs = FeatureService( + name="svc", + features=[fv], + precompute_online=True, + description="test desc", + owner="owner@test.com", + tags={"env": "prod"}, + ) + proto = fs.to_proto() + restored = FeatureService.from_proto(proto) + + assert restored.precompute_online is True + assert restored.description == "test desc" + assert restored.owner == "owner@test.com" + assert restored.tags == {"env": "prod"} + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Validation +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestFeatureServiceValidation: + def test_validate_passes_without_precompute(self): + fs = FeatureService(name="svc", features=[], precompute_online=False) + fs.validate() + + def test_validate_passes_precompute_regular_fv(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + fs = FeatureService(name="svc", features=[fv], precompute_online=True) + fs.validate() + + def test_validate_rejects_odfv_without_write_to_online(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + + odfv = MagicMock(spec=OnDemandFeatureView) + odfv.name = "odfv1" + odfv.write_to_online_store = False + + fs = FeatureService(name="svc", features=[fv], precompute_online=True) + fs._features = [fv, odfv] + + with pytest.raises(ValueError, match="write_to_online_store=False"): + fs.validate() + + def test_validate_passes_odfv_with_write_to_online(self): + fv = _make_fv("fv1", [Field(name="f1", dtype=Float32)]) + + odfv = MagicMock(spec=OnDemandFeatureView) + odfv.name = "odfv1" + odfv.write_to_online_store = True + + fs = FeatureService(name="svc", features=[fv], precompute_online=True) + fs._features = [fv, odfv] + + fs.validate() + + def test_validate_rejects_multiple_odfvs_without_write(self): + odfv1 = MagicMock(spec=OnDemandFeatureView) + odfv1.name = "odfv1" + odfv1.write_to_online_store = False + + odfv2 = MagicMock(spec=OnDemandFeatureView) + odfv2.name = "odfv2" + odfv2.write_to_online_store = False + + fs = FeatureService(name="svc", features=[], precompute_online=True) + fs._features = [odfv1, odfv2] + + with pytest.raises(ValueError, match="odfv1"): + fs.validate() + + def test_validate_error_message_includes_service_and_odfv_name(self): + odfv = MagicMock(spec=OnDemandFeatureView) + odfv.name = "my_transform" + odfv.write_to_online_store = False + + fs = FeatureService(name="my_service", features=[], precompute_online=True) + fs._features = [odfv] + + with pytest.raises(ValueError) as exc_info: + fs.validate() + + assert "my_service" in str(exc_info.value) + assert "my_transform" in str(exc_info.value) + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Schema mismatch detection (fast path fallback) +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestSchemaMismatchFallback: + def _fast_path(self, blobs, expected_names, grouped_refs=None, num_rows=None): + from feast.infra.online_stores.online_store import OnlineStore + + response = GetOnlineFeaturesResponse(results=[]) + result = OnlineStore._try_precomputed_fast_path( + blobs=blobs, + expected_feature_names=expected_names, + online_features_response=response, + full_feature_names=True, + num_rows=num_rows or len(blobs), + grouped_refs=grouped_refs or [], + registry=MagicMock(), + project="test", + ) + return result, response + + def test_mismatch_returns_false(self): + vector = _make_vector( + feature_names=["fv1__f1", "fv1__f2"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + ) + ok, _ = self._fast_path([vector.SerializeToString()], ["fv1__f1", "fv1__f3"]) + assert ok is False + + def test_none_blob_returns_false(self): + ok, _ = self._fast_path([None], ["fv1__f1"]) + assert ok is False + + def test_matching_schema_returns_true(self): + vector = _make_vector( + feature_names=["fv1__f1"], + values=[ValueProto(float_val=42.0)], + ) + ok, response = self._fast_path([vector.SerializeToString()], ["fv1__f1"]) + assert ok is True + assert len(response.results) == 1 + assert response.results[0].values[0].float_val == pytest.approx(42.0) + + def test_extra_feature_in_expected_returns_false(self): + vector = _make_vector( + feature_names=["fv1__f1"], + values=[ValueProto(float_val=1.0)], + ) + ok, _ = self._fast_path([vector.SerializeToString()], ["fv1__f1", "fv1__f2"]) + assert ok is False + + def test_fewer_features_in_expected_returns_false(self): + vector = _make_vector( + feature_names=["fv1__f1", "fv1__f2"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + ) + ok, _ = self._fast_path([vector.SerializeToString()], ["fv1__f1"]) + assert ok is False + + def test_reordered_features_succeeds_with_correct_values(self): + vector = _make_vector( + feature_names=["fv1__f1", "fv1__f2"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + ) + ok, response = self._fast_path( + [vector.SerializeToString()], ["fv1__f2", "fv1__f1"] + ) + assert ok is True + assert response.results[0].values[0].float_val == pytest.approx(2.0) + assert response.results[1].values[0].float_val == pytest.approx(1.0) + + def test_all_none_blobs_returns_false(self): + ok, _ = self._fast_path([None, None, None], ["fv1__f1"], num_rows=3) + assert ok is False + + def test_mixed_none_and_valid_returns_false(self): + vector = _make_vector( + feature_names=["fv1__f1"], + values=[ValueProto(float_val=1.0)], + ) + ok, _ = self._fast_path( + [vector.SerializeToString(), None], ["fv1__f1"], num_rows=2 + ) + assert ok is False + + def test_schema_mismatch_in_second_entity_returns_false(self): + vec1 = _make_vector( + feature_names=["fv1__f1"], values=[ValueProto(float_val=1.0)] + ) + vec2 = _make_vector( + feature_names=["fv1__f_WRONG"], values=[ValueProto(float_val=2.0)] + ) + ok, _ = self._fast_path( + [vec1.SerializeToString(), vec2.SerializeToString()], + ["fv1__f1"], + num_rows=2, + ) + assert ok is False + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Fast path: multi-entity response building +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestFastPathMultiEntity: + def _fast_path(self, blobs, expected_names, grouped_refs=None, num_rows=None): + from feast.infra.online_stores.online_store import OnlineStore + + response = GetOnlineFeaturesResponse(results=[]) + result = OnlineStore._try_precomputed_fast_path( + blobs=blobs, + expected_feature_names=expected_names, + online_features_response=response, + full_feature_names=True, + num_rows=num_rows or len(blobs), + grouped_refs=grouped_refs or [], + registry=MagicMock(), + project="test", + ) + return result, response + + def test_multiple_entities_all_present(self): + vec1 = _make_vector( + feature_names=["fv1__a", "fv1__b"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=10.0)], + ) + vec2 = _make_vector( + feature_names=["fv1__a", "fv1__b"], + values=[ValueProto(float_val=2.0), ValueProto(float_val=20.0)], + ) + vec3 = _make_vector( + feature_names=["fv1__a", "fv1__b"], + values=[ValueProto(float_val=3.0), ValueProto(float_val=30.0)], + ) + + ok, response = self._fast_path( + [ + vec1.SerializeToString(), + vec2.SerializeToString(), + vec3.SerializeToString(), + ], + ["fv1__a", "fv1__b"], + num_rows=3, + ) + assert ok is True + assert len(response.results) == 2 + + a_values = [v.float_val for v in response.results[0].values] + b_values = [v.float_val for v in response.results[1].values] + + assert a_values == pytest.approx([1.0, 2.0, 3.0]) + assert b_values == pytest.approx([10.0, 20.0, 30.0]) + + def test_statuses_are_present(self): + vec = _make_vector( + feature_names=["fv1__a"], + values=[ValueProto(float_val=1.0)], + ) + ok, response = self._fast_path( + [vec.SerializeToString()], ["fv1__a"], num_rows=1 + ) + assert ok is True + assert response.results[0].statuses[0] == FieldStatus.PRESENT + + def test_feature_names_in_metadata(self): + vec = _make_vector( + feature_names=["fv1__x", "fv2__y"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + ) + ok, response = self._fast_path([vec.SerializeToString()], ["fv1__x", "fv2__y"]) + assert ok is True + assert list(response.metadata.feature_names.val) == ["fv1__x", "fv2__y"] + + +# ═══════════════════════════════════════════════════════════════════════════════ +# TTL enforcement in fast path +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestFastPathTTLEnforcement: + def _fast_path_with_ttl(self, fv_event_dt, fv_ttl_seconds, fv_name="fv1"): + from feast.infra.online_stores.online_store import OnlineStore + + event_ts = _make_timestamp(fv_event_dt) + fv_ts = FeatureViewTimestamp( + feature_view_name=fv_name, event_timestamp=event_ts + ) + vector = _make_vector( + feature_names=[f"{fv_name}__f1"], + values=[ValueProto(float_val=1.0)], + fv_timestamps=[fv_ts], + ) + + fv = _make_fv( + fv_name, + [Field(name="f1", dtype=Float32)], + ttl=timedelta(seconds=fv_ttl_seconds), + ) + grouped_refs = [(fv, ["f1"])] + + response = GetOnlineFeaturesResponse(results=[]) + ok = OnlineStore._try_precomputed_fast_path( + blobs=[vector.SerializeToString()], + expected_feature_names=[f"{fv_name}__f1"], + online_features_response=response, + full_feature_names=True, + num_rows=1, + grouped_refs=grouped_refs, + registry=MagicMock(), + project="test", + ) + return ok, response + + def test_fresh_data_is_present(self): + now = datetime.now(tz=timezone.utc) + ok, response = self._fast_path_with_ttl(now, fv_ttl_seconds=3600) + assert ok is True + assert response.results[0].statuses[0] == FieldStatus.PRESENT + + def test_expired_data_is_outside_max_age(self): + old = datetime.now(tz=timezone.utc) - timedelta(hours=2) + ok, response = self._fast_path_with_ttl(old, fv_ttl_seconds=3600) + assert ok is True + assert response.results[0].statuses[0] == FieldStatus.OUTSIDE_MAX_AGE + + def test_zero_ttl_means_no_expiry(self): + old = datetime.now(tz=timezone.utc) - timedelta(days=365) + fv = _make_fv( + "fv1", + [Field(name="f1", dtype=Float32)], + ttl=timedelta(0), + ) + + event_ts = _make_timestamp(old) + fv_ts = FeatureViewTimestamp(feature_view_name="fv1", event_timestamp=event_ts) + vector = _make_vector( + feature_names=["fv1__f1"], + values=[ValueProto(float_val=1.0)], + fv_timestamps=[fv_ts], + ) + + from feast.infra.online_stores.online_store import OnlineStore + + response = GetOnlineFeaturesResponse(results=[]) + ok = OnlineStore._try_precomputed_fast_path( + blobs=[vector.SerializeToString()], + expected_feature_names=["fv1__f1"], + online_features_response=response, + full_feature_names=True, + num_rows=1, + grouped_refs=[(fv, ["f1"])], + registry=MagicMock(), + project="test", + ) + assert ok is True + assert response.results[0].statuses[0] == FieldStatus.PRESENT + + def test_mixed_ttl_some_expired_some_fresh(self): + from feast.infra.online_stores.online_store import OnlineStore + + now = datetime.now(tz=timezone.utc) + fresh_ts = _make_timestamp(now) + stale_ts = _make_timestamp(now - timedelta(hours=5)) + + vector = _make_vector( + feature_names=["fv1__f1", "fv2__f2"], + values=[ValueProto(float_val=1.0), ValueProto(float_val=2.0)], + fv_timestamps=[ + FeatureViewTimestamp(feature_view_name="fv1", event_timestamp=fresh_ts), + FeatureViewTimestamp(feature_view_name="fv2", event_timestamp=stale_ts), + ], + ) + + fv1 = _make_fv("fv1", [Field(name="f1", dtype=Float32)], ttl=timedelta(hours=1)) + fv2 = _make_fv("fv2", [Field(name="f2", dtype=Float32)], ttl=timedelta(hours=1)) + + response = GetOnlineFeaturesResponse(results=[]) + ok = OnlineStore._try_precomputed_fast_path( + blobs=[vector.SerializeToString()], + expected_feature_names=["fv1__f1", "fv2__f2"], + online_features_response=response, + full_feature_names=True, + num_rows=1, + grouped_refs=[(fv1, ["f1"]), (fv2, ["f2"])], + registry=MagicMock(), + project="test", + ) + assert ok is True + assert response.results[0].statuses[0] == FieldStatus.PRESENT + assert response.results[1].statuses[0] == FieldStatus.OUTSIDE_MAX_AGE + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Expected feature names computation +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestComputeExpectedFeatureNames: + def _compute(self, grouped_refs, full_feature_names): + from feast.infra.online_stores.online_store import OnlineStore + + return OnlineStore._compute_expected_feature_names( + grouped_refs, full_feature_names + ) + + def test_full_feature_names(self): + fv = _make_fv("driver_fv", [Field(name="trips", dtype=Int64)]) + assert self._compute([(fv, ["trips"])], True) == ["driver_fv__trips"] + + def test_short_feature_names(self): + fv = _make_fv("driver_fv", [Field(name="trips", dtype=Int64)]) + assert self._compute([(fv, ["trips"])], False) == ["trips"] + + def test_skips_ts_keys(self): + fv = _make_fv("driver_fv", [Field(name="trips", dtype=Int64)]) + result = self._compute([(fv, ["trips", "_ts:driver_fv"])], True) + assert result == ["driver_fv__trips"] + + def test_multiple_fvs(self): + fv1 = _make_fv("fv1", [Field(name="a", dtype=Float32)]) + fv2 = _make_fv("fv2", [Field(name="b", dtype=Float32)]) + result = self._compute([(fv1, ["a"]), (fv2, ["b"])], True) + assert result == ["fv1__a", "fv2__b"] + + def test_multiple_features_per_fv(self): + fv = _make_fv( + "fv1", + [ + Field(name="a", dtype=Float32), + Field(name="b", dtype=Float32), + Field(name="c", dtype=Float32), + ], + ) + result = self._compute([(fv, ["a", "b", "c"])], True) + assert result == ["fv1__a", "fv1__b", "fv1__c"] + + def test_empty_grouped_refs(self): + assert self._compute([], True) == [] + + def test_only_ts_keys(self): + fv = _make_fv("fv1", [Field(name="a", dtype=Float32)]) + result = self._compute([(fv, ["_ts:fv1"])], True) + assert result == [] + + +# ═══════════════════════════════════════════════════════════════════════════════ +# OnlineStore base class default implementations +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestOnlineStoreBaseDefaults: + def _make_dummy_store(self, online_read_fn=None, online_write_batch_fn=None): + from feast.infra.online_stores.online_store import OnlineStore + + class DummyStore(OnlineStore): + def __init__(self): + self.written = [] + + def online_write_batch(self, config, table, data, progress): + self.written.append((table.name, data)) + if online_write_batch_fn: + online_write_batch_fn(config, table, data, progress) + + def online_read(self, config, table, entity_keys, requested_features=None): + if online_read_fn: + return online_read_fn( + config, table, entity_keys, requested_features + ) + raise RuntimeError("not implemented") + + def update(self, *args, **kwargs): + pass + + def teardown(self, *args, **kwargs): + pass + + return DummyStore() + + def test_read_precomputed_returns_none_on_exception(self): + store = self._make_dummy_store() + config = MagicMock() + entity_keys = [MagicMock(), MagicMock()] + + result = store.read_precomputed_vectors( + config, "my_service", "project", entity_keys + ) + assert result == [None, None] + + def test_read_precomputed_returns_none_for_missing_entities(self): + def online_read_fn(config, table, entity_keys, requested_features): + return [(None, None) for _ in entity_keys] + + store = self._make_dummy_store(online_read_fn=online_read_fn) + result = store.read_precomputed_vectors( + MagicMock(), "svc", "proj", [MagicMock()] + ) + assert result == [None] + + def test_read_precomputed_returns_bytes_for_present_entities(self): + test_bytes = b"test_vector_data" + + def online_read_fn(config, table, entity_keys, requested_features): + return [ + ( + datetime.now(tz=timezone.utc), + {"vector": ValueProto(bytes_val=test_bytes)}, + ) + for _ in entity_keys + ] + + store = self._make_dummy_store(online_read_fn=online_read_fn) + result = store.read_precomputed_vectors( + MagicMock(), "svc", "proj", [MagicMock()] + ) + assert result == [test_bytes] + + def test_write_precomputed_delegates_to_online_write_batch(self): + store = self._make_dummy_store() + entity_key = MagicMock() + vector_bytes = b"blob_data" + + store.write_precomputed_vector( + MagicMock(), "my_svc", "proj", entity_key, vector_bytes + ) + assert len(store.written) == 1 + table_name, data = store.written[0] + assert table_name == "__precomputed__my_svc" + assert len(data) == 1 + assert data[0][1]["vector"].bytes_val == vector_bytes + + def test_write_then_read_roundtrip(self): + stored = {} + + def online_write_fn(config, table, data, progress): + for ek, vals, ts, _ in data: + stored[id(ek)] = (ts, vals) + + def online_read_fn(config, table, entity_keys, requested_features): + results = [] + for ek in entity_keys: + if id(ek) in stored: + ts, vals = stored[id(ek)] + results.append((ts, vals)) + else: + results.append((None, None)) + return results + + store = self._make_dummy_store( + online_read_fn=online_read_fn, + online_write_batch_fn=online_write_fn, + ) + + entity_key = MagicMock() + vector_bytes = b"test_roundtrip" + + store.write_precomputed_vector( + MagicMock(), "svc", "proj", entity_key, vector_bytes + ) + result = store.read_precomputed_vectors( + MagicMock(), "svc", "proj", [entity_key] + ) + assert result == [vector_bytes] + + def test_read_returns_none_for_non_bytes_val(self): + def online_read_fn(config, table, entity_keys, requested_features): + return [ + ( + datetime.now(tz=timezone.utc), + {"vector": ValueProto(string_val="not bytes")}, + ) + for _ in entity_keys + ] + + store = self._make_dummy_store(online_read_fn=online_read_fn) + result = store.read_precomputed_vectors( + MagicMock(), "svc", "proj", [MagicMock()] + ) + assert result == [None] + + def test_read_returns_none_when_no_vector_key(self): + def online_read_fn(config, table, entity_keys, requested_features): + return [ + ( + datetime.now(tz=timezone.utc), + {"other_field": ValueProto(float_val=1.0)}, + ) + for _ in entity_keys + ] + + store = self._make_dummy_store(online_read_fn=online_read_fn) + result = store.read_precomputed_vectors( + MagicMock(), "svc", "proj", [MagicMock()] + ) + assert result == [None] + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Materialization hook: _precompute_affected_services +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestPrecomputeAffectedServices: + def _make_mock_store(self, services): + store = MagicMock() + store.registry.list_feature_services.return_value = services + store.project = "test_project" + store._precompute_affected_services = lambda fv_names: type( + store + )._precompute_affected_services(store, fv_names) + + from feast.feature_store import FeatureStore + + store._precompute_affected_services = ( + FeatureStore._precompute_affected_services.__get__(store) + ) + return store + + def test_triggers_precompute_for_matching_service(self): + proj = MagicMock() + proj.name = "fv1" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "my_service" + + store = self._make_mock_store([svc]) + store._precompute_affected_services(["fv1"]) + store.precompute_feature_service.assert_called_once_with("my_service") + + def test_skips_non_precompute_services(self): + svc = MagicMock() + svc.precompute_online = False + svc.name = "svc" + + store = self._make_mock_store([svc]) + store._precompute_affected_services(["fv1"]) + store.precompute_feature_service.assert_not_called() + + def test_skips_when_no_fvs_match(self): + proj = MagicMock() + proj.name = "fv_other" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store._precompute_affected_services(["fv1"]) + store.precompute_feature_service.assert_not_called() + + def test_handles_registry_exception_gracefully(self): + store = MagicMock() + store.registry.list_feature_services.side_effect = RuntimeError("oops") + store.project = "test" + + from feast.feature_store import FeatureStore + + FeatureStore._precompute_affected_services(store, ["fv1"]) + + def test_handles_precompute_exception_gracefully(self): + proj = MagicMock() + proj.name = "fv1" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store.precompute_feature_service.side_effect = RuntimeError("fail") + + store._precompute_affected_services(["fv1"]) + + def test_multiple_services_all_triggered(self): + proj1 = MagicMock() + proj1.name = "fv1" + svc1 = MagicMock() + svc1.precompute_online = True + svc1.feature_view_projections = [proj1] + svc1.name = "svc1" + + proj2 = MagicMock() + proj2.name = "fv1" + svc2 = MagicMock() + svc2.precompute_online = True + svc2.feature_view_projections = [proj2] + svc2.name = "svc2" + + store = self._make_mock_store([svc1, svc2]) + store._precompute_affected_services(["fv1"]) + + assert store.precompute_feature_service.call_count == 2 + + +# ═══════════════════════════════════════════════════════════════════════════════ +# Push hook: _precompute_for_push +# ═══════════════════════════════════════════════════════════════════════════════ + + +class TestPrecomputeForPush: + def _make_mock_store(self, services): + store = MagicMock() + store.registry.list_feature_services.return_value = services + store.project = "test_project" + + from feast.feature_store import FeatureStore + + store._precompute_for_push = FeatureStore._precompute_for_push.__get__(store) + return store + + def test_triggers_for_matching_fv(self): + proj = MagicMock() + proj.name = "pushed_fv" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store._precompute_for_push("pushed_fv", MagicMock()) + store.precompute_feature_service.assert_called_once_with("svc") + + def test_skips_non_matching_fv(self): + proj = MagicMock() + proj.name = "other_fv" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store._precompute_for_push("pushed_fv", MagicMock()) + store.precompute_feature_service.assert_not_called() + + def test_skips_non_precompute_service(self): + proj = MagicMock() + proj.name = "pushed_fv" + svc = MagicMock() + svc.precompute_online = False + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store._precompute_for_push("pushed_fv", MagicMock()) + store.precompute_feature_service.assert_not_called() + + def test_handles_exception_gracefully(self): + proj = MagicMock() + proj.name = "fv" + svc = MagicMock() + svc.precompute_online = True + svc.feature_view_projections = [proj] + svc.name = "svc" + + store = self._make_mock_store([svc]) + store.precompute_feature_service.side_effect = RuntimeError("fail") + + store._precompute_for_push("fv", MagicMock()) + + def test_handles_registry_exception_gracefully(self): + store = MagicMock() + store.registry.list_feature_services.side_effect = RuntimeError("oops") + store.project = "test" + + from feast.feature_store import FeatureStore + + FeatureStore._precompute_for_push(store, "fv", MagicMock()) diff --git a/sdk/python/tests/unit/test_proto_json.py b/sdk/python/tests/unit/test_proto_json.py index b5e01744e44..6b3c7181ad7 100644 --- a/sdk/python/tests/unit/test_proto_json.py +++ b/sdk/python/tests/unit/test_proto_json.py @@ -103,6 +103,33 @@ def test_feature_list(proto_json_patch): ) +def test_nested_collection_json_roundtrip(proto_json_patch): + """Nested collection values (list of lists) should survive JSON roundtrip.""" + from feast.protos.feast.types.Value_pb2 import Value + + # Build a Value with list_val containing [[1,2],[3,4,5]] + value_proto = Value() + inner1 = value_proto.list_val.val.add() + inner1.int64_list_val.val.extend([1, 2]) + inner2 = value_proto.list_val.val.add() + inner2.int64_list_val.val.extend([3, 4, 5]) + + # Serialize to JSON + value_json = MessageToDict(value_proto) + assert isinstance(value_json, list) + assert len(value_json) == 2 + assert value_json[0] == [1, 2] + assert value_json[1] == [3, 4, 5] + + # Deserialize back from JSON + feature_vector_str = '{"values": [[[1, 2], [3, 4, 5]]]}' + feature_vector_proto = FeatureVector() + Parse(feature_vector_str, feature_vector_proto) + assert len(feature_vector_proto.values) == 1 + assert feature_vector_proto.values[0].WhichOneof("val") == "list_val" + assert len(feature_vector_proto.values[0].list_val.val) == 2 + + @pytest.fixture(scope="module") def proto_json_patch(): proto_json.patch() diff --git a/sdk/python/tests/unit/test_registry_string_config.py b/sdk/python/tests/unit/test_registry_string_config.py new file mode 100644 index 00000000000..ca337454e52 --- /dev/null +++ b/sdk/python/tests/unit/test_registry_string_config.py @@ -0,0 +1,137 @@ +"""Tests for string-based registry configuration in RepoConfig. + +Verifies that passing registry as a string (e.g. "gs://bucket/registry.pb") +correctly allows auto-detection of the registry store class from the URI +scheme, rather than hardcoding FileRegistryStore. + +Regression test for: RepoConfig.registry property hardcodes +get_registry_config_from_type("file") when registry_config is a string, +ignoring URI scheme and breaking gs:// and s3:// paths. +""" + +from pathlib import Path + +import pytest + +from feast.infra.registry.registry import ( + REGISTRY_STORE_CLASS_FOR_SCHEME, + get_registry_store_class_from_scheme, +) +from feast.repo_config import RegistryConfig, RepoConfig + + +def _make_repo_config(registry): + """Helper to create a minimal RepoConfig with the given registry value.""" + return RepoConfig( + project="test", + provider="gcp", + registry=registry, + online_store={"type": "redis", "connection_string": "localhost:6379"}, + entity_key_serialization_version=3, + ) + + +class TestStringRegistryAutoDetection: + """When registry is passed as a string, RepoConfig must produce a + RegistryConfig that allows Registry.__init__ to auto-detect the correct + store class from the URI scheme.""" + + def test_gcs_string_registry_produces_correct_config(self): + """gs:// string -> RegistryConfig with registry_store_type=None + so Registry.__init__ auto-detects GCSRegistryStore.""" + config = _make_repo_config("gs://my-bucket/feast/registry.pb") + reg = config.registry + + assert isinstance(reg, RegistryConfig) + assert reg.path == "gs://my-bucket/feast/registry.pb" + assert reg.registry_store_type is None + + def test_s3_string_registry_produces_correct_config(self): + """s3:// string -> RegistryConfig with registry_store_type=None + so Registry.__init__ auto-detects S3RegistryStore.""" + config = _make_repo_config("s3://my-bucket/feast/registry.pb") + reg = config.registry + + assert isinstance(reg, RegistryConfig) + assert reg.path == "s3://my-bucket/feast/registry.pb" + assert reg.registry_store_type is None + + def test_local_string_registry_still_works(self): + """A local file path string must still produce a valid RegistryConfig + (no regression for the common case).""" + config = _make_repo_config("/tmp/feast/registry.db") + reg = config.registry + + assert isinstance(reg, RegistryConfig) + assert reg.path == "/tmp/feast/registry.db" + # registry_type defaults to "file", which is correct for local paths + assert reg.registry_type == "file" + + def test_dict_registry_still_works(self): + """Dict-based registry config must continue to work as before.""" + config = _make_repo_config({"path": "gs://my-bucket/feast/registry.pb"}) + reg = config.registry + + assert isinstance(reg, RegistryConfig) + assert reg.path == "gs://my-bucket/feast/registry.pb" + assert reg.registry_store_type is None + + def test_dict_registry_with_explicit_registry_type(self): + """Dict with explicit registry_type must route through + get_registry_config_from_type (no change in behavior).""" + config = _make_repo_config( + {"registry_type": "file", "path": "/tmp/registry.db"} + ) + reg = config.registry + + assert isinstance(reg, RegistryConfig) + assert reg.path == "/tmp/registry.db" + assert reg.registry_type == "file" + + +class TestRegistryStoreSchemeDetection: + """Verify that REGISTRY_STORE_CLASS_FOR_SCHEME and + get_registry_store_class_from_scheme correctly map URI schemes + to their store classes.""" + + def test_gcs_scheme_selects_gcs_registry_store(self): + assert "gs" in REGISTRY_STORE_CLASS_FOR_SCHEME + cls = get_registry_store_class_from_scheme("gs://bucket/registry.pb") + assert cls.__name__ == "GCSRegistryStore" + + def test_s3_scheme_selects_s3_registry_store(self): + assert "s3" in REGISTRY_STORE_CLASS_FOR_SCHEME + cls = get_registry_store_class_from_scheme("s3://bucket/registry.pb") + assert cls.__name__ == "S3RegistryStore" + + def test_file_scheme_selects_file_registry_store(self): + assert "file" in REGISTRY_STORE_CLASS_FOR_SCHEME + cls = get_registry_store_class_from_scheme("file:///tmp/registry.db") + assert cls.__name__ == "FileRegistryStore" + + def test_unknown_scheme_raises(self): + with pytest.raises(Exception, match="unsupported scheme"): + get_registry_store_class_from_scheme("ftp://host/registry.pb") + + +class TestFileRegistryStorePathHandling: + """Demonstrate that FileRegistryStore cannot handle cloud URIs — + this is the root cause of the IsADirectoryError in production when + the bug is present.""" + + def test_pathlib_does_not_treat_gcs_as_absolute(self): + """pathlib.Path('gs://...') is NOT absolute, so FileRegistryStore + joins it with repo_path producing nonsense like /app/gs://...""" + gcs_path = Path("gs://my-bucket/feast/registry.pb") + assert not gcs_path.is_absolute() + + joined = Path("/app").joinpath(gcs_path) + assert str(joined).startswith("/app/gs:") + + def test_pathlib_does_not_treat_s3_as_absolute(self): + """Same issue for s3:// paths.""" + s3_path = Path("s3://my-bucket/feast/registry.pb") + assert not s3_path.is_absolute() + + joined = Path("/app").joinpath(s3_path) + assert str(joined).startswith("/app/s3:") diff --git a/sdk/python/tests/unit/test_stream_feature_view.py b/sdk/python/tests/unit/test_stream_feature_view.py index 96e62d9d9e2..e0670b084bd 100644 --- a/sdk/python/tests/unit/test_stream_feature_view.py +++ b/sdk/python/tests/unit/test_stream_feature_view.py @@ -303,3 +303,36 @@ def test_update_materialization_intervals(): updated_stream_feature_view.materialization_intervals[0][1] == stored_stream_feature_view.materialization_intervals[0][1] ) + + +def test_stream_feature_view_org_field(): + """Test that the optional `org` field is stored, serialized, and round-trips correctly.""" + stream_source = KafkaSource( + name="kafka", + timestamp_field="event_timestamp", + kafka_bootstrap_servers="", + message_format=AvroFormat(""), + topic="topic", + batch_source=FileSource(path="some path"), + ) + common = dict( + entities=[], + ttl=timedelta(days=30), + schema=[Field(name="dummy_field", dtype=Float32)], + source=stream_source, + ) + + sfv_no_org = StreamFeatureView(name="sfv-no-org", **common) + assert sfv_no_org.org == "" + + sfv_with_org = StreamFeatureView(name="sfv-with-org", org="ads", **common) + assert sfv_with_org.org == "ads" + + proto = sfv_with_org.to_proto() + assert proto.spec.org == "ads" + + roundtripped = StreamFeatureView.from_proto(proto) + assert roundtripped.org == "ads" + + sfv_other_org = StreamFeatureView(name="sfv-with-org", org="search", **common) + assert sfv_with_org != sfv_other_org diff --git a/sdk/python/tests/unit/test_type_map.py b/sdk/python/tests/unit/test_type_map.py index 8125ab61b90..412b63298a5 100644 --- a/sdk/python/tests/unit/test_type_map.py +++ b/sdk/python/tests/unit/test_type_map.py @@ -1,9 +1,12 @@ +import uuid + import numpy as np import pandas as pd import pyarrow import pytest from feast.protos.feast.types.Value_pb2 import Map, MapList +from feast.protos.feast.types.Value_pb2 import Value as ProtoValue from feast.type_map import ( _convert_value_type_str_to_value_type, _python_dict_to_map_proto, @@ -84,6 +87,9 @@ def test_python_values_to_proto_values_bool(values): (np.array([None]), ValueType.BYTES_LIST, None), (np.array([None]), ValueType.STRING_LIST, None), (np.array([None]), ValueType.UNIX_TIMESTAMP_LIST, None), + ([np.array([], dtype=np.int32)], ValueType.INT32_LIST, []), + ([np.array([], dtype=np.float32)], ValueType.FLOAT_LIST, []), + ([np.array([], dtype=np.bool_)], ValueType.BOOL_LIST, []), ([b"[1,2,3]"], ValueType.INT64_LIST, [1, 2, 3]), ([b"[1,2,3]"], ValueType.INT32_LIST, [1, 2, 3]), ([b"[1.5,2.5,3.5]"], ValueType.FLOAT_LIST, [1.5, 2.5, 3.5]), @@ -1415,3 +1421,897 @@ def test_array_element_incompatibility(self): assert not _spark_types_compatible( ArrayType(StringType()), ArrayType(IntegerType()) ) + + +class TestUuidTypes: + """Test cases for UUID and TIME_UUID value types.""" + + def test_uuid_string_roundtrip(self): + """UUID string -> proto -> uuid.UUID object roundtrip.""" + test_uuid = uuid.uuid4() + protos = python_values_to_proto_values([str(test_uuid)], ValueType.UUID) + assert protos[0].uuid_val == str(test_uuid) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, uuid.UUID) + assert result == test_uuid + + def test_uuid_object_serialization(self): + """uuid.UUID object -> proto serialization (str conversion automatic).""" + test_uuid = uuid.uuid4() + protos = python_values_to_proto_values([test_uuid], ValueType.UUID) + assert protos[0].uuid_val == str(test_uuid) + + def test_time_uuid_roundtrip(self): + """TIME_UUID string -> proto -> uuid.UUID object roundtrip.""" + test_uuid = uuid.uuid1() + protos = python_values_to_proto_values([str(test_uuid)], ValueType.TIME_UUID) + assert protos[0].time_uuid_val == str(test_uuid) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, uuid.UUID) + assert result == test_uuid + + def test_uuid_without_feature_type_returns_uuid(self): + """With dedicated uuid_val proto field, UUID is identified without feature_type hint.""" + test_uuid = uuid.uuid4() + protos = python_values_to_proto_values([str(test_uuid)], ValueType.UUID) + + # No feature_type hint needed — uuid_val field identifies the type + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, uuid.UUID) + assert result == test_uuid + + def test_uuid_backward_compat_string_val(self): + """UUIDs stored as string_val (old format) still work with feature_type hint.""" + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + test_uuid = uuid.uuid4() + # Simulate old-format proto with string_val + proto = ProtoValue(string_val=str(test_uuid)) + + # Without feature_type, returns plain string + result = feast_value_type_to_python_type(proto) + assert isinstance(result, str) + + # With feature_type hint, returns uuid.UUID + result = feast_value_type_to_python_type(proto, ValueType.UUID) + assert isinstance(result, uuid.UUID) + assert result == test_uuid + + def test_uuid_list_roundtrip(self): + """UUID list -> proto -> list of uuid.UUID objects roundtrip.""" + test_uuids = [uuid.uuid4(), uuid.uuid4()] + test_uuid_strs = [str(u) for u in test_uuids] + protos = python_values_to_proto_values([test_uuid_strs], ValueType.UUID_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_uuid_object_list_roundtrip(self): + """uuid.UUID objects in list -> proto -> list of uuid.UUID roundtrip.""" + test_uuids = [uuid.uuid4(), uuid.uuid4(), uuid.uuid4()] + protos = python_values_to_proto_values([test_uuids], ValueType.UUID_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_time_uuid_object_list_roundtrip(self): + """uuid.UUID objects in TIME_UUID list -> proto -> roundtrip.""" + test_uuids = [uuid.uuid1(), uuid.uuid1()] + protos = python_values_to_proto_values([test_uuids], ValueType.TIME_UUID_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_uuid_set_roundtrip(self): + """UUID set -> proto -> set of uuid.UUID objects roundtrip.""" + test_uuids = {uuid.uuid4(), uuid.uuid4(), uuid.uuid4()} + protos = python_values_to_proto_values([test_uuids], ValueType.UUID_SET) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, set) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_time_uuid_set_roundtrip(self): + """TIME_UUID set -> proto -> set of uuid.UUID objects roundtrip.""" + test_uuids = {uuid.uuid1(), uuid.uuid1()} + protos = python_values_to_proto_values([test_uuids], ValueType.TIME_UUID_SET) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, set) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_uuid_object_set_roundtrip(self): + """uuid.UUID objects in set -> proto -> set of uuid.UUID roundtrip.""" + test_uuids = {uuid.uuid4(), uuid.uuid4()} + protos = python_values_to_proto_values([test_uuids], ValueType.UUID_SET) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, set) + assert result == test_uuids + + def test_uuid_set_backward_compat_string_set_val(self): + """UUIDs stored as string_set_val (old format) still work with feature_type hint.""" + from feast.protos.feast.types.Value_pb2 import StringSet + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + test_uuids = {uuid.uuid4(), uuid.uuid4()} + # Simulate old-format proto with string_set_val + proto = ProtoValue(string_set_val=StringSet(val=[str(u) for u in test_uuids])) + + # Without feature_type, returns set of strings + result = feast_value_type_to_python_type(proto) + assert isinstance(result, set) + assert all(isinstance(r, str) for r in result) + + # With feature_type hint, returns set of uuid.UUID + result = feast_value_type_to_python_type(proto, ValueType.UUID_SET) + assert isinstance(result, set) + assert all(isinstance(r, uuid.UUID) for r in result) + assert result == test_uuids + + def test_pg_uuid_type_mapping(self): + """PostgreSQL uuid type maps to ValueType.UUID.""" + assert pg_type_to_feast_value_type("uuid") == ValueType.UUID + assert pg_type_to_feast_value_type("uuid[]") == ValueType.UUID_LIST + + +class TestDecimalTypes: + """Test cases for DECIMAL, DECIMAL_LIST, and DECIMAL_SET value types.""" + + def test_decimal_string_roundtrip(self): + """Decimal string -> proto -> decimal.Decimal object roundtrip.""" + import decimal + + val = decimal.Decimal("3.14159265358979323846") + protos = python_values_to_proto_values([str(val)], ValueType.DECIMAL) + assert protos[0].decimal_val == str(val) + + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, decimal.Decimal) + assert result == val + + def test_decimal_object_serialization(self): + """decimal.Decimal object -> proto serialization (str conversion automatic).""" + import decimal + + val = decimal.Decimal("99.99") + protos = python_values_to_proto_values([val], ValueType.DECIMAL) + assert protos[0].decimal_val == "99.99" + + def test_decimal_preserves_precision(self): + """High-precision decimal values survive the proto round-trip without loss.""" + import decimal + + high_prec = decimal.Decimal("1.23456789012345678901234567890") + protos = python_values_to_proto_values([high_prec], ValueType.DECIMAL) + result = feast_value_type_to_python_type(protos[0]) + assert result == high_prec + + def test_decimal_negative_value(self): + """Negative decimal values round-trip correctly.""" + import decimal + + val = decimal.Decimal("-9876.543210") + protos = python_values_to_proto_values([val], ValueType.DECIMAL) + result = feast_value_type_to_python_type(protos[0]) + assert result == val + + def test_decimal_zero(self): + """Zero decimal value round-trips correctly.""" + import decimal + + val = decimal.Decimal("0") + protos = python_values_to_proto_values([val], ValueType.DECIMAL) + result = feast_value_type_to_python_type(protos[0]) + assert result == val + + def test_decimal_list_roundtrip(self): + """DECIMAL_LIST string list -> proto -> list of decimal.Decimal roundtrip.""" + import decimal + + vals = [decimal.Decimal("1.1"), decimal.Decimal("2.2"), decimal.Decimal("3.3")] + val_strs = [str(v) for v in vals] + protos = python_values_to_proto_values([val_strs], ValueType.DECIMAL_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert all(isinstance(r, decimal.Decimal) for r in result) + assert result == vals + + def test_decimal_object_list_roundtrip(self): + """List of decimal.Decimal objects -> proto -> list of decimal.Decimal roundtrip.""" + import decimal + + vals = [ + decimal.Decimal("10.5"), + decimal.Decimal("20.75"), + decimal.Decimal("30.125"), + ] + protos = python_values_to_proto_values([vals], ValueType.DECIMAL_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert all(isinstance(r, decimal.Decimal) for r in result) + assert result == vals + + def test_decimal_set_roundtrip(self): + """DECIMAL_SET -> proto -> set of decimal.Decimal roundtrip.""" + import decimal + + vals = {decimal.Decimal("1.1"), decimal.Decimal("2.2"), decimal.Decimal("3.3")} + protos = python_values_to_proto_values([vals], ValueType.DECIMAL_SET) + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, set) + assert all(isinstance(r, decimal.Decimal) for r in result) + assert result == vals + + def test_decimal_set_deduplication(self): + """Duplicate decimal values in a set are deduplicated.""" + import decimal + + vals = {decimal.Decimal("5.0"), decimal.Decimal("5.0"), decimal.Decimal("6.0")} + protos = python_values_to_proto_values([vals], ValueType.DECIMAL_SET) + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, set) + assert len(result) == 2 + + def test_decimal_type_inference(self): + """python_type_to_feast_value_type infers DECIMAL from decimal.Decimal values.""" + import decimal + + from feast.type_map import python_type_to_feast_value_type + + assert ( + python_type_to_feast_value_type("price", decimal.Decimal("1.5")) + == ValueType.DECIMAL + ) + + def test_decimal_value_type_string_conversion(self): + """_convert_value_type_str_to_value_type handles DECIMAL strings.""" + from feast.type_map import _convert_value_type_str_to_value_type + + assert _convert_value_type_str_to_value_type("DECIMAL") == ValueType.DECIMAL + assert ( + _convert_value_type_str_to_value_type("DECIMAL_LIST") + == ValueType.DECIMAL_LIST + ) + assert ( + _convert_value_type_str_to_value_type("DECIMAL_SET") + == ValueType.DECIMAL_SET + ) + + def test_decimal_proto_field_name_mapping(self): + """PROTO_VALUE_TO_VALUE_TYPE_MAP and VALUE_TYPE_TO_PROTO_VALUE_MAP include DECIMAL.""" + from feast.type_map import ( + PROTO_VALUE_TO_VALUE_TYPE_MAP, + VALUE_TYPE_TO_PROTO_VALUE_MAP, + ) + + assert PROTO_VALUE_TO_VALUE_TYPE_MAP["decimal_val"] == ValueType.DECIMAL + assert ( + PROTO_VALUE_TO_VALUE_TYPE_MAP["decimal_list_val"] == ValueType.DECIMAL_LIST + ) + assert PROTO_VALUE_TO_VALUE_TYPE_MAP["decimal_set_val"] == ValueType.DECIMAL_SET + assert VALUE_TYPE_TO_PROTO_VALUE_MAP[ValueType.DECIMAL] == "decimal_val" + assert ( + VALUE_TYPE_TO_PROTO_VALUE_MAP[ValueType.DECIMAL_LIST] == "decimal_list_val" + ) + assert VALUE_TYPE_TO_PROTO_VALUE_MAP[ValueType.DECIMAL_SET] == "decimal_set_val" + + def test_decimal_pandas_type(self): + """feast_value_type_to_pandas_type returns 'object' for DECIMAL.""" + from feast.type_map import feast_value_type_to_pandas_type + + assert feast_value_type_to_pandas_type(ValueType.DECIMAL) == "object" + + def test_decimal_pyarrow_type(self): + """feast_value_type_to_pa returns pyarrow.string() for DECIMAL scalar/list/set.""" + import pyarrow + + from feast.type_map import feast_value_type_to_pa + + assert feast_value_type_to_pa(ValueType.DECIMAL) == pyarrow.string() + assert feast_value_type_to_pa(ValueType.DECIMAL_LIST) == pyarrow.list_( + pyarrow.string() + ) + assert feast_value_type_to_pa(ValueType.DECIMAL_SET) == pyarrow.list_( + pyarrow.string() + ) + + def test_decimal_snowflake_udf(self): + """_convert_value_name_to_snowflake_udf maps DECIMAL types to varchar UDFs.""" + from feast.type_map import _convert_value_name_to_snowflake_udf + + project = "myproject" + assert _convert_value_name_to_snowflake_udf("DECIMAL", project) == ( + f"FEAST_{project.upper()}_SNOWFLAKE_VARCHAR_TO_STRING_PROTO" + ) + assert _convert_value_name_to_snowflake_udf("DECIMAL_LIST", project) == ( + f"FEAST_{project.upper()}_SNOWFLAKE_ARRAY_VARCHAR_TO_LIST_STRING_PROTO" + ) + assert _convert_value_name_to_snowflake_udf("DECIMAL_SET", project) == ( + f"FEAST_{project.upper()}_SNOWFLAKE_ARRAY_VARCHAR_TO_LIST_STRING_PROTO" + ) + + +class TestNestedCollectionTypes: + """Tests for nested collection type proto conversion (VALUE_LIST, VALUE_SET).""" + + def test_value_list_proto_roundtrip(self): + """Test python_values_to_proto_values and feast_value_type_to_python_type for VALUE_LIST.""" + values = [[[1, 2, 3], [4, 5]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + assert len(protos) == 1 + assert protos[0].WhichOneof("val") == "list_val" + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, list) + assert len(result) == 2 + + def test_value_set_proto_roundtrip(self): + """Test VALUE_SET proto conversion.""" + values = [[["a", "b"], ["c"]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_SET) + assert len(protos) == 1 + assert protos[0].WhichOneof("val") == "set_val" + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, list) + assert len(result) == 2 + + def test_nested_collection_null_handling(self): + """Test that None values are handled correctly.""" + values = [None] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + assert len(protos) == 1 + assert protos[0].WhichOneof("val") is None + + def test_convert_value_type_str_nested(self): + """Test _convert_value_type_str_to_value_type for nested types.""" + assert ( + _convert_value_type_str_to_value_type("VALUE_LIST") == ValueType.VALUE_LIST + ) + assert _convert_value_type_str_to_value_type("VALUE_SET") == ValueType.VALUE_SET + + def test_nested_collection_empty_inner_list(self): + """Test that empty inner collections are handled gracefully.""" + values = [[[], [1, 2]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, list) + assert len(result) == 2 + # Empty inner list should round-trip as None (empty ProtoValue) + assert result[0] is None + assert result[1] == [1, 2] + + def test_nested_collection_inner_none(self): + """Test that None inner elements are handled.""" + values = [[[1, 2], None, [3]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert len(result) == 3 + assert result[0] == [1, 2] + assert result[1] is None + assert result[2] == [3] + + def test_value_list_no_dedup(self): + """Test that VALUE_LIST does NOT deduplicate (Array semantics).""" + values = [[[1, 1, 2], [3, 3]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert result[0] == [1, 1, 2] + assert result[1] == [3, 3] + + def test_value_list_proto_roundtrip_values(self): + """Test that VALUE_LIST roundtrip preserves actual inner values.""" + values = [[[1, 2, 3], [4, 5]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + result = feast_value_type_to_python_type(protos[0]) + assert result[0] == [1, 2, 3] + assert result[1] == [4, 5] + + def test_value_set_proto_roundtrip_values(self): + """Test that VALUE_SET roundtrip preserves actual inner values.""" + values = [[["a", "b"], ["c"]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_SET) + result = feast_value_type_to_python_type(protos[0]) + assert result[0] == ["a", "b"] + assert result[1] == ["c"] + + def test_multi_value_batch_nested(self): + """Test multiple nested collection values in a single batch.""" + values = [[[1, 2], [3]], [[4], [5, 6]]] + protos = python_values_to_proto_values(values, ValueType.VALUE_LIST) + assert len(protos) == 2 + r0 = feast_value_type_to_python_type(protos[0]) + r1 = feast_value_type_to_python_type(protos[1]) + assert r0 == [[1, 2], [3]] + assert r1 == [[4], [5, 6]] + + def test_feast_value_type_to_pa_nested(self): + """Test feast_value_type_to_pa for nested collection types.""" + for vt in ( + ValueType.VALUE_LIST, + ValueType.VALUE_SET, + ): + pa_type = feast_value_type_to_pa(vt) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.string())) + + def test_pa_to_feast_value_type_nested(self): + """Test pa_to_feast_value_type recognizes nested list PyArrow types.""" + assert ( + pa_to_feast_value_type("list>") + == ValueType.VALUE_LIST + ) + assert ( + pa_to_feast_value_type("list>") + == ValueType.VALUE_LIST + ) + assert ( + pa_to_feast_value_type("list>") + == ValueType.VALUE_LIST + ) + + +class TestEmptyArrayAsNull: + """Regression tests for https://github.com/feast-dev/feast/issues/6255 + Ensure that an empty numpy array in a scalar feature column is treated as + null rather than raising ``ValueError: The truth value of an empty array is + ambiguous``. + """ + + def test_empty_numpy_array_treated_as_null_double(self): + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + result = python_values_to_proto_values( + [np.array([]), 1.0, None], ValueType.DOUBLE + ) + assert result[0] == ProtoValue(), ( + "empty array should produce an empty ProtoValue" + ) + assert result[1].double_val == 1.0 + assert result[2] == ProtoValue(), ( + "None should still produce an empty ProtoValue" + ) + + def test_empty_numpy_array_treated_as_null_int64(self): + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + result = python_values_to_proto_values( + [np.array([]), 42, None], ValueType.INT64 + ) + assert result[0] == ProtoValue(), ( + "empty array should produce an empty ProtoValue" + ) + assert result[1].int64_val == 42 + assert result[2] == ProtoValue() + + def test_empty_numpy_array_treated_as_null_bool(self): + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + result = python_values_to_proto_values( + [np.array([]), True, None], ValueType.BOOL + ) + assert result[0] == ProtoValue(), ( + "empty array should produce an empty ProtoValue" + ) + assert result[1].bool_val is True + assert result[2] == ProtoValue() + + def test_array_with_null_element_treated_as_null(self): + """A non-empty array containing any null element in a scalar column is treated as null.""" + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + result = python_values_to_proto_values( + [np.array([np.nan, 1.0]), 3.0], ValueType.DOUBLE + ) + assert result[0] == ProtoValue(), ( + "array with null element should produce an empty ProtoValue" + ) + assert result[1].double_val == 3.0 + + def test_non_empty_array_without_nulls_is_treated_as_null(self): + """A non-empty numpy array in a scalar column is always treated as null. + + A scalar feature column cannot hold an ndarray value (protobuf would + reject it), so any array-like value – empty or not – is mapped to an + empty ProtoValue() rather than crashing with ValueError. + """ + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + result = python_values_to_proto_values( + [np.array([1.0, 2.0]), 3.0, None], ValueType.DOUBLE + ) + # array-like value in a scalar column → null, not a crash + assert result[0] == ProtoValue(), ( + "non-empty array in scalar column should be null" + ) + assert result[1].double_val == 3.0 + assert result[2] == ProtoValue() + + def test_empty_numpy_array_treated_as_null_unix_timestamp(self): + """Array-like values in a scalar UNIX_TIMESTAMP column must not crash.""" + from datetime import datetime, timezone + + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + ts = datetime(2024, 1, 1, tzinfo=timezone.utc) + result = python_values_to_proto_values( + [np.array([]), ts, None], ValueType.UNIX_TIMESTAMP + ) + assert result[0] == ProtoValue(), ( + "empty array in UNIX_TIMESTAMP scalar column should produce null" + ) + assert result[1].unix_timestamp_val == int(ts.timestamp()) + assert result[2] == ProtoValue() + + def test_non_empty_array_treated_as_null_unix_timestamp(self): + """Non-empty array in a UNIX_TIMESTAMP scalar column should produce null, not crash.""" + from datetime import datetime, timezone + + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + ts = datetime(2024, 6, 15, tzinfo=timezone.utc) + result = python_values_to_proto_values( + [np.array([1, 2, 3]), ts], ValueType.UNIX_TIMESTAMP + ) + assert result[0] == ProtoValue(), ( + "non-empty array in UNIX_TIMESTAMP scalar column should produce null" + ) + assert result[1].unix_timestamp_val == int(ts.timestamp()) + + +class TestValueMapTypes: + """Tests for SCALAR_MAP: maps with non-string keys encoded via ScalarMap proto.""" + + def test_int_key_roundtrip(self): + """Int keys are encoded as int64_key and round-trip back as int.""" + data = {1: "one", 2: "two", 3: "three"} + + protos = python_values_to_proto_values([data], ValueType.SCALAR_MAP) + assert protos[0].WhichOneof("val") == "scalar_map_val" + result = feast_value_type_to_python_type(protos[0]) + + assert result == {1: "one", 2: "two", 3: "three"} + + def test_long_key_roundtrip(self): + """Large int keys (simulating int64/Long) round-trip correctly.""" + data = {1513185957000: {"svacct_id": 123, "amount": 99.5}} + + protos = python_values_to_proto_values([data], ValueType.SCALAR_MAP) + result = feast_value_type_to_python_type(protos[0]) + + assert result[1513185957000]["svacct_id"] == 123 + assert result[1513185957000]["amount"] == 99.5 + + def test_uuid_key_roundtrip(self): + """UUID keys are encoded as uuid_key strings and decoded back to uuid.UUID.""" + key1 = uuid.UUID("12345678-1234-5678-1234-567812345678") + key2 = uuid.UUID("87654321-4321-8765-4321-876543218765") + data = {key1: "first", key2: "second"} + + protos = python_values_to_proto_values([data], ValueType.SCALAR_MAP) + result = feast_value_type_to_python_type(protos[0]) + + assert result[key1] == "first" + assert result[key2] == "second" + + def test_type_inference_non_string_keys_returns_scalar_map(self): + """python_type_to_feast_value_type infers SCALAR_MAP for non-string-keyed dicts.""" + assert python_type_to_feast_value_type("f", {1: "a"}) == ValueType.SCALAR_MAP + assert ( + python_type_to_feast_value_type("f", {uuid.uuid4(): "x"}) + == ValueType.SCALAR_MAP + ) + + def test_type_inference_string_keys_returns_map(self): + """python_type_to_feast_value_type still infers MAP for string-keyed dicts.""" + assert python_type_to_feast_value_type("f", {"k": "v"}) == ValueType.MAP + + def test_type_inference_empty_dict_returns_map(self): + """Empty dict infers MAP (no key to inspect).""" + assert python_type_to_feast_value_type("f", {}) == ValueType.MAP + + def test_none_value_roundtrip(self): + """None values in SCALAR_MAP are preserved as None.""" + data = {10: "present", 20: None} + + protos = python_values_to_proto_values([data], ValueType.SCALAR_MAP) + result = feast_value_type_to_python_type(protos[0]) + + assert result[10] == "present" + assert result[20] is None + + def test_null_value_map(self): + """None SCALAR_MAP encodes to empty ProtoValue and decodes to None.""" + protos = python_values_to_proto_values([None], ValueType.SCALAR_MAP) + assert protos[0] == ProtoValue() + assert feast_value_type_to_python_type(protos[0]) is None + + def test_empty_value_map(self): + """Empty dict encodes and decodes as empty SCALAR_MAP.""" + protos = python_values_to_proto_values([{}], ValueType.SCALAR_MAP) + # empty dict has no non-string key to trigger SCALAR_MAP via inference, + # but explicit type forces the path + result = feast_value_type_to_python_type(protos[0]) + assert isinstance(result, dict) + + def test_multiple_value_maps_in_batch(self): + """Batch of SCALAR_MAP values all encode correctly.""" + batch = [{1: "a", 2: "b"}, {10: "x"}, None] + + protos = python_values_to_proto_values(batch, ValueType.SCALAR_MAP) + assert feast_value_type_to_python_type(protos[0]) == {1: "a", 2: "b"} + assert feast_value_type_to_python_type(protos[1]) == {10: "x"} + assert feast_value_type_to_python_type(protos[2]) is None + + def test_nested_map_value_in_value_map(self): + """SCALAR_MAP can hold nested dicts as values (encoded as MAP vals).""" + inner = {"name": "alice", "score": 42} + data = {100: inner} + + protos = python_values_to_proto_values([data], ValueType.SCALAR_MAP) + result = feast_value_type_to_python_type(protos[0]) + + assert result[100]["name"] == "alice" + assert result[100]["score"] == 42 + + def test_invalid_key_type_raises(self): + """Passing an unsupported key type raises TypeError.""" + + class Unsupported: + pass + + with pytest.raises(TypeError, match="Unsupported key type for SCALAR_MAP"): + python_values_to_proto_values([{Unsupported(): "v"}], ValueType.SCALAR_MAP) + + def test_proto_field_name_in_map(self): + """scalar_map_val maps to ValueType.SCALAR_MAP in PROTO_VALUE_TO_VALUE_TYPE_MAP.""" + from feast.type_map import PROTO_VALUE_TO_VALUE_TYPE_MAP + + assert PROTO_VALUE_TO_VALUE_TYPE_MAP["scalar_map_val"] == ValueType.SCALAR_MAP + + +class TestArrowArrayStringListMaterialization: + """Regression tests for Array(String) columns from Arrow/Athena materialization. + + Arrow/Athena deserializes Array(String) feature columns as numpy.ndarray with + object dtype. Two bugs were triggered: + + 1. ValueError: "The truth value of an empty array is ambiguous" + — when an empty ndarray reached the scalar null-check `elif not pd.isnull(value)`. + + 2. TypeError: "bad argument type for built-in operation" + — when proto_type(val=) was called; protobuf rejects ndarrays. + + Both are fixed by _sanitize_list_value, which converts ndarrays to plain Python + lists and replaces None elements with a type-appropriate zero/empty default + (see _LIST_NONE_DEFAULTS). + """ + + def test_sanitize_list_value_ndarray(self): + """ndarray is converted to a plain Python list.""" + from feast.type_map import _sanitize_list_value + + arr = np.array(["foo", "bar"], dtype=object) + result = _sanitize_list_value(arr, ValueType.STRING_LIST) + assert result == ["foo", "bar"] + assert isinstance(result, list) + + def test_sanitize_list_value_empty_ndarray(self): + """Empty ndarray is converted to an empty Python list.""" + from feast.type_map import _sanitize_list_value + + arr = np.array([], dtype=object) + result = _sanitize_list_value(arr, ValueType.STRING_LIST) + assert result == [] + + def test_sanitize_list_value_ndarray_with_none(self): + """None elements inside a STRING_LIST ndarray are replaced with empty string.""" + from feast.type_map import _sanitize_list_value + + arr = np.array(["foo", None, "baz"], dtype=object) + result = _sanitize_list_value(arr, ValueType.STRING_LIST) + assert result == ["foo", "", "baz"] + + def test_sanitize_list_value_plain_list(self): + """Plain Python lists without None pass through unchanged.""" + from feast.type_map import _sanitize_list_value + + lst = ["foo", "bar"] + result = _sanitize_list_value(lst, ValueType.STRING_LIST) + assert result == ["foo", "bar"] + + def test_sanitize_list_value_plain_list_with_none(self): + """None elements in a STRING_LIST plain list are replaced with empty string.""" + from feast.type_map import _sanitize_list_value + + lst = ["foo", None] + result = _sanitize_list_value(lst, ValueType.STRING_LIST) + assert result == ["foo", ""] + + def test_sanitize_list_value_numeric_none_replaced(self): + """None elements in numeric lists are replaced with a type-appropriate default.""" + from feast.type_map import _sanitize_list_value + + assert _sanitize_list_value([1, None, 2], ValueType.INT32_LIST) == [1, 0, 2] + assert _sanitize_list_value([1, None, 2], ValueType.INT64_LIST) == [1, 0, 2] + assert _sanitize_list_value([1.0, None, 2.0], ValueType.FLOAT_LIST) == [ + 1.0, + 0.0, + 2.0, + ] + assert _sanitize_list_value([1.0, None, 2.0], ValueType.DOUBLE_LIST) == [ + 1.0, + 0.0, + 2.0, + ] + assert _sanitize_list_value([True, None, False], ValueType.BOOL_LIST) == [ + True, + False, + False, + ] + + def test_sanitize_list_value_bytes_none_replaced(self): + """None elements in BYTES_LIST are replaced with b''.""" + from feast.type_map import _sanitize_list_value + + result = _sanitize_list_value([b"x", None], ValueType.BYTES_LIST) + assert result == [b"x", b""] + + def test_sanitize_list_value_scalar_passthrough(self): + """Non-list, non-ndarray values are returned unchanged.""" + from feast.type_map import _sanitize_list_value + + assert _sanitize_list_value("hello", ValueType.STRING_LIST) == "hello" + assert _sanitize_list_value(42, ValueType.INT32_LIST) == 42 + + def test_string_list_from_ndarray(self): + """STRING_LIST column with ndarray values materializes without TypeError.""" + values = [ + np.array(["foo", "bar"], dtype=object), + np.array(["baz"], dtype=object), + ] + protos = python_values_to_proto_values(values, ValueType.STRING_LIST) + assert len(protos) == 2 + assert list(protos[0].string_list_val.val) == ["foo", "bar"] + assert list(protos[1].string_list_val.val) == ["baz"] + + def test_string_list_from_empty_ndarray(self): + """Empty ndarray in a STRING_LIST column must not raise ValueError.""" + values = [ + np.array([], dtype=object), + np.array(["foo"], dtype=object), + ] + protos = python_values_to_proto_values(values, ValueType.STRING_LIST) + assert list(protos[0].string_list_val.val) == [] + assert list(protos[1].string_list_val.val) == ["foo"] + + def test_string_list_from_ndarray_with_none_elements(self): + """None elements inside an ndarray must not cause TypeError in protobuf.""" + values = [ + np.array(["foo", None, "baz"], dtype=object), + ] + protos = python_values_to_proto_values(values, ValueType.STRING_LIST) + # None is replaced with empty string + assert list(protos[0].string_list_val.val) == ["foo", "", "baz"] + + def test_string_list_null_row_produces_empty_proto(self): + """A None row (missing user) produces an empty ProtoValue.""" + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + values = [ + None, + np.array(["foo"], dtype=object), + ] + protos = python_values_to_proto_values(values, ValueType.STRING_LIST) + assert protos[0] == ProtoValue() + assert list(protos[1].string_list_val.val) == ["foo"] + + def test_mixed_batch_simulating_athena_chunk(self): + """Simulate a real Athena chunk: mix of ndarray, empty ndarray, and None rows. + + This is the exact scenario that triggered the TypeError during + string_list_features materialization. + """ + from feast.protos.feast.types.Value_pb2 import Value as ProtoValue + + # tags / labels column from Athena + values = [ + np.array(["foo", "bar"], dtype=object), # normal entity + np.array([], dtype=object), # entity with no values set + None, # missing entity (NULL row) + np.array(["baz"], dtype=object), # normal entity + np.array(["qux", None], dtype=object), # entity with partial null + ] + protos = python_values_to_proto_values(values, ValueType.STRING_LIST) + + assert list(protos[0].string_list_val.val) == ["foo", "bar"] + assert list(protos[1].string_list_val.val) == [] + assert protos[2] == ProtoValue() + assert list(protos[3].string_list_val.val) == ["baz"] + assert list(protos[4].string_list_val.val) == ["qux", ""] + + +class TestZonedTimestamp: + def test_round_trip_preserves_zone(self): + from datetime import datetime + from zoneinfo import ZoneInfo + + dt = datetime(2026, 6, 17, 9, 0, 0, tzinfo=ZoneInfo("America/Los_Angeles")) + protos = python_values_to_proto_values([dt], ValueType.ZONED_TIMESTAMP) + assert protos[0].WhichOneof("val") == "zoned_timestamp_val" + assert protos[0].zoned_timestamp_val.zone == "America/Los_Angeles" + + converted = feast_value_type_to_python_type(protos[0]) + # Same instant AND same wall-clock zone (unlike UNIX_TIMESTAMP, which is UTC). + assert converted == dt + assert str(converted.tzinfo) == "America/Los_Angeles" + assert converted.hour == 9 + + def test_distinct_zones_same_instant_are_not_collapsed(self): + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + + la = datetime(2026, 6, 17, 9, 0, 0, tzinfo=ZoneInfo("America/Los_Angeles")) + utc = datetime(2026, 6, 17, 16, 0, 0, tzinfo=timezone.utc) # same instant + protos = python_values_to_proto_values([la, utc], ValueType.ZONED_TIMESTAMP) + # Same epoch, different zone preserved. + assert ( + protos[0].zoned_timestamp_val.unix_timestamp + == protos[1].zoned_timestamp_val.unix_timestamp + ) + assert protos[0].zoned_timestamp_val.zone == "America/Los_Angeles" + assert protos[1].zoned_timestamp_val.zone == "UTC" + + def test_naive_datetime_treated_as_utc(self): + from datetime import datetime, timezone + + dt = datetime(2026, 6, 17, 12, 0, 0) # naive + protos = python_values_to_proto_values([dt], ValueType.ZONED_TIMESTAMP) + assert protos[0].zoned_timestamp_val.zone == "" + converted = feast_value_type_to_python_type(protos[0]) + assert converted == dt.replace(tzinfo=timezone.utc) + + def test_null_values(self): + protos = python_values_to_proto_values([None], ValueType.ZONED_TIMESTAMP) + assert protos[0] == ProtoValue() + assert feast_value_type_to_python_type(protos[0]) is None + + def test_value_type_round_trips_to_feast_type(self): + from feast.types import ZonedTimestamp, from_value_type + + assert from_value_type(ValueType.ZONED_TIMESTAMP) == ZonedTimestamp + assert ZonedTimestamp.to_value_type() == ValueType.ZONED_TIMESTAMP + + def test_fixed_offset_zone_round_trips(self): + from datetime import datetime, timedelta, timezone + + # A fixed-offset tzinfo has no IANA key, so _zone_name stores it as an + # offset string. Decode must preserve the offset rather than dropping to UTC. + offset = timezone(timedelta(hours=-7)) + dt = datetime(2026, 6, 17, 9, 0, 0, tzinfo=offset) + protos = python_values_to_proto_values([dt], ValueType.ZONED_TIMESTAMP) + + converted = feast_value_type_to_python_type(protos[0]) + # Same instant AND same wall-clock offset preserved. + assert converted == dt + assert converted.utcoffset() == timedelta(hours=-7) + assert converted.hour == 9 + + def test_str_to_value_type_resolves_zoned_timestamp(self): + from feast.type_map import _convert_value_type_str_to_value_type + + # Must not silently fall back to STRING. + assert ( + _convert_value_type_str_to_value_type("ZONED_TIMESTAMP") + == ValueType.ZONED_TIMESTAMP + ) + + def test_not_supported_as_collection_base_type(self): + # ZonedTimestamp has no ZONED_TIMESTAMP_LIST/_SET ValueType, so it must be + # rejected as an Array/Set base type rather than KeyError-ing later. + from feast.types import Array, Set, ZonedTimestamp + + with pytest.raises(ValueError): + Array(ZonedTimestamp) + with pytest.raises(ValueError): + Set(ZonedTimestamp) diff --git a/sdk/python/tests/unit/test_types.py b/sdk/python/tests/unit/test_types.py index 438735d213a..aa89a1b4c6c 100644 --- a/sdk/python/tests/unit/test_types.py +++ b/sdk/python/tests/unit/test_types.py @@ -1,6 +1,23 @@ +import pyarrow import pytest -from feast.types import Array, Float32, Set, String, from_value_type +from feast.field import Field +from feast.types import ( + Array, + Bool, + Decimal, + Float32, + Float64, + Int32, + Int64, + Set, + String, + TimeUuid, + Uuid, + from_feast_to_pyarrow_type, + from_feast_type, + from_value_type, +) from feast.value_type import ValueType @@ -23,9 +40,6 @@ def test_array_feast_type(): with pytest.raises(ValueError): _ = Array(Array) - with pytest.raises(ValueError): - _ = Array(Array(String)) - def test_set_feast_type(): set_string = Set(String) @@ -39,8 +53,201 @@ def test_set_feast_type(): with pytest.raises(ValueError): _ = Set(Set) - with pytest.raises(ValueError): - _ = Set(Set(String)) + +def test_nested_array_array(): + """Array(Array(T)) should produce VALUE_LIST.""" + t = Array(Array(String)) + assert t.to_value_type() == ValueType.VALUE_LIST + assert from_feast_type(t) == ValueType.VALUE_LIST + + t2 = Array(Array(Int32)) + assert t2.to_value_type() == ValueType.VALUE_LIST + + +def test_nested_array_set(): + """Array(Set(T)) should produce VALUE_LIST.""" + t = Array(Set(String)) + assert t.to_value_type() == ValueType.VALUE_LIST + assert from_feast_type(t) == ValueType.VALUE_LIST + + +def test_nested_set_array(): + """Set(Array(T)) should produce VALUE_SET.""" + t = Set(Array(String)) + assert t.to_value_type() == ValueType.VALUE_SET + assert from_feast_type(t) == ValueType.VALUE_SET + + +def test_nested_set_set(): + """Set(Set(T)) should produce VALUE_SET.""" + t = Set(Set(String)) + assert t.to_value_type() == ValueType.VALUE_SET + assert from_feast_type(t) == ValueType.VALUE_SET + + +def test_nested_unbounded_depth(): + """Nesting depth should be unbounded.""" + # 3-level + t3 = Array(Array(Array(String))) + assert t3.to_value_type() == ValueType.VALUE_LIST + + t3_mixed = Array(Set(Array(String))) + assert t3_mixed.to_value_type() == ValueType.VALUE_LIST + + t3_set = Set(Array(Array(String))) + assert t3_set.to_value_type() == ValueType.VALUE_SET + + t3_set2 = Set(Set(Set(String))) + assert t3_set2.to_value_type() == ValueType.VALUE_SET + + # 4-level + t4 = Array(Array(Array(Array(Int32)))) + assert t4.to_value_type() == ValueType.VALUE_LIST + + +def test_nested_from_value_type_roundtrip(): + """from_value_type should return a placeholder for nested types.""" + for vt in ( + ValueType.VALUE_LIST, + ValueType.VALUE_SET, + ): + ft = from_value_type(vt) + assert ft.to_value_type() == vt + + +def test_nested_pyarrow_conversion(): + """Nested collection types should convert to pyarrow list(list(...)).""" + # Array(Array(String)) -> list(list(string)) + pa_type = from_feast_to_pyarrow_type(Array(Array(String))) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.string())) + + # Array(Set(Int64)) -> list(list(int64)) + pa_type = from_feast_to_pyarrow_type(Array(Set(Int64))) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.int64())) + + # Set(Array(Float64)) -> list(list(float64)) + pa_type = from_feast_to_pyarrow_type(Set(Array(Float64))) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.float64())) + + # Set(Set(Bool)) -> list(list(bool)) + pa_type = from_feast_to_pyarrow_type(Set(Set(Bool))) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.bool_())) + + # 3-level: Array(Array(Array(Int32))) -> list(list(list(int32))) + pa_type = from_feast_to_pyarrow_type(Array(Array(Array(Int32)))) + assert pa_type == pyarrow.list_(pyarrow.list_(pyarrow.list_(pyarrow.int32()))) + + +def test_nested_field_roundtrip(): + """Field with nested collection type should survive to_proto -> from_proto.""" + test_cases = [ + ("aa", Array(Array(String))), + ("as_field", Array(Set(Int32))), + ("sa", Set(Array(Float64))), + ("ss", Set(Set(Bool))), + # 3-level nesting + ("aaa", Array(Array(Array(Int32)))), + ("asa", Array(Set(Array(String)))), + # 4-level nesting + ("aaaa", Array(Array(Array(Array(Float64))))), + ] + for name, dtype in test_cases: + field = Field(name=name, dtype=dtype, tags={"user_tag": "value"}) + proto = field.to_proto() + restored = Field.from_proto(proto) + assert restored.name == name, f"Name mismatch for {dtype}" + assert restored.dtype.to_value_type() == dtype.to_value_type(), ( + f"dtype mismatch for {name}: {restored.dtype} vs {dtype}" + ) + # Verify inner type is preserved (not just ValueType equality) + assert str(restored.dtype) == str(dtype), ( + f"Inner type lost for {name}: got {restored.dtype}, expected {dtype}" + ) + assert restored.tags == {"user_tag": "value"}, ( + f"Tags should not contain internal tags for {name}" + ) + + +def test_uuid_feast_type(): + assert Uuid.to_value_type() == ValueType.UUID + assert from_value_type(ValueType.UUID) == Uuid + assert TimeUuid.to_value_type() == ValueType.TIME_UUID + assert from_value_type(ValueType.TIME_UUID) == TimeUuid + + +def test_uuid_array_feast_type(): + array_uuid = Array(Uuid) + assert array_uuid.to_value_type() == ValueType.UUID_LIST + assert from_value_type(array_uuid.to_value_type()) == array_uuid + + array_time_uuid = Array(TimeUuid) + assert array_time_uuid.to_value_type() == ValueType.TIME_UUID_LIST + assert from_value_type(array_time_uuid.to_value_type()) == array_time_uuid + + +def test_uuid_set_feast_type(): + set_uuid = Set(Uuid) + assert set_uuid.to_value_type() == ValueType.UUID_SET + assert from_value_type(set_uuid.to_value_type()) == set_uuid + + set_time_uuid = Set(TimeUuid) + assert set_time_uuid.to_value_type() == ValueType.TIME_UUID_SET + assert from_value_type(set_time_uuid.to_value_type()) == set_time_uuid + + +def test_decimal_feast_type(): + assert Decimal.to_value_type() == ValueType.DECIMAL + assert from_value_type(ValueType.DECIMAL) == Decimal + + +def test_decimal_array_feast_type(): + array_decimal = Array(Decimal) + assert array_decimal.to_value_type() == ValueType.DECIMAL_LIST + assert from_value_type(array_decimal.to_value_type()) == array_decimal + + +def test_decimal_set_feast_type(): + set_decimal = Set(Decimal) + assert set_decimal.to_value_type() == ValueType.DECIMAL_SET + assert from_value_type(set_decimal.to_value_type()) == set_decimal + + +def test_feast_type_str_roundtrip(): + """_feast_type_to_str and _str_to_feast_type should roundtrip for nested types.""" + from feast.field import _feast_type_to_str, _str_to_feast_type + + test_cases = [ + Array(Array(String)), + Array(Array(Int32)), + Array(Array(Float64)), + Array(Set(Int64)), + Array(Set(Bool)), + Set(Array(String)), + Set(Array(Float32)), + Set(Set(Int32)), + Set(Set(Float64)), + # 3+ level nesting + Array(Array(Array(String))), + Array(Set(Array(Int32))), + Set(Set(Set(Float64))), + ] + for dtype in test_cases: + s = _feast_type_to_str(dtype) + restored = _str_to_feast_type(s) + assert str(restored) == str(dtype), ( + f"Roundtrip failed: {dtype} -> '{s}' -> {restored}" + ) + + +def test_str_to_feast_type_invalid(): + """_str_to_feast_type should raise ValueError on unrecognized type names.""" + from feast.field import _str_to_feast_type + + with pytest.raises(ValueError, match="Unknown FeastType"): + _str_to_feast_type("INVALID_TYPE") + + with pytest.raises(ValueError, match="Unknown FeastType"): + _str_to_feast_type("Strig") def test_all_value_types(): diff --git a/sdk/python/tests/unit/test_ui_server.py b/sdk/python/tests/unit/test_ui_server.py index 36389f7b860..d878a3f1a20 100644 --- a/sdk/python/tests/unit/test_ui_server.py +++ b/sdk/python/tests/unit/test_ui_server.py @@ -15,7 +15,6 @@ EXPECTED_SUCCESS_STATUS = 200 EXPECTED_ERROR_STATUS = 503 TEST_PROJECT_NAME = "test_project" -REGISTRY_TTL_SECS = 60 def _create_mock_ui_files(temp_dir): @@ -23,12 +22,10 @@ def _create_mock_ui_files(temp_dir): ui_dir = os.path.join(temp_dir, "ui", "build") os.makedirs(ui_dir, exist_ok=True) - # Create projects-list.json file projects_file = os.path.join(ui_dir, "projects-list.json") with open(projects_file, "w") as f: json.dump({"projects": []}, f) - # Create index.html file index_file = os.path.join(ui_dir, "index.html") with open(index_file, "w") as f: f.write("Test UI") @@ -36,20 +33,13 @@ def _create_mock_ui_files(temp_dir): @contextlib.contextmanager def _setup_importlib_mocks(temp_dir): - """Helper function to setup importlib resource mocks. - - This function mocks the importlib_resources functionality used by the UI server - to serve static files. It creates a proper context manager that returns the - temporary directory path when used with importlib_resources.as_file(). - """ + """Helper function to setup importlib resource mocks.""" mock_path = Path(temp_dir) - # Create a proper context manager mock mock_context_manager = MagicMock() mock_context_manager.__enter__.return_value = mock_path mock_context_manager.__exit__.return_value = None - # Mock the files() method to return a mock that supports division mock_file_ref = MagicMock() mock_file_ref.__truediv__.return_value = MagicMock() @@ -63,104 +53,65 @@ def _setup_importlib_mocks(temp_dir): yield mock_files, mock_as_file +def _make_project_mock(name, description=""): + """Create a mock project object with the given name and description.""" + proj = MagicMock() + proj.name = name + proj.description = description + return proj + + @pytest.fixture def mock_feature_store(): """Fixture for creating a mock feature store""" mock_store = MagicMock() - mock_store.refresh_registry = MagicMock() return mock_store @pytest.fixture def ui_app_with_registry(mock_feature_store): - """Fixture for UI app with valid registry data. - - Creates a UI app instance with a properly configured feature store - that has valid registry data available for testing endpoints that - require registry access. - """ + """Fixture for UI app with valid registry data.""" mock_registry = MagicMock() - mock_proto = MagicMock() - mock_proto.SerializeToString.return_value = b"mock_proto_data" - mock_registry.proto.return_value = mock_proto + mock_registry.list_projects.return_value = [] mock_feature_store.registry = mock_registry with tempfile.TemporaryDirectory() as temp_dir: _create_mock_ui_files(temp_dir) with _setup_importlib_mocks(temp_dir): - app = get_app(mock_feature_store, TEST_PROJECT_NAME, REGISTRY_TTL_SECS) + app = get_app(mock_feature_store, TEST_PROJECT_NAME) yield app @pytest.fixture def ui_app_without_registry(mock_feature_store): - """Fixture for UI app with None registry data. - - Creates a UI app instance with a feature store that has no registry - data available, used for testing error conditions and service - unavailable responses. - """ + """Fixture for UI app where registry raises on list_projects.""" mock_registry = MagicMock() - mock_registry.proto.return_value = None + mock_registry.list_projects.side_effect = Exception("registry unavailable") mock_feature_store.registry = mock_registry with tempfile.TemporaryDirectory() as temp_dir: _create_mock_ui_files(temp_dir) with _setup_importlib_mocks(temp_dir): - app = get_app(mock_feature_store, TEST_PROJECT_NAME, REGISTRY_TTL_SECS) + app = get_app(mock_feature_store, TEST_PROJECT_NAME) yield app def test_ui_server_health_endpoint(ui_app_with_registry): - """Test the UI server health endpoint returns 200 when registry is available. - - This test verifies that the /health endpoint correctly returns HTTP 200 - when the feature store registry is properly initialized and contains data. - """ + """Health endpoint returns 200 when registry is available.""" client = TestClient(ui_app_with_registry) response = client.get("/health") assertpy.assert_that(response.status_code).is_equal_to(EXPECTED_SUCCESS_STATUS) -def test_ui_server_health_endpoint_with_none_registry(ui_app_without_registry): - """Test the UI server health endpoint returns 503 when registry is None. - - This test verifies that the /health endpoint correctly returns HTTP 503 - (Service Unavailable) when the feature store registry is not available - or contains no data. - """ +def test_ui_server_health_endpoint_with_unavailable_registry(ui_app_without_registry): + """Health endpoint returns 503 when registry is unavailable.""" client = TestClient(ui_app_without_registry) response = client.get("/health") assertpy.assert_that(response.status_code).is_equal_to(EXPECTED_ERROR_STATUS) -def test_registry_endpoint_with_valid_data(ui_app_with_registry): - """Test the registry endpoint returns valid data with correct content type. - - This test verifies that the /registry endpoint correctly returns HTTP 200 - with the proper content-type header when registry data is available. - """ - client = TestClient(ui_app_with_registry) - response = client.get("/registry") - assertpy.assert_that(response.status_code).is_equal_to(EXPECTED_SUCCESS_STATUS) - assertpy.assert_that(response.headers["content-type"]).is_equal_to( - "application/octet-stream" - ) - - -def test_registry_endpoint_with_none_data(ui_app_without_registry): - """Test the registry endpoint returns 503 when registry data is None. - - This test verifies that the /registry endpoint correctly returns HTTP 503 - (Service Unavailable) when no registry data is available. - """ - client = TestClient(ui_app_without_registry) - response = client.get("/registry") - assertpy.assert_that(response.status_code).is_equal_to(EXPECTED_ERROR_STATUS) - - @pytest.mark.parametrize( "registry_available,expected_status", [(True, EXPECTED_SUCCESS_STATUS), (False, EXPECTED_ERROR_STATUS)], @@ -168,42 +119,131 @@ def test_registry_endpoint_with_none_data(ui_app_without_registry): def test_health_endpoint_status( registry_available, expected_status, mock_feature_store ): - """Test the health endpoint returns correct status based on registry availability. - - This parametrized test verifies that the /health endpoint returns the - appropriate HTTP status code based on whether registry data is available. - """ + """Health endpoint returns correct status based on registry availability.""" + mock_registry = MagicMock() if registry_available: - mock_registry = MagicMock() - mock_proto = MagicMock() - mock_proto.SerializeToString.return_value = b"mock_proto_data" - mock_registry.proto.return_value = mock_proto - mock_feature_store.registry = mock_registry + mock_registry.list_projects.return_value = [] else: - mock_registry = MagicMock() - mock_registry.proto.return_value = None - mock_feature_store.registry = mock_registry + mock_registry.list_projects.side_effect = Exception("unavailable") + mock_feature_store.registry = mock_registry with tempfile.TemporaryDirectory() as temp_dir: _create_mock_ui_files(temp_dir) with _setup_importlib_mocks(temp_dir): - app = get_app(mock_feature_store, TEST_PROJECT_NAME, REGISTRY_TTL_SECS) + app = get_app(mock_feature_store, TEST_PROJECT_NAME) client = TestClient(app) response = client.get("/health") assertpy.assert_that(response.status_code).is_equal_to(expected_status) def test_catch_all_route(ui_app_with_registry): - """Test the catch-all route for React router paths. - - This test reveals a bug in the original UI server code where ui_dir - is not in scope for the catch_all function. The ui_dir variable is defined - inside the importlib_resources context manager but used outside of it. - This causes a NameError when the route is accessed. - """ + """Test the catch-all route for React router paths.""" client = TestClient(ui_app_with_registry) - # The route will fail due to the scope issue with ui_dir - with pytest.raises(Exception): # Expecting NameError or FileNotFoundError + with pytest.raises(Exception): client.get("/p/some/react/path") + + +# ---------- projects-list.json tests ---------- + + +def _read_projects_list(temp_dir): + """Read the projects-list.json written by get_app via the mock (ui_dir = temp_dir).""" + projects_file = os.path.join(temp_dir, "projects-list.json") + with open(projects_file) as f: + return json.load(f) + + +def test_projects_list_registry_path(mock_feature_store): + """projects-list.json uses /api/v1 as registryPath.""" + mock_registry = MagicMock() + mock_registry.list_projects.return_value = [] + mock_feature_store.registry = mock_registry + + with tempfile.TemporaryDirectory() as temp_dir: + _create_mock_ui_files(temp_dir) + + with _setup_importlib_mocks(temp_dir): + get_app(mock_feature_store, TEST_PROJECT_NAME) + + data = _read_projects_list(temp_dir) + assertpy.assert_that(data["projects"][0]["registryPath"]).is_equal_to("/api/v1") + + +def test_projects_list_with_root_path(mock_feature_store): + """root_path prefix is included in registryPath.""" + mock_registry = MagicMock() + mock_registry.list_projects.return_value = [] + mock_feature_store.registry = mock_registry + + with tempfile.TemporaryDirectory() as temp_dir: + _create_mock_ui_files(temp_dir) + + with _setup_importlib_mocks(temp_dir): + get_app( + mock_feature_store, + TEST_PROJECT_NAME, + root_path="/feast", + ) + + data = _read_projects_list(temp_dir) + assertpy.assert_that(data["projects"][0]["registryPath"]).is_equal_to( + "/feast/api/v1" + ) + + +def test_projects_list_multiple_projects(mock_feature_store): + """Multiple projects get an 'All Projects' entry prepended.""" + mock_registry = MagicMock() + mock_registry.list_projects.return_value = [ + _make_project_mock("project_alpha", "Alpha project"), + _make_project_mock("project_beta", "Beta project"), + ] + mock_feature_store.registry = mock_registry + + with tempfile.TemporaryDirectory() as temp_dir: + _create_mock_ui_files(temp_dir) + + with _setup_importlib_mocks(temp_dir): + get_app(mock_feature_store, TEST_PROJECT_NAME) + + data = _read_projects_list(temp_dir) + assertpy.assert_that(len(data["projects"])).is_equal_to(3) + assertpy.assert_that(data["projects"][0]["id"]).is_equal_to("all") + assertpy.assert_that(data["projects"][1]["id"]).is_equal_to("project_alpha") + assertpy.assert_that(data["projects"][2]["id"]).is_equal_to("project_beta") + + +def test_projects_list_fallback_on_empty(mock_feature_store): + """When list_projects returns empty, fallback project is used.""" + mock_registry = MagicMock() + mock_registry.list_projects.return_value = [] + mock_feature_store.registry = mock_registry + + with tempfile.TemporaryDirectory() as temp_dir: + _create_mock_ui_files(temp_dir) + + with _setup_importlib_mocks(temp_dir): + get_app(mock_feature_store, TEST_PROJECT_NAME) + + data = _read_projects_list(temp_dir) + assertpy.assert_that(len(data["projects"])).is_equal_to(1) + assertpy.assert_that(data["projects"][0]["id"]).is_equal_to(TEST_PROJECT_NAME) + + +def test_projects_list_fallback_on_exception(mock_feature_store): + """When list_projects raises, fallback project is used.""" + mock_registry = MagicMock() + mock_registry.list_projects.side_effect = Exception("not implemented") + mock_feature_store.registry = mock_registry + + with tempfile.TemporaryDirectory() as temp_dir: + _create_mock_ui_files(temp_dir) + + with _setup_importlib_mocks(temp_dir): + get_app(mock_feature_store, TEST_PROJECT_NAME) + + data = _read_projects_list(temp_dir) + assertpy.assert_that(len(data["projects"])).is_equal_to(1) + assertpy.assert_that(data["projects"][0]["id"]).is_equal_to(TEST_PROJECT_NAME) diff --git a/sdk/python/tests/unit/test_utils.py b/sdk/python/tests/unit/test_utils.py index 4ffec9750b2..7eebf46461a 100644 --- a/sdk/python/tests/unit/test_utils.py +++ b/sdk/python/tests/unit/test_utils.py @@ -1,76 +1,111 @@ """ Tests for feast.utils module. -These unit tests cover the _convert_rows_to_protobuf function which is critical -for online feature retrieval performance. The function converts raw database -rows to protobuf format for the serving response. +These unit tests cover the _populate_response_from_feature_data function +which converts raw online_read rows into protobuf FeatureVectors and +populates the GetOnlineFeaturesResponse. """ from datetime import datetime, timezone +from unittest.mock import MagicMock -from feast.protos.feast.serving.ServingService_pb2 import FieldStatus +from feast.protos.feast.serving.ServingService_pb2 import ( + FieldStatus, + GetOnlineFeaturesResponse, +) from feast.protos.feast.types.Value_pb2 import Value as ValueProto -from feast.utils import _convert_rows_to_protobuf +from feast.utils import _populate_response_from_feature_data -class TestConvertRowsToProtobuf: - """Tests for _convert_rows_to_protobuf function.""" +def _make_table(name="test_fv"): + """Create a minimal mock FeatureView for testing.""" + table = MagicMock() + table.projection.name_to_use.return_value = name + table.projection.name_alias = None + table.projection.name = name + return table - def test_basic_conversion(self): - """Test basic conversion with single feature and entity.""" + +class TestPopulateResponseFromFeatureData: + """Tests for _populate_response_from_feature_data function.""" + + def test_basic_single_feature(self): + """Test basic conversion with single feature and single entity.""" timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) value = ValueProto(float_val=1.5) read_rows = [(timestamp, {"feature_1": value})] - requested_features = ["feature_1"] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - assert len(result) == 1 - ts_vector, status_vector, value_vector = result[0] - assert len(ts_vector) == 1 - assert ts_vector[0].seconds == int(timestamp.timestamp()) - assert value_vector[0] == value - - def test_multiple_features_same_timestamp(self): - """Test that multiple features share the same pre-computed timestamp. - - This verifies the optimization: timestamps are computed once per entity, - not once per feature per entity. - """ + indexes = ([0],) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=1, + ) + + assert len(response.results) == 1 + assert response.results[0].values[0] == value + assert response.results[0].statuses[0] == FieldStatus.PRESENT + assert response.results[0].event_timestamps[0].seconds == int( + timestamp.timestamp() + ) + assert list(response.metadata.feature_names.val) == ["feature_1"] + + def test_multiple_features_same_entity(self): + """Test multiple features from the same row.""" timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) - value1 = ValueProto(float_val=1.0) - value2 = ValueProto(float_val=2.0) - - read_rows = [(timestamp, {"feature_1": value1, "feature_2": value2})] - requested_features = ["feature_1", "feature_2"] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - assert len(result) == 2 - ts1 = result[0][0][0] - ts2 = result[1][0][0] - assert ts1.seconds == ts2.seconds - assert ts1.seconds == int(timestamp.timestamp()) - - def test_multiple_entities(self): - """Test conversion with multiple entities having different timestamps.""" - ts1 = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) - ts2 = datetime(2024, 1, 2, 12, 0, 0, tzinfo=timezone.utc) - - read_rows = [ - (ts1, {"feature_1": ValueProto(float_val=1.0)}), - (ts2, {"feature_1": ValueProto(float_val=2.0)}), - ] - requested_features = ["feature_1"] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - assert len(result) == 1 - ts_vector, status_vector, value_vector = result[0] - assert len(ts_vector) == 2 - assert ts_vector[0].seconds == int(ts1.timestamp()) - assert ts_vector[1].seconds == int(ts2.timestamp()) + v1 = ValueProto(float_val=1.0) + v2 = ValueProto(float_val=2.0) + + read_rows = [(timestamp, {"feature_1": v1, "feature_2": v2})] + indexes = ([0],) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1", "feature_2"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=1, + ) + + assert len(response.results) == 2 + assert response.results[0].values[0] == v1 + assert response.results[1].values[0] == v2 + ts1 = response.results[0].event_timestamps[0].seconds + ts2 = response.results[1].event_timestamps[0].seconds + assert ts1 == ts2 == int(timestamp.timestamp()) + + def test_multiple_entities_deduplication(self): + """Test that duplicate entity rows are correctly mapped via indexes.""" + ts = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + val = ValueProto(float_val=42.0) + + read_rows = [(ts, {"feature_1": val})] + indexes = ([0, 1, 2],) # One unique row maps to 3 output positions + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=3, + ) + + assert len(response.results[0].values) == 3 + for i in range(3): + assert response.results[0].values[i] == val + assert response.results[0].statuses[i] == FieldStatus.PRESENT def test_null_timestamp_handling(self): """Test that null timestamps produce empty Timestamp proto.""" @@ -81,64 +116,120 @@ def test_null_timestamp_handling(self): {"feature_1": ValueProto(float_val=2.0)}, ), ] - requested_features = ["feature_1"] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - ts_vector = result[0][0] - assert ts_vector[0].seconds == 0 # Null timestamp -> empty proto - assert ts_vector[1].seconds != 0 # Valid timestamp + indexes = ([0],), ([1],) + indexes = ([0], [1]) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=2, + ) + + ts_list = response.results[0].event_timestamps + assert ts_list[0].seconds == 0 # Null timestamp -> empty proto + assert ts_list[1].seconds != 0 # Valid timestamp def test_missing_feature_data(self): """Test handling of missing feature data (None row).""" - timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + ts = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) read_rows = [ - (timestamp, {"feature_1": ValueProto(float_val=1.0)}), - (timestamp, None), # No feature data for this entity + (ts, {"feature_1": ValueProto(float_val=1.0)}), + (ts, None), ] - requested_features = ["feature_1"] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - ts_vector, status_vector, value_vector = result[0] - assert len(ts_vector) == 2 - assert status_vector[0] == FieldStatus.PRESENT - assert status_vector[1] == FieldStatus.NOT_FOUND + indexes = ([0], [1]) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=2, + ) + + assert response.results[0].statuses[0] == FieldStatus.PRESENT + assert response.results[0].statuses[1] == FieldStatus.NOT_FOUND def test_feature_not_in_row(self): """Test handling when requested feature is not in the row's data.""" - timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) - - read_rows = [ - (timestamp, {"feature_1": ValueProto(float_val=1.0)}), - ] - requested_features = ["feature_1", "feature_2"] # feature_2 not in data - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - assert len(result) == 2 - # feature_1 is present - assert result[0][1][0] == FieldStatus.PRESENT - # feature_2 is not found - assert result[1][1][0] == FieldStatus.NOT_FOUND + ts = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + + read_rows = [(ts, {"feature_1": ValueProto(float_val=1.0)})] + indexes = ([0],) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1", "feature_2"], + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=1, + ) + + assert len(response.results) == 2 + assert response.results[0].statuses[0] == FieldStatus.PRESENT + assert response.results[1].statuses[0] == FieldStatus.NOT_FOUND def test_empty_inputs(self): """Test handling of empty inputs.""" - # Empty rows - result = _convert_rows_to_protobuf(["feature_1"], []) - assert len(result) == 1 - assert len(result[0][0]) == 0 # Empty ts_vector - - # Empty features - timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) - result = _convert_rows_to_protobuf([], [(timestamp, {"f": ValueProto()})]) - assert len(result) == 0 + response = GetOnlineFeaturesResponse(results=[]) + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=[], + indexes=(), + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=0, + ) + assert len(response.results) == 1 + assert len(response.results[0].values) == 0 + + response2 = GetOnlineFeaturesResponse(results=[]) + ts = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + _populate_response_from_feature_data( + requested_features=[], + read_rows=[(ts, {"f": ValueProto()})], + indexes=([0],), + online_features_response=response2, + full_feature_names=False, + table=_make_table(), + output_len=1, + ) + assert len(response2.results) == 0 + + def test_full_feature_names(self): + """Test that full_feature_names prefixes feature names with table name.""" + ts = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + read_rows = [(ts, {"feature_1": ValueProto(float_val=1.0)})] + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=["feature_1"], + read_rows=read_rows, + indexes=([0],), + online_features_response=response, + full_feature_names=True, + table=_make_table("my_fv"), + output_len=1, + ) + + assert list(response.metadata.feature_names.val) == ["my_fv__feature_1"] def test_large_scale_correctness(self): """Test correctness with large number of features and entities. - This test verifies that the optimized implementation produces correct + This test verifies that the fused implementation produces correct results at scale (50 features x 500 entities = 25,000 data points). """ timestamp = datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc) @@ -150,21 +241,28 @@ def test_large_scale_correctness(self): } read_rows = [(timestamp, feature_data.copy()) for _ in range(num_entities)] requested_features = [f"feature_{i}" for i in range(num_features)] - - result = _convert_rows_to_protobuf(requested_features, read_rows) - - # Verify structure - assert len(result) == num_features - for feature_idx, (ts_vector, status_vector, value_vector) in enumerate(result): - assert len(ts_vector) == num_entities - assert len(status_vector) == num_entities - assert len(value_vector) == num_entities - - # Verify all timestamps are the same (pre-computed once) - expected_ts = int(timestamp.timestamp()) - for ts in ts_vector: + indexes = tuple([i] for i in range(num_entities)) + response = GetOnlineFeaturesResponse(results=[]) + + _populate_response_from_feature_data( + requested_features=requested_features, + read_rows=read_rows, + indexes=indexes, + online_features_response=response, + full_feature_names=False, + table=_make_table(), + output_len=num_entities, + ) + + assert len(response.results) == num_features + expected_ts = int(timestamp.timestamp()) + for feature_idx in range(num_features): + fv = response.results[feature_idx] + assert len(fv.values) == num_entities + assert len(fv.statuses) == num_entities + assert len(fv.event_timestamps) == num_entities + + for ts in fv.event_timestamps: assert ts.seconds == expected_ts - - # Verify all statuses are PRESENT - for status in status_vector: + for status in fv.statuses: assert status == FieldStatus.PRESENT diff --git a/sdk/python/tests/unit/transformation/__init__.py b/sdk/python/tests/unit/transformation/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/tests/unit/transformation/test_factory.py b/sdk/python/tests/unit/transformation/test_factory.py new file mode 100644 index 00000000000..64c0e282239 --- /dev/null +++ b/sdk/python/tests/unit/transformation/test_factory.py @@ -0,0 +1,102 @@ +from unittest.mock import MagicMock, patch + +import pytest + +from feast.transformation.factory import ( + TRANSFORMATION_CLASS_FOR_TYPE, + get_transformation_class_from_type, +) + + +class TestTransformationClassForType: + def test_all_expected_types_registered(self): + expected_types = { + "python", + "pandas", + "substrait", + "sql", + "spark_sql", + "spark", + "flink", + "ray", + } + assert set(TRANSFORMATION_CLASS_FOR_TYPE.keys()) == expected_types + + def test_spark_and_spark_sql_resolve_to_same_class(self): + assert ( + TRANSFORMATION_CLASS_FOR_TYPE["spark"] + == TRANSFORMATION_CLASS_FOR_TYPE["spark_sql"] + ) + + +class TestGetTransformationClassFromType: + @patch("feast.transformation.factory.import_class") + def test_known_type_resolves(self, mock_import): + mock_cls = MagicMock() + mock_import.return_value = mock_cls + + result = get_transformation_class_from_type("python") + + mock_import.assert_called_once_with( + "feast.transformation.python_transformation", + "PythonTransformation", + "PythonTransformation", + ) + assert result == mock_cls + + @patch("feast.transformation.factory.import_class") + def test_pandas_type_resolves(self, mock_import): + mock_cls = MagicMock() + mock_import.return_value = mock_cls + + get_transformation_class_from_type("pandas") + + mock_import.assert_called_once_with( + "feast.transformation.pandas_transformation", + "PandasTransformation", + "PandasTransformation", + ) + + @patch("feast.transformation.factory.import_class") + def test_sql_type_resolves(self, mock_import): + mock_cls = MagicMock() + mock_import.return_value = mock_cls + + get_transformation_class_from_type("sql") + + mock_import.assert_called_once_with( + "feast.transformation.sql_transformation", + "SQLTransformation", + "SQLTransformation", + ) + + @patch("feast.transformation.factory.import_class") + def test_flink_type_resolves(self, mock_import): + mock_cls = MagicMock() + mock_import.return_value = mock_cls + + get_transformation_class_from_type("flink") + + mock_import.assert_called_once_with( + "feast.transformation.flink_transformation", + "FlinkTransformation", + "FlinkTransformation", + ) + + def test_invalid_type_raises_value_error(self): + with pytest.raises(ValueError, match="Invalid transformation type"): + get_transformation_class_from_type("nonexistent") + + @patch("feast.transformation.factory.import_class") + def test_fully_qualified_class_name_accepted(self, mock_import): + """A string ending in 'Transformation' is treated as a fully qualified class path.""" + mock_cls = MagicMock() + mock_import.return_value = mock_cls + + get_transformation_class_from_type("my.custom.module.CustomTransformation") + + mock_import.assert_called_once_with( + "my.custom.module", + "CustomTransformation", + "CustomTransformation", + ) diff --git a/sdk/python/tests/unit/transformation/test_mode.py b/sdk/python/tests/unit/transformation/test_mode.py new file mode 100644 index 00000000000..3b35edcba0f --- /dev/null +++ b/sdk/python/tests/unit/transformation/test_mode.py @@ -0,0 +1,31 @@ +from feast.transformation.mode import TransformationMode + + +class TestTransformationMode: + def test_all_modes_defined(self): + expected = { + "PYTHON", + "PANDAS", + "SPARK_SQL", + "SPARK", + "FLINK", + "RAY", + "SQL", + "SUBSTRAIT", + } + actual = {m.name for m in TransformationMode} + assert actual == expected + + def test_mode_values(self): + assert TransformationMode.PYTHON.value == "python" + assert TransformationMode.PANDAS.value == "pandas" + assert TransformationMode.SPARK_SQL.value == "spark_sql" + assert TransformationMode.SPARK.value == "spark" + assert TransformationMode.FLINK.value == "flink" + assert TransformationMode.RAY.value == "ray" + assert TransformationMode.SQL.value == "sql" + assert TransformationMode.SUBSTRAIT.value == "substrait" + + def test_mode_from_value(self): + assert TransformationMode("python") == TransformationMode.PYTHON + assert TransformationMode("pandas") == TransformationMode.PANDAS diff --git a/sdk/python/tests/unit/transformation/test_sql_transformation.py b/sdk/python/tests/unit/transformation/test_sql_transformation.py new file mode 100644 index 00000000000..8d24eaac3ee --- /dev/null +++ b/sdk/python/tests/unit/transformation/test_sql_transformation.py @@ -0,0 +1,16 @@ +from feast.transformation.sql_transformation import SQLTransformation + + +def sql_udf(inputs): + return f"SELECT * FROM source WHERE id = {inputs['id']}" + + +def test_sql_transformation_transform(): + """SQLTransformation.transform delegates to the udf.""" + transformation = SQLTransformation( + mode="sql", + udf=sql_udf, + udf_string="sql_udf", + ) + result = transformation.transform({"id": 42}) + assert result == "SELECT * FROM source WHERE id = 42" diff --git a/sdk/python/tests/universal/feature_repos/repo_configuration.py b/sdk/python/tests/universal/feature_repos/repo_configuration.py index 33d189583b2..7da8d54f433 100644 --- a/sdk/python/tests/universal/feature_repos/repo_configuration.py +++ b/sdk/python/tests/universal/feature_repos/repo_configuration.py @@ -120,29 +120,36 @@ from tests.universal.feature_repos.universal.data_sources.redshift import ( RedshiftDataSourceCreator, ) - from tests.universal.feature_repos.universal.data_sources.snowflake import ( - SnowflakeDataSourceCreator, - ) AVAILABLE_OFFLINE_STORES.extend( [ ("gcp", BigQueryDataSourceCreator), ("aws", RedshiftDataSourceCreator), - ("aws", SnowflakeDataSourceCreator), ] ) OFFLINE_STORE_TO_PROVIDER_CONFIG["bigquery"] = ("gcp", BigQueryDataSourceCreator) OFFLINE_STORE_TO_PROVIDER_CONFIG["redshift"] = ("aws", RedshiftDataSourceCreator) - OFFLINE_STORE_TO_PROVIDER_CONFIG["snowflake"] = ("aws", SnowflakeDataSourceCreator) AVAILABLE_ONLINE_STORES["redis"] = (REDIS_CONFIG, None) AVAILABLE_ONLINE_STORES["dynamodb"] = (DYNAMO_CONFIG, None) AVAILABLE_ONLINE_STORES["datastore"] = ("datastore", None) - AVAILABLE_ONLINE_STORES["snowflake"] = (SNOWFLAKE_CONFIG, None) AVAILABLE_ONLINE_STORES["bigtable"] = (BIGTABLE_CONFIG, None) AVAILABLE_ONLINE_STORES["milvus"] = (MILVUS_CONFIG, None) + # Snowflake is disabled temporarily + if os.getenv("SNOWFLAKE_CI_DEPLOYMENT"): + from tests.universal.feature_repos.universal.data_sources.snowflake import ( + SnowflakeDataSourceCreator, + ) + + AVAILABLE_OFFLINE_STORES.extend([("aws", SnowflakeDataSourceCreator)]) + OFFLINE_STORE_TO_PROVIDER_CONFIG["snowflake"] = ( + "aws", + SnowflakeDataSourceCreator, + ) + AVAILABLE_ONLINE_STORES["snowflake"] = (SNOWFLAKE_CONFIG, None) + full_repo_configs_module = os.environ.get(FULL_REPO_CONFIGS_MODULE_ENV_NAME) if full_repo_configs_module is not None: @@ -193,6 +200,9 @@ from tests.universal.feature_repos.universal.online_store.milvus import ( MilvusOnlineStoreCreator, ) + from tests.universal.feature_repos.universal.online_store.postgres import ( + PGVectorOnlineStoreCreator, + ) from tests.universal.feature_repos.universal.online_store.redis import ( RedisOnlineStoreCreator, ) @@ -206,6 +216,10 @@ "datastore": ("datastore", DatastoreOnlineStoreCreator), "bigtable": ("bigtable", BigtableOnlineStoreCreator), } + AVAILABLE_ONLINE_STORES["pgvector"] = ( + {"type": "postgres", "vector_enabled": True, "sslmode": "disable"}, + PGVectorOnlineStoreCreator, + ) for key, replacement in replacements.items(): if key in AVAILABLE_ONLINE_STORES: diff --git a/sdk/python/tests/universal/feature_repos/universal/data_sources/mongodb.py b/sdk/python/tests/universal/feature_repos/universal/data_sources/mongodb.py new file mode 100644 index 00000000000..829dcda9766 --- /dev/null +++ b/sdk/python/tests/universal/feature_repos/universal/data_sources/mongodb.py @@ -0,0 +1,195 @@ +""" +MongoDB DataSourceCreator implementation for universal Feast tests. +""" + +import os +import tempfile +from typing import Any, Dict, Optional + +import pandas as pd +import pytest +from testcontainers.mongodb import MongoDbContainer + +from feast.data_source import DataSource +from feast.feature_logging import LoggingDestination +from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb import ( + MongoDBOfflineStoreConfig, + MongoDBSource, +) +from feast.infra.offline_stores.file_source import ( + FileLoggingDestination, + SavedDatasetFileStorage, +) +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import FeastConfigBaseModel +from tests.universal.feature_repos.universal.data_source_creator import ( + DataSourceCreator, +) + +try: + from pymongo import MongoClient +except ImportError: + MongoClient = None # type: ignore + + +class MongoDBDataSourceCreator(DataSourceCreator): + """DataSourceCreator for the MongoDB offline store (single shared collection).""" + + ENTITY_KEY_VERSION = 3 + + def __init__(self, project_name: str, *args, **kwargs): + super().__init__(project_name) + self.container = MongoDbContainer( + "mongo:7.0", + username="test", + password="test", # pragma: allowlist secret + ).with_exposed_ports(27017) + self.container.start() + self.port = self.container.get_exposed_port(27017) + self.connection_string = ( + f"mongodb://test:test@localhost:{self.port}" # pragma: allowlist secret + ) + self.database = f"feast_test_{project_name}" + self.collection = "feature_history" + self._entity_key_columns: Dict[str, list] = {} + + def _serialize_entity_key(self, row: pd.Series, join_keys: list[str]) -> bytes: + """Serialize entity key columns to bytes. + + Join keys are sorted before serialization to match the order used by + _serialize_entity_key_from_row at query time. Without sorting, compound + join keys written in a different order would produce different bytes and + cause all features to be returned as NULL. + """ + entity_key = EntityKeyProto() + for key in sorted(join_keys): + entity_key.join_keys.append(key) + val = ValueProto() + value = row[key] + # bool must be checked before int: bool is a subclass of int + if isinstance(value, bool): + val.bool_val = value + elif isinstance(value, int): + val.int64_val = value + elif isinstance(value, str): + val.string_val = value + elif isinstance(value, float): + val.double_val = value + else: + val.string_val = str(value) + entity_key.entity_values.append(val) + return serialize_entity_key(entity_key, self.ENTITY_KEY_VERSION) + + def create_data_source( + self, + df: pd.DataFrame, + destination_name: str, + created_timestamp_column: str = "created_ts", + field_mapping: Optional[Dict[str, str]] = None, + timestamp_field: Optional[str] = "ts", + ) -> DataSource: + """Create a MongoDB data source by inserting df into the shared collection. + + The data is transformed into the One schema: + - entity_id: serialized entity key + - feature_view: destination_name + - features: nested dict of feature values + - event_timestamp: from timestamp_field + - created_at: from created_timestamp_column + """ + # Determine which columns are join keys vs features + # Join keys must be integer or string types (serializable as entity keys) + timestamp_cols = {timestamp_field, created_timestamp_column} + all_cols = set(df.columns) - timestamp_cols - {None} + + # Heuristic: identify join keys (columns ending with _id or known key names) + join_keys = [] + for c in all_cols: + if c.endswith("_id") or c in {"driver", "customer", "entity"}: + dtype = df[c].dtype + if dtype in ("int64", "int32", "object") or str(dtype).startswith( + "int" + ): + join_keys.append(c) + + if not join_keys: + for c in all_cols: + if df[c].dtype in ("int64", "int32") or str(df[c].dtype).startswith( + "int" + ): + join_keys = [c] + break + + feature_cols = [c for c in all_cols if c not in join_keys] + self._entity_key_columns[destination_name] = join_keys + + docs = [] + for _, row in df.iterrows(): + entity_id = self._serialize_entity_key(row, join_keys) + features = {col: row[col] for col in feature_cols if pd.notna(row.get(col))} + doc: Dict[str, Any] = { + "entity_id": entity_id, + "feature_view": destination_name, + "features": features, + } + if timestamp_field and timestamp_field in row: + doc["event_timestamp"] = row[timestamp_field] + if created_timestamp_column and created_timestamp_column in row: + doc["created_at"] = row[created_timestamp_column] + docs.append(doc) + + # Insert into MongoDB + client: Any = MongoClient(self.connection_string, tz_aware=True) + try: + coll = client[self.database][self.collection] + if docs: + coll.insert_many(docs) + finally: + client.close() + + return MongoDBSource( + name=destination_name, + timestamp_field="event_timestamp", + created_timestamp_column="created_at" if created_timestamp_column else None, + field_mapping=field_mapping, + ) + + def get_prefixed_table_name(self, suffix: str) -> str: + return f"{self.project_name}_{suffix}" + + def create_offline_store_config(self) -> FeastConfigBaseModel: + return MongoDBOfflineStoreConfig( + connection_string=self.connection_string, + database=self.database, + collection=self.collection, + ) + + def create_saved_dataset_destination(self) -> SavedDatasetFileStorage: + # Saved datasets are written as parquet via SavedDatasetFileStorage. + # A fresh temp file is created per call; teardown() does not clean it up + # because the test framework owns the lifetime of saved datasets. + path = os.path.join( + tempfile.mkdtemp(), f"{self.project_name}_saved_dataset.parquet" + ) + return SavedDatasetFileStorage(path=path) + + def create_logged_features_destination(self) -> LoggingDestination: + d = tempfile.mkdtemp(prefix=self.project_name) + return FileLoggingDestination(path=d) + + def teardown(self): + try: + client: Any = MongoClient(self.connection_string, tz_aware=True) + try: + client[self.database][self.collection].drop() + finally: + client.close() + except Exception: + pass + self.container.stop() + + @staticmethod + def test_markers() -> list: + return [pytest.mark.mongodb] diff --git a/sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py b/sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py index 0c0afd4908a..a3791446232 100644 --- a/sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py +++ b/sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py @@ -1,6 +1,6 @@ from typing import Any, Dict -from testcontainers.mongodb import MongoDbContainer +from testcontainers.mongodb import MongoDBAtlasLocalContainer, MongoDbContainer from tests.universal.feature_repos.universal.online_store_creator import ( OnlineStoreCreator, @@ -29,3 +29,29 @@ def create_online_store(self) -> Dict[str, Any]: def teardown(self): self.container.stop() + + +class MongoDBAtlasOnlineStoreCreator(OnlineStoreCreator): + """OnlineStoreCreator backed by ``MongoDBAtlasLocalContainer``. + + This uses the ``mongodb/mongodb-atlas-local`` Docker image which provides + a local Atlas deployment with support for Atlas Search and Vector Search. + """ + + def __init__(self, project_name: str, **kwargs): + super().__init__(project_name) + self.container = MongoDBAtlasLocalContainer( + "mongodb/mongodb-atlas-local:8.0.4", + ) + + def create_online_store(self) -> Dict[str, Any]: + self.container.start() + connection_string = self.container.get_connection_url() + return { + "type": "mongodb", + "connection_string": connection_string, + "vector_enabled": True, + } + + def teardown(self): + self.container.stop() diff --git a/sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py b/sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py index c1ebdf6c984..fa6978b259a 100644 --- a/sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py +++ b/sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py @@ -11,7 +11,7 @@ class MySQLOnlineStoreCreator(OnlineStoreCreator): def __init__(self, project_name: str, **kwargs): super().__init__(project_name) self.container = ( - MySqlContainer("mysql:latest", platform="linux/amd64") + MySqlContainer("mysql:latest", platform="linux/amd64", dialect="pymysql") .with_exposed_ports(3306) .with_env("MYSQL_USER", "root") .with_env("MYSQL_PASSWORD", "test") @@ -37,7 +37,7 @@ class BatchWriteMySQLOnlineStoreCreator(OnlineStoreCreator): def __init__(self, project_name: str, **kwargs): super().__init__(project_name) self.container = ( - MySqlContainer("mysql:latest", platform="linux/amd64") + MySqlContainer("mysql:latest", platform="linux/amd64", dialect="pymysql") .with_exposed_ports(3306) .with_env("MYSQL_USER", "root") .with_env("MYSQL_PASSWORD", "test") diff --git a/sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py b/sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py index a3f8d28ef19..0141232f12f 100644 --- a/sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py +++ b/sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py @@ -1,4 +1,5 @@ import os +import time from typing import Any, Dict from testcontainers.core.container import DockerContainer @@ -53,14 +54,18 @@ def __init__(self, project_name: str, **kwargs): def create_online_store(self) -> Dict[str, Any]: self.container.start() - log_string_to_wait_for = "database system is ready to accept connections" wait_for_logs( - container=self.container, predicate=log_string_to_wait_for, timeout=10 + container=self.container, + predicate="database system is ready to accept connections", + timeout=30, ) - init_log_string_to_wait_for = "PostgreSQL init process complete" wait_for_logs( - container=self.container, predicate=init_log_string_to_wait_for, timeout=10 + container=self.container, + predicate="PostgreSQL init process complete", + timeout=30, ) + # PG restarts after init completes; allow the restart to finish + time.sleep(3) return { "host": "localhost", "type": "postgres", @@ -69,6 +74,7 @@ def create_online_store(self) -> Dict[str, Any]: "database": "test", "vector_enabled": True, "port": self.container.get_exposed_port(5432), + "sslmode": "disable", } def teardown(self): diff --git a/sdk/python/tests/utils/cli_repo_creator.py b/sdk/python/tests/utils/cli_repo_creator.py index 3aa96768f61..25c3fdd1198 100644 --- a/sdk/python/tests/utils/cli_repo_creator.py +++ b/sdk/python/tests/utils/cli_repo_creator.py @@ -1,12 +1,22 @@ """ CLI test utilities for Feast testing. -Note: This module contains workarounds for a known PySpark JVM cleanup issue on macOS -with Python 3.11+. The 'feast teardown' command can hang indefinitely due to py4j -(PySpark's Java bridge) not properly terminating JVM processes. This is a PySpark -environmental issue, not a Feast logic error. - -The timeout handling ensures tests fail gracefully rather than hanging CI. +Note: This module contains a workaround for a known subprocess hang issue: + +Dask atexit handler: when a Feast materialization fails mid-execution, Dask's +global ThreadPoolExecutor registers an atexit.register(default_pool.shutdown) +handler. If the pool has active or recently-used threads, shutdown(wait=True) +can block for an extended period, preventing the subprocess from exiting. This +causes the parent's subprocess.check_output / communicate() to block forever. + +The fix is to use subprocess.Popen with communicate(timeout=...) so we can kill +the subprocess if it hangs and still recover any partial output (which contains +the error message printed before the hang). + +Teardown is intentionally performed in-process (store.teardown()) rather than +via a 'feast teardown' subprocess. This eliminates per-repo subprocess startup +overhead and avoids atexit-handler (Dask thread pool, PySpark JVM) hang risks +that can push the cumulative test time past the pytest global timeout budget. """ import random @@ -44,12 +54,9 @@ class CliRunner: """ def run(self, args: List[str], cwd: Path) -> subprocess.CompletedProcess: - # Handle known PySpark JVM cleanup issue on macOS - # The 'feast teardown' command can hang indefinitely on macOS with Python 3.11+ - # due to py4j (PySpark's Java bridge) not properly cleaning up JVM processes. - # This is a known environmental issue, not a test logic error. - # See: https://issues.apache.org/jira/browse/SPARK-XXXXX (PySpark JVM cleanup) - timeout = 120 if "teardown" in args else None + # Apply a conservative timeout to prevent CI hangs from Dask atexit-handler + # stalls or other subprocess blockages. + timeout = 120 try: return subprocess.run( @@ -59,41 +66,46 @@ def run(self, args: List[str], cwd: Path) -> subprocess.CompletedProcess: timeout=timeout, ) except subprocess.TimeoutExpired: - # For teardown timeouts, return a controlled failure rather than hanging CI. - # This allows the test to fail gracefully and continue with other tests. - if "teardown" in args: - return subprocess.CompletedProcess( - args=[sys.executable, cli.__file__] + args, - returncode=-1, - stdout=b"", - stderr=b"Teardown timed out (known PySpark JVM cleanup issue on macOS)", - ) - else: - # For non-teardown commands, re-raise as this indicates a real issue - raise + return subprocess.CompletedProcess( + args=[sys.executable, cli.__file__] + args, + returncode=-1, + stdout=b"", + stderr=f"Command timed out after {timeout}s: {args}".encode(), + ) def run_with_output(self, args: List[str], cwd: Path) -> Tuple[int, bytes]: - timeout = 120 if "teardown" in args else None + is_teardown = "teardown" in args + # Use subprocess.Popen + communicate(timeout=...) so that on a hang we can + # kill the process and still recover any output already buffered in the pipe. + # This matters when feast prints an error and then hangs in the Dask atexit + # handler — the error text is already in the pipe buffer and can be read after + # the process is killed. + timeout = 120 if is_teardown else 60 + + proc = subprocess.Popen( + [sys.executable, cli.__file__] + args, + cwd=cwd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) try: - return ( - 0, - subprocess.check_output( - [sys.executable, cli.__file__] + args, - cwd=cwd, - stderr=subprocess.STDOUT, - timeout=timeout, - ), - ) - except subprocess.CalledProcessError as e: - return e.returncode, e.output + stdout, _ = proc.communicate(timeout=timeout) + returncode = proc.returncode + if returncode != 0: + return returncode, stdout + return 0, stdout except subprocess.TimeoutExpired: - if "teardown" in args: + proc.kill() + stdout, _ = proc.communicate() + if is_teardown: return ( -1, b"Teardown timed out (known PySpark JVM cleanup issue on macOS)", ) else: - raise + # Return partial output (likely contains the error printed before hang) + # with a non-zero returncode so callers can inspect it. + return -1, stdout or b"" @contextmanager def local_repo( @@ -179,23 +191,13 @@ def local_repo( f"stdout: {result.stdout}\nstderr: {result.stderr}" ) - yield FeatureStore(repo_path=str(repo_path), config=None) + store_instance = FeatureStore(repo_path=str(repo_path), config=None) + yield store_instance if teardown: - result = self.run(["teardown"], cwd=repo_path) - stdout = result.stdout.decode("utf-8") - stderr = result.stderr.decode("utf-8") - print(f"Teardown stdout:\n{stdout}") - print(f"Teardown stderr:\n{stderr}") - - # Handle PySpark JVM cleanup timeout gracefully on macOS - # This is a known environmental issue, not a test failure - if result.returncode == -1 and "PySpark JVM cleanup issue" in stderr: - print( - "Warning: Teardown timed out due to known PySpark JVM cleanup issue on macOS" - ) - print("This is an environmental issue, not a test logic failure") - else: - assert result.returncode == 0, ( - f"stdout: {result.stdout}\nstderr: {result.stderr}" - ) + # Use in-process teardown instead of a 'feast teardown' subprocess. + # Subprocess teardown adds per-repo startup overhead and risks + # blocking indefinitely in Dask/PySpark atexit handlers, which + # can push the cumulative test time past the pytest timeout budget. + # store.teardown() performs the same SQLite/registry cleanup directly. + store_instance.teardown() diff --git a/sdk/python/tests/utils/rag_test_utils.py b/sdk/python/tests/utils/rag_test_utils.py index e3aac2546bd..675fa28b4a5 100644 --- a/sdk/python/tests/utils/rag_test_utils.py +++ b/sdk/python/tests/utils/rag_test_utils.py @@ -92,7 +92,9 @@ def run_side_effect(cmd, *args, **kwargs): with runner.local_repo( get_example_repo("example_feature_repo_1.py"), offline_store="file", - online_store="milvus", + # The vector store tests below use MockVectorStore and only need the + # feature view registered; avoid Milvus Lite index setup flakiness. + online_store="sqlite", apply=False, teardown=True, ) as store: diff --git a/sdk/python/tests/utils/ssl_certifcates_util.py b/sdk/python/tests/utils/ssl_certifcates_util.py index 53b9df3973c..4525e0249c9 100644 --- a/sdk/python/tests/utils/ssl_certifcates_util.py +++ b/sdk/python/tests/utils/ssl_certifcates_util.py @@ -15,6 +15,97 @@ logger = logging.getLogger(__name__) +def generate_mtls_certs( + output_dir: str, + server_san: str = "feature-registry.example.com", +) -> dict[str, str]: + """ + Generate a CA, server, and client certificate chain for mTLS testing. + + The server cert's SAN is set to ``server_san`` (no ``localhost``), so a + gRPC client connecting to ``localhost`` must set the ``authority`` channel + option to ``server_san`` — exactly the IAP-tunnel pattern. + + Returns a dict with keys: ca_cert, server_key, server_cert, + client_key, client_cert. + """ + os.makedirs(output_dir, exist_ok=True) + paths = { + "ca_cert": os.path.join(output_dir, "ca.crt"), + "server_key": os.path.join(output_dir, "server.key"), + "server_cert": os.path.join(output_dir, "server.crt"), + "client_key": os.path.join(output_dir, "client.key"), + "client_cert": os.path.join(output_dir, "client.crt"), + } + + # --- CA (self-signed) --- + ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + ca_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "TestCA")]) + ca_cert = ( + x509.CertificateBuilder() + .subject_name(ca_name) + .issuer_name(ca_name) + .public_key(ca_key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.utcnow()) + .not_valid_after(datetime.utcnow() + timedelta(days=1)) + .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) + .sign(ca_key, hashes.SHA256()) + ) + with open(paths["ca_cert"], "wb") as f: + f.write(ca_cert.public_bytes(serialization.Encoding.PEM)) + + def _issue_cert( + cn: str, + key_path: str, + cert_path: str, + san: x509.SubjectAlternativeName | None = None, + ): + key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)]) + builder = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(ca_cert.subject) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.utcnow()) + .not_valid_after(datetime.utcnow() + timedelta(days=1)) + ) + if san is not None: + builder = builder.add_extension(san, critical=False) + cert = builder.sign(ca_key, hashes.SHA256()) + + with open(key_path, "wb") as f: + f.write( + key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.NoEncryption(), + ) + ) + with open(cert_path, "wb") as f: + f.write(cert.public_bytes(serialization.Encoding.PEM)) + + # --- Server cert --- + _issue_cert( + cn=server_san, + key_path=paths["server_key"], + cert_path=paths["server_cert"], + san=x509.SubjectAlternativeName([x509.DNSName(server_san)]), + ) + + # --- Client cert (no SAN needed) --- + _issue_cert( + cn="TestClient", + key_path=paths["client_key"], + cert_path=paths["client_cert"], + ) + + logger.info(f"mTLS certificates generated in {output_dir}") + return paths + + def generate_self_signed_cert( cert_path="cert.pem", key_path="key.pem", common_name="localhost" ): diff --git a/skills/SKILL.md b/skills/SKILL.md new file mode 100644 index 00000000000..8be173257ac --- /dev/null +++ b/skills/SKILL.md @@ -0,0 +1,253 @@ +--- +name: feast-user-guide +description: Guide for working with Feast (Feature Store) — defining features, configuring feature_store.yaml, retrieving features online/offline, using the CLI, and building RAG retrieval pipelines. Use when the user asks about creating entities, feature views, on-demand feature views, stream feature views, feature services, data sources, feature_store.yaml configuration, feast apply/materialize commands, online or historical feature retrieval, or vector-based document retrieval with Feast. +license: Apache-2.0 +compatibility: Works with Claude Code, OpenAI Codex, and any Agent Skills compatible tool. +metadata: + author: feast-dev + version: "1.0" +--- + +# Feast User Guide + +## Quick Start + +A Feast project requires: +1. A `feature_store.yaml` config file +2. Python files defining entities, data sources, feature views, and feature services +3. Running `feast apply` to register definitions + +```bash +feast init my_project +cd my_project +feast apply +``` + +## Core Concepts + +### Entity +An entity is a collection of semantically related features (e.g., a customer, a driver). Entities have join keys used to look up features. + +```python +from feast import Entity +from feast.value_type import ValueType + +driver = Entity( + name="driver_id", + description="Driver identifier", + value_type=ValueType.INT64, +) +``` + +### Data Sources +Data sources describe where raw feature data lives. + +```python +from feast import FileSource, BigQuerySource, KafkaSource, PushSource, RequestSource +from feast.data_format import ParquetFormat + +# Batch source (file) +driver_stats_source = FileSource( + name="driver_stats_source", + path="data/driver_stats.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created", +) + +# Request source (for on-demand features) +input_request = RequestSource( + name="vals_to_add", + schema=[Field(name="val_to_add", dtype=Float64)], +) +``` + +### FeatureView +Maps features from a data source to entities with a schema, TTL, and online/offline settings. + +```python +from feast import FeatureView, Field +from feast.types import Float32, Int64, String +from datetime import timedelta + +driver_hourly_stats = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=365), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + ], + online=True, + source=driver_stats_source, +) +``` + +### OnDemandFeatureView +Computes features at request time from other feature views and/or request data. + +```python +from feast import on_demand_feature_view +import pandas as pd + +@on_demand_feature_view( + sources=[driver_hourly_stats, input_request], + schema=[Field(name="conv_rate_plus_val", dtype=Float64)], + mode="pandas", +) +def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: + df = pd.DataFrame() + df["conv_rate_plus_val"] = inputs["conv_rate"] + inputs["val_to_add"] + return df +``` + +### FeatureService +Groups features from multiple views for retrieval. + +```python +from feast import FeatureService + +driver_fs = FeatureService( + name="driver_ranking", + features=[driver_hourly_stats, transformed_conv_rate], +) +``` + +## Feature Retrieval + +### Online (low-latency) +```python +from feast import FeatureStore + +store = FeatureStore(repo_path=".") + +features = store.get_online_features( + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + ], + entity_rows=[{"driver_id": 1001}, {"driver_id": 1002}], +).to_dict() +``` + +### Historical (training data with point-in-time joins) +```python +entity_df = pd.DataFrame({ + "driver_id": [1001, 1002], + "event_timestamp": [datetime(2023, 1, 1), datetime(2023, 1, 2)], +}) + +training_df = store.get_historical_features( + entity_df=entity_df, + features=["driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate"], +).to_df() +``` + +Or use a FeatureService: +```python +training_df = store.get_historical_features( + entity_df=entity_df, + features=driver_fs, +).to_df() +``` + +## Materialization + +Load features from offline store into online store: + +```bash +# Full materialization over a time range +feast materialize 2023-01-01T00:00:00 2023-12-31T23:59:59 + +# Incremental (from last materialized timestamp) +feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S") +``` + +Python API: +```python +from datetime import datetime +store.materialize(start_date=datetime(2023, 1, 1), end_date=datetime(2023, 12, 31)) +store.materialize_incremental(end_date=datetime.utcnow()) +``` + +## CLI Commands + +| Command | Purpose | +|---------|---------| +| `feast init [DIR]` | Create new feature repository | +| `feast apply` | Register/update feature definitions | +| `feast plan` | Preview changes without applying | +| `feast materialize START END` | Materialize features to online store | +| `feast materialize-incremental END` | Incremental materialization | +| `feast entities list` | List registered entities | +| `feast feature-views list` | List feature views | +| `feast feature-services list` | List feature services | +| `feast on-demand-feature-views list` | List on-demand feature views | +| `feast teardown` | Remove infrastructure resources | +| `feast version` | Show SDK version | + +Options: `--chdir` / `-c` (run in different directory), `--feature-store-yaml` / `-f` (override config path). + +## Vector Search / RAG + +Define a feature view with vector fields for similarity search: + +```python +from feast.types import Array, Float32 + +wiki_passages = FeatureView( + name="wiki_passages", + entities=[passage_entity], + schema=[ + Field(name="passage_text", dtype=String), + Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=384, + vector_search_metric="COSINE", + ), + ], + source=passages_source, + online=True, +) +``` + +Retrieve similar documents: +```python +results = store.retrieve_online_documents( + feature="wiki_passages:embedding", + query=query_embedding, + top_k=5, +) +``` + +## feature_store.yaml Minimal Config + +```yaml +project: my_project +registry: data/registry.db +provider: local +online_store: + type: sqlite + path: data/online_store.db +``` + +## Common Imports + +```python +from feast import ( + Entity, FeatureView, OnDemandFeatureView, FeatureService, + Field, FileSource, RequestSource, FeatureStore, +) +from feast.on_demand_feature_view import on_demand_feature_view +from feast.types import Float32, Float64, Int64, String, Bool, Array +from feast.value_type import ValueType +from datetime import timedelta +``` + +## Detailed References + +- **Feature definitions** (all types, parameters, patterns): See [references/feature-definitions.md](references/feature-definitions.md) +- **Configuration** (feature_store.yaml, all store types, auth): See [references/configuration.md](references/configuration.md) +- **Retrieval & RAG** (online/offline retrieval, vector search, RAG retriever): See [references/retrieval-and-rag.md](references/retrieval-and-rag.md) diff --git a/skills/feast-architecture/SKILL.md b/skills/feast-architecture/SKILL.md new file mode 100644 index 00000000000..a2132983d61 --- /dev/null +++ b/skills/feast-architecture/SKILL.md @@ -0,0 +1,378 @@ +--- +name: feast-architecture +description: Internals of the Feast codebase — how each component works, where the key abstractions live, and the data flow through the system. Use when asked how feast apply works, how the registry stores data, how materialization moves data, how get_online_features retrieves features, how the feature server works, how the Kubernetes operator manages deployments, or when navigating the codebase to understand where to make a change. +license: Apache-2.0 +compatibility: Works with Claude Code, OpenAI Codex, and any Agent Skills compatible tool. +metadata: + author: feast-dev + version: "1.0" +--- + +# Feast Architecture Internals + +## Full Component Map + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Feast Deployment Modes │ +│ │ +│ Local / Python SDK Kubernetes (feast-operator) │ +│ ───────────────── ───────────────────────────────── │ +│ feature_store.yaml ←── FeatureStore CR (CRD) │ +│ │ │ │ +│ ▼ ▼ │ +│ FeatureStore (Python) Operator deploys services: │ +│ ├── Registry - feature-server (Go or Python) │ +│ ├── Provider - offline-store-server │ +│ │ ├── OnlineStore - registry-server │ +│ │ └── OfflineStore + manages feature_store.yaml config │ +│ └── FeatureServer │ +│ (Python FastAPI or │ +│ Go gRPC/HTTP) │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Python SDK Core + +### FeatureStore — the orchestrator + +**File**: `sdk/python/feast/feature_store.py` + +`FeatureStore` is the single entry point for all operations. It never reads/writes data +directly — it delegates to the registry (for metadata) and the provider (for infrastructure +and data movement). + +```python +FeatureStore(repo_path=".") # loads feature_store.yaml +store.apply(objects) # register feature definitions +store.materialize(...) # offline → online +store.get_online_features(...) # serve +store.get_historical_features(...) # training data +``` + +**File**: `sdk/python/feast/repo_config.py` — parses `feature_store.yaml` into typed `RepoConfig`. +All component classes (online store, offline store, registry) are loaded dynamically from the +`type:` string via `repo_config.ONLINE_STORE_TYPE_MAP` / `OFFLINE_STORE_TYPE_MAP`. + +--- + +### Registry + +**Purpose**: Metadata store — persists definitions of entities, feature views, data sources, +feature services, permissions. + +**Backends and their files:** + +| Backend | File | Notes | +|---|---|---| +| File/GCS/S3 (default) | `infra/registry/registry.py` | Single proto blob, cached in memory | +| SQL | `infra/registry/sql.py` | Per-object tables via SQLAlchemy | +| Snowflake | `infra/registry/snowflake.py` | Snowflake tables | +| Remote | `infra/registry/remote.py` | Delegates to a remote registry server over gRPC | + +**How the proto/file backend works:** +1. All metadata is serialized into one `Registry` protobuf (`protos/feast/core/Registry.proto`) +2. The proto blob is stored at the configured `registry:` path +3. In-memory `cached_registry_proto` is refreshed on a TTL (default 10s) +4. Writes re-serialize and overwrite the full blob — no partial updates + +**Key pattern — apply:** +```python +# Python object → proto → stored in registry blob +registry.apply_feature_view(feature_view, project) +# → feature_view.to_proto() +# → upserts into cached_registry_proto.feature_views +# → registry_store.update_registry_proto(proto) +``` + +**Supporting files:** +- `infra/registry/base_registry.py` — abstract interface +- `infra/registry/proto_registry_utils.py` — proto serialization helpers +- `infra/registry/caching_registry.py` — adds TTL caching on top of any backend + +--- + +### Provider + +**Purpose**: Infrastructure lifecycle — creates/updates/tears down online store tables. +Also dispatches `online_write_batch` and `get_historical_features`. + +**File**: `sdk/python/feast/infra/provider.py` + +Built-in providers (set via `provider:` in `feature_store.yaml`): +- `local` — SQLite online store, file offline (dev default) +- `gcp` — Datastore/Bigtable online, BigQuery offline +- `aws` — DynamoDB online, Redshift offline + +Custom providers extend `Provider` and override `update_infra` / `teardown_infra`. + +--- + +### Online Store + +**Purpose**: Low-latency feature serving. Stores the latest feature values per entity key. + +**Interface**: `sdk/python/feast/infra/online_stores/online_store.py` +**Implementations**: `sdk/python/feast/infra/online_stores/` (redis, dynamodb, sqlite, bigtable, postgres, snowflake, …) + +Key methods: +- `online_write_batch` — write entity→feature values +- `online_read` — read by entity keys +- `update` — provision/deprovision tables on `feast apply` +- `teardown` — clean up on `feast teardown` + +--- + +### Offline Store + +**Purpose**: Historical feature retrieval and training data generation (point-in-time joins). + +**Interface**: `sdk/python/feast/infra/offline_stores/offline_store.py` +**Implementations**: `sdk/python/feast/infra/offline_stores/` (bigquery, snowflake, redshift, duckdb, file, …) + +Returns a `RetrievalJob` (lazy) — no data moves until `.to_df()` or `.to_arrow()` is called. + +PIT join logic (shared): `sdk/python/feast/infra/offline_stores/offline_utils.py` + +**Key methods to implement for a new backend:** +```python +class MyOfflineStore(OfflineStore): + def get_historical_features(self, config, feature_views, feature_refs, + entity_df, registry, project, ...) -> RetrievalJob: ... + def pull_latest_from_table_or_query(self, config, data_source, + join_key_columns, feature_name_columns, + timestamp_field, created_timestamp_column, + start_date, end_date) -> RetrievalJob: ... + def pull_all_from_table_or_query(self, config, data_source, join_key_columns, + feature_name_columns, timestamp_field, + start_date, end_date) -> RetrievalJob: ... + def write_logged_features(self, config, data, source, logging_config, + registry) -> None: ... # optional +``` + +**Config class**: subclass `FeastConfigBaseModel` with a `type` Literal (short alias + full dotted path). Register in `OFFLINE_STORE_TYPE_MAP` in `sdk/python/feast/repo_config.py`. + +**Data source**: each offline store backend pairs with a `DataSource` subclass (e.g. `BigQuerySource`, `FileSource`). Add it to `sdk/python/feast/data_sources/` and register in `DATA_SOURCE_CLASS_FOR_TYPE`. + +--- + +## Data Flows + +### `feast apply` +``` +feast apply (CLI → repo_operations.py) + ├── Parse Python files → collect FeastObjects + ├── store.apply(objects) + │ ├── diff against registry (diff/registry_diff.py) + │ ├── update registry metadata for changed objects + │ └── provider.update_infra(tables_to_keep, tables_to_delete) + │ └── online_store.update(...) ← create/drop tables + └── Write updated registry to storage +``` + +### `feast materialize` +``` +store.materialize(start_date, end_date) + ├── Load feature views from registry + ├── For each feature view: + │ ├── offline_store.pull_latest_from_table_or_query(...) + │ │ └── Returns RetrievalJob (lazy) + │ ├── job.to_arrow() ← executes query, fetches Arrow table + │ └── provider.online_write_batch(...) + │ └── online_store.online_write_batch(config, table, data, progress) + └── Update last_updated_timestamp in registry +``` + +### `get_online_features` +``` +store.get_online_features(features, entity_rows) + ├── Resolve feature refs → FeatureViews from registry + ├── online_store.online_read(config, table, entity_rows, requested_features) + │ └── Deserialize ValueProto → Python dict + ├── Apply OnDemandFeatureView transformations (if any) + └── Return OnlineFeaturesResponse +``` + +### `get_historical_features` +``` +store.get_historical_features(entity_df, features) + ├── Resolve feature refs → FeatureViews from registry + ├── offline_store.get_historical_features(config, feature_views, entity_df) + │ └── Point-in-time join: + │ for each entity row, find latest values where + │ event_timestamp ≤ entity_df.event_timestamp + │ (prevents data leakage in training) + └── Returns RetrievalJob → .to_df() / .to_arrow() +``` + +--- + +## Feature Servers + +### Python Feature Server (FastAPI) + +**File**: `sdk/python/feast/feature_server.py` + +A FastAPI app that wraps `FeatureStore`. Started with `feast serve`. + +Endpoints: +- `POST /get-online-features` — online feature retrieval +- `POST /push` — push features to online/offline store +- `POST /materialize` — trigger materialization +- `GET /health` — health check + +The app loads `feature_store.yaml` at startup, creates a `FeatureStore`, and periodically +refreshes the registry in the background (async timer). + +### Go Feature Server + +**Directory**: `go/` +**Entry point**: `go/main.go` + +A high-performance alternative to the Python feature server, written in Go. +Supports HTTP, HTTPS, and gRPC transports: + +```bash +go run go/main.go -type http -port 6566 +go run go/main.go -type grpc -port 6566 +``` + +Key packages: +- `go/internal/feast/` — Go port of FeatureStore (reads feature_store.yaml, calls online store) +- `go/internal/feast/server/` — HTTP and gRPC server implementations +- `go/internal/feast/server/logging/` — feature logging to offline store + +The Go server reads the registry directly (proto file or remote) and calls the online store. +It does not support `feast apply` or materialization — those remain Python-only. + +--- + +## Feast Operator (Kubernetes) + +**Directory**: `infra/feast-operator/` +**Language**: Go (controller-runtime / kubebuilder) + +The operator manages the full lifecycle of a Feast deployment on Kubernetes via a +`FeatureStore` Custom Resource Definition (CRD). + +### CRD: FeatureStore + +**API version**: `feast.dev/v1` +**File**: `infra/feast-operator/api/v1/featurestore_types.go` + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: my-feast +spec: + feastProjectName: my_project + services: + offlineStore: + persistence: + file: + type: dask + onlineStore: + persistence: + store: + type: redis + secretRef: + name: redis-credentials + registry: + local: + persistence: + file: + path: /data/registry.db +``` + +### What the operator manages + +| Service | What it deploys | +|---|---| +| **Online Store server** | Deployment + Service for the feature server (Go or Python) | +| **Offline Store server** | Deployment + Service for the offline feature server | +| **Registry server** | Deployment + Service for the registry gRPC server | +| **feature_store.yaml** | ConfigMap auto-generated from the CR spec | +| **Materialization jobs** | CronJob (`spec.services.onlineStore.cronJob`) | +| **TLS** | Certificate management via `spec.services.*.tls` | +| **Auth** | OIDC / Kubernetes RBAC via `spec.authz` | + +### Reconcile loop + +**File**: `infra/feast-operator/internal/controller/featurestore_controller.go` + +The `FeatureStoreReconciler.Reconcile` method runs on every CR change: +1. Fetches the `FeatureStore` CR +2. Calls `deployFeast()` → creates/updates Deployments, Services, ConfigMaps +3. Updates CR status conditions (`OfflineStore`, `OnlineStore`, `Registry` ready conditions) +4. Watches owned resources; re-reconciles on any change + +Supporting services logic: `infra/feast-operator/internal/controller/services/` + +--- + +## Serialization Layer + +All persistent metadata and the feature server wire format use **Protocol Buffers**. + +``` +Python object (FeatureView, Entity, ...) + ├── .to_proto() → Protobuf message → stored in registry or sent over gRPC + └── .from_proto() ← Protobuf message + +Proto definitions: + protos/feast/core/ # registry objects (FeatureView, Entity, DataSource, …) + protos/feast/serving/ # serving API (GetOnlineFeaturesRequest/Response) + protos/feast/types/ # Value, EntityKey, Field +``` + +When adding a new field to a Feast object: +1. Update the `.proto` file +2. Run `make compile-protos-python` (and `make compile-protos-go` if applicable) +3. Update `.to_proto()` and `.from_proto()` in the Python class + +--- + +## Key Files Quick Reference + +| Concern | Key file(s) | +|---|---| +| User-facing Python API | `sdk/python/feast/feature_store.py` | +| Config parsing | `sdk/python/feast/repo_config.py` | +| `feast apply` CLI logic | `sdk/python/feast/repo_operations.py` | +| Registry diff | `sdk/python/feast/diff/registry_diff.py` | +| Registry (proto/file) | `sdk/python/feast/infra/registry/registry.py` | +| Registry (SQL) | `sdk/python/feast/infra/registry/sql.py` | +| PIT join | `sdk/python/feast/infra/offline_stores/offline_utils.py` | +| Online store interface | `sdk/python/feast/infra/online_stores/online_store.py` | +| Entity key serialization | `sdk/python/feast/infra/online_stores/helpers.py` | +| Python feature server | `sdk/python/feast/feature_server.py` | +| Go feature server | `go/main.go`, `go/internal/feast/server/` | +| Operator CRD types | `infra/feast-operator/api/v1/featurestore_types.go` | +| Operator controller | `infra/feast-operator/internal/controller/featurestore_controller.go` | +| Operator services | `infra/feast-operator/internal/controller/services/` | +| Proto definitions | `protos/feast/` | +| Web UI | `ui/` (React) | + +--- + +## Official Architecture Documentation + +The `docs/` directory contains user-facing architecture documentation that complements this skill: + +| Topic | Doc | +|---|---| +| Architecture overview | `docs/getting-started/architecture/overview.md` | +| Push vs pull model | `docs/getting-started/architecture/push-vs-pull-model.md` | +| Write patterns | `docs/getting-started/architecture/write-patterns.md` | +| Feature transformation | `docs/getting-started/architecture/feature-transformation.md` | +| RBAC / authorization | `docs/getting-started/architecture/rbac.md` | +| Online store component | `docs/getting-started/components/online-store.md` | +| Offline store component | `docs/getting-started/components/offline-store.md` | +| Registry component | `docs/getting-started/components/registry.md` | +| Feature server component | `docs/getting-started/components/feature-server.md` | +| Provider component | `docs/getting-started/components/provider.md` | +| Compute engine | `docs/getting-started/components/compute-engine.md` | +| ADRs (design decisions) | `docs/adr/` | diff --git a/skills/feast-dev/SKILL.md b/skills/feast-dev/SKILL.md new file mode 100644 index 00000000000..b3e0c27c5a2 --- /dev/null +++ b/skills/feast-dev/SKILL.md @@ -0,0 +1,142 @@ +--- +name: feast-dev +description: Development guide for contributing to the Feast codebase. Covers environment setup, testing, linting, project structure, and PR workflow for feast-dev/feast. +license: Apache-2.0 +compatibility: Works with Claude Code, OpenAI Codex, and any Agent Skills compatible tool. Requires Python 3.10+, uv, and git. +metadata: + author: feast-dev + version: "1.0" +--- + +# Feast Development Guide + +## Environment Setup + +```bash +# Install development dependencies (uses uv pip sync with pinned requirements) +make install-python-dependencies-dev + +# Install minimal dependencies +make install-python-dependencies-minimal + +# Install pre-commit hooks (runs formatters and linters on commit) +make install-precommit +``` + +## Running Tests + +### Unit Tests +```bash +# Run all unit tests +make test-python-unit + +# Run a specific test file +python -m pytest sdk/python/tests/unit/test_unit_feature_store.py -v + +# Run a specific test by name +python -m pytest sdk/python/tests/unit/test_unit_feature_store.py -k "test_apply" -v + +# Run fast unit tests only (no external dependencies) +make test-python-unit-fast +``` + +### Integration Tests (local) +```bash +# Run integration tests in local dev mode +make test-python-integration-local +``` + +## Linting and Formatting + +```bash +# Format Python code +make format-python + +# Lint Python code +make lint-python + +# Run all precommit checks (format + lint) +make precommit-check + +# Type checking (entire codebase) +uv run bash -c "cd sdk/python && mypy feast" + +# Type-check a single file +uv run bash -c "cd sdk/python && mypy feast/path/to/file.py" +``` + +## Code Style + +- Use type hints on all function signatures +- Use `from __future__ import annotations` at the top of new files +- Follow existing patterns in the module you are modifying +- PR titles must follow semantic conventions: `feat:`, `fix:`, `ci:`, `chore:`, `docs:` +- Add a GitHub label to PRs (e.g. `kind/bug`, `kind/feature`, `kind/housekeeping`) +- Sign off commits with `git commit -s` (DCO requirement) + +## Docker Images + +```bash +# Build all Docker images +make build-docker + +# Build feature server Docker image +make build-feature-server-docker +``` + +## Documentation + +```bash +# Build Sphinx documentation +make build-sphinx + +# Build templates +make build-templates + +# Build Helm docs +make build-helm-docs +``` + +## Documentation and Blog Posts + +- **Blog posts must be placed in `/infra/website/docs/blog/`** — do NOT place them under `docs/blog/` or elsewhere. +- Blog post files must include YAML frontmatter with `title`, `description`, `date`, and `authors` fields matching the format of existing posts in that directory. +- All other docs go under `docs/` and **must be added to `docs/SUMMARY.md`** (GitBook navigation) or they won't appear on the website. + +| Change type | Doc location | +|---|---| +| New online store | `docs/reference/online-stores/.md` + update `README.md` and `SUMMARY.md` | +| New offline store | `docs/reference/offline-stores/.md` + update `README.md`, `overview.md`, `SUMMARY.md` | +| New registry backend | `docs/reference/registries/.md` + update `SUMMARY.md` | +| Config option | `docs/reference/feature-store-yaml.md` | +| CLI flag/command | `docs/reference/feast-cli-commands.md` | +| How-to / integration | `docs/how-to-guides/customizing-feast/` or `docs/how-to-guides/` + update `SUMMARY.md` | +| Architecture / concept | `docs/getting-started/architecture/` or `docs/getting-started/components/` | + +## Project Structure + +``` +sdk/python/feast/ # Main Python SDK + cli/cli.py # CLI entry point (feast apply, feast materialize, etc.) + feature_store.py # FeatureStore class - core orchestration + repo_config.py # feature_store.yaml configuration parsing + repo_operations.py # feast apply / feast teardown logic + infra/ # Online/offline store implementations + online_stores/ # Redis, DynamoDB, SQLite, etc. + offline_stores/ # BigQuery, Snowflake, File, etc. + transformation/ # On-demand and streaming transformations +protos/feast/ # Protobuf definitions +sdk/python/tests/ # Test suite + unit/ # Fast, no external deps + integration/ # Requires infrastructure +``` + +## Key Abstractions + +- **FeatureStore** (`feature_store.py`): Entry point for all operations +- **FeatureView**: Defines a set of features from a data source +- **OnDemandFeatureView**: Computed features using request-time transformations +- **Entity**: Join key definition (e.g. driver_id, customer_id) +- **DataSource**: Where raw data lives (BigQuery, files, Snowflake, etc.) +- **OnlineStore**: Low-latency feature serving (Redis, DynamoDB, SQLite) +- **OfflineStore**: Historical feature retrieval (BigQuery, Snowflake, file) diff --git a/skills/feast-testing/SKILL.md b/skills/feast-testing/SKILL.md new file mode 100644 index 00000000000..5d778a9a33e --- /dev/null +++ b/skills/feast-testing/SKILL.md @@ -0,0 +1,246 @@ +--- +name: feast-testing +description: How to test and debug Feast — running targeted tests, writing unit tests for new components, debugging registry and online store issues, and inspecting live feature store state. Use when writing tests for a new feature, debugging a failing test, investigating a runtime error, or verifying that a change works correctly end-to-end. +license: Apache-2.0 +compatibility: Works with Claude Code, OpenAI Codex, and any Agent Skills compatible tool. +metadata: + author: feast-dev + version: "1.0" +--- + +# Testing and Debugging Feast + +## Test Organization + +``` +sdk/python/tests/ +├── unit/ # Fast tests, no external deps, run locally +│ ├── infra/ +│ │ ├── online_store/ # Per-store unit tests (redis, dynamodb, etc.) +│ │ ├── offline_stores/ # Offline store unit tests +│ │ └── registry/ # Registry unit tests +│ ├── test_unit_feature_store.py # Core FeatureStore behavior +│ ├── test_feature_views.py # Feature view validation +│ └── test_on_demand_*.py # On-demand transformation tests +└── integration/ # Requires real infrastructure (run in CI) + ├── feature_repos/ # Sample repos used as test fixtures + └── test_universal_*.py # Cross-store compatibility tests +``` + +**Rule of thumb**: if a test needs mocks for an external service, it belongs in `unit/`. +If it spins up real infra (Redis, DynamoDB, BigQuery), it belongs in `integration/`. + +--- + +## Running Tests + +### Targeted unit tests + +```bash +# Run a single test file +python -m pytest sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py -v + +# Run a single test by name +python -m pytest sdk/python/tests/unit/test_unit_feature_store.py -k "test_apply" -v + +# Run all unit tests for one subsystem +python -m pytest sdk/python/tests/unit/infra/online_store/ -v + +# Run all unit tests (fast, no infra needed) +make test-python-unit +``` + +### Integration tests (local) + +```bash +# Run local integration tests (SQLite online, file offline) +make test-python-integration-local + +# Run specific integration test with verbose output +python -m pytest sdk/python/tests/integration/ -k "test_online_retrieval" -v -s +``` + +### Running a single test file fast (skip slow markers) + +```bash +python -m pytest sdk/python/tests/unit/infra/online_store/test_redis.py -v --no-header -q +``` + +--- + +## Writing Unit Tests for a New Component + +### Pattern: testing an online store + +Follow `sdk/python/tests/unit/infra/online_store/test_dynamodb_online_store.py` or `test_redis.py`. + +```python +import asyncio +from unittest.mock import AsyncMock, MagicMock, patch +from feast.infra.online_stores.mystore import MyStore, MyStoreConfig +from feast.repo_config import RepoConfig + +def make_config(store_config: dict) -> RepoConfig: + return RepoConfig( + project="test_project", + registry="data/registry.db", + provider="local", + online_store=store_config, + ) + +@patch("feast.infra.online_stores.mystore.MyClient") +def test_online_write_batch(mock_client_cls): + mock_client = MagicMock() + mock_client_cls.return_value = mock_client + + config = make_config({"type": "mystore", "host": "localhost"}) + store = MyStore() + feature_view = MagicMock() + feature_view.name = "driver_stats" + + store.online_write_batch(config, feature_view, data=[...], progress=None) + + mock_client.set.assert_called_once() + +# For async methods: +def test_online_write_batch_async(): + async def _run(): + store = MyStore() + await store.online_write_batch_async(config, feature_view, data, progress=None) + asyncio.run(_run()) +``` + +### Pattern: testing registry operations + +Follow `sdk/python/tests/unit/infra/registry/test_registry.py`. + +```python +from feast.infra.registry.registry import Registry +from feast.repo_config import RegistryConfig + +def test_apply_feature_view(tmp_path): + config = RegistryConfig(path=str(tmp_path / "registry.db")) + registry = Registry("test_project", config, repo_path=None) + + entity = Entity(name="driver_id", value_type=ValueType.INT64) + registry.apply_entity(entity, project="test_project") + + stored = registry.get_entity("driver_id", project="test_project") + assert stored.name == "driver_id" +``` + +### Pattern: testing FeatureStore end-to-end (unit level) + +```python +from feast import FeatureStore +from feast.repo_config import RepoConfig + +def test_get_online_features(tmp_path): + config = RepoConfig( + project="test", + registry=str(tmp_path / "registry.db"), + provider="local", + online_store={"type": "sqlite", "path": str(tmp_path / "online.db")}, + offline_store={"type": "file"}, + ) + store = FeatureStore(config=config) + # apply objects, write data, then assert retrieval +``` + +--- + +## Debugging Common Issues + +### Registry out of sync / stale metadata + +```bash +# Inspect the live registry +feast registry-dump # prints full proto as JSON + +# Or from Python: +from feast import FeatureStore +store = FeatureStore(repo_path=".") +store.registry.list_feature_views(project=store.project) +store.registry.list_entities(project=store.project) +``` + +**Symptom**: `FeatureView not found` or stale feature definitions. +**Fix**: Re-run `feast apply`. If using a cached registry (TTL > 0), wait for cache expiry or force refresh by restarting the process. + +### Online store returns None for all features + +```bash +# Check if materialization has run +feast feature-views list # shows last_updated_timestamp + +# Check entity key format +# Entity keys are serialized — if the serialization_version doesn't match, lookups fail. +# Check entity_key_serialization_version in feature_store.yaml +``` + +**Symptom**: `get_online_features` returns all `None` values despite materialization running. +**Cause**: Entity key serialization version mismatch, wrong project name, or wrong TTL causing data to expire. + +### Type errors from mypy + +```bash +# Type-check only the file you changed +uv run bash -c "cd sdk/python && mypy feast/infra/online_stores/mystore.py" + +# Common fix: add Optional[] around return types, use cast() for dynamic lookups +``` + +### Test imports fail / module not found + +```bash +# Ensure you're running from repo root with dev dependencies installed +make install-python-dependencies-dev + +# Run with uv to use the pinned venv +uv run python -m pytest sdk/python/tests/unit/... -v +``` + +### Protobuf deserialization errors + +**Symptom**: `DecodeError` or unexpected field values when reading registry. +**Cause**: Proto schema changed without recompiling. +**Fix**: +```bash +make compile-protos-python +``` + +### Feature server returns 500 + +```bash +# Start the feature server locally and check logs +feast serve --host 0.0.0.0 --port 6566 + +# Test directly +curl -X POST http://localhost:6566/get-online-features \ + -H "Content-Type: application/json" \ + -d '{"features": ["driver_stats:conv_rate"], "entities": {"driver_id": [1001]}}' +``` + +--- + +## Useful CLI Commands for Inspection + +```bash +feast entities list # list all registered entities +feast feature-views list # list feature views + last materialization time +feast feature-services list # list feature services +feast on-demand-feature-views list # list ODFVs +feast registry-dump # dump full registry as JSON (debug) +feast plan # preview what feast apply would change (dry run) +``` + +--- + +## Test Utilities + +| Utility | Location | Purpose | +|---|---|---| +| `get_feature_view()` helpers | `tests/unit/infra/online_store/test_*.py` | Build minimal FeatureView mocks | +| `LocalRegistry` fixture | `tests/unit/infra/registry/test_registry.py` | In-memory registry for unit tests | +| `integration/feature_repos/` | `tests/integration/` | Sample repos for integration test scenarios | +| `conftest.py` fixtures | Various `tests/` subdirs | Shared pytest fixtures per subsystem | diff --git a/skills/feast-user-guide/SKILL.md b/skills/feast-user-guide/SKILL.md new file mode 100644 index 00000000000..0210ee00b42 --- /dev/null +++ b/skills/feast-user-guide/SKILL.md @@ -0,0 +1,253 @@ +--- +name: feast-user-guide +description: Guide for working with Feast (Feature Store) — defining features, configuring feature_store.yaml, retrieving features online/offline, using the CLI, and building RAG retrieval pipelines. Use when the user asks about creating entities, feature views, on-demand feature views, stream feature views, feature services, data sources, feature_store.yaml configuration, feast apply/materialize commands, online or historical feature retrieval, or vector-based document retrieval with Feast. +license: Apache-2.0 +compatibility: Works with Claude Code, OpenAI Codex, and any Agent Skills compatible tool. +metadata: + author: feast-dev + version: "1.0" +--- + +# Feast User Guide + +## Quick Start + +A Feast project requires: +1. A `feature_store.yaml` config file +2. Python files defining entities, data sources, feature views, and feature services +3. Running `feast apply` to register definitions + +```bash +feast init my_project +cd my_project +feast apply +``` + +## Core Concepts + +### Entity +An entity is a collection of semantically related features (e.g., a customer, a driver). Entities have join keys used to look up features. + +```python +from feast import Entity +from feast.value_type import ValueType + +driver = Entity( + name="driver_id", + description="Driver identifier", + value_type=ValueType.INT64, +) +``` + +### Data Sources +Data sources describe where raw feature data lives. + +```python +from feast import FileSource, BigQuerySource, KafkaSource, PushSource, RequestSource +from feast.data_format import ParquetFormat + +# Batch source (file) +driver_stats_source = FileSource( + name="driver_stats_source", + path="data/driver_stats.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created", +) + +# Request source (for on-demand features) +input_request = RequestSource( + name="vals_to_add", + schema=[Field(name="val_to_add", dtype=Float64)], +) +``` + +### FeatureView +Maps features from a data source to entities with a schema, TTL, and online/offline settings. + +```python +from feast import FeatureView, Field +from feast.types import Float32, Int64, String +from datetime import timedelta + +driver_hourly_stats = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=365), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + ], + online=True, + source=driver_stats_source, +) +``` + +### OnDemandFeatureView +Computes features at request time from other feature views and/or request data. + +```python +from feast import on_demand_feature_view +import pandas as pd + +@on_demand_feature_view( + sources=[driver_hourly_stats, input_request], + schema=[Field(name="conv_rate_plus_val", dtype=Float64)], + mode="pandas", +) +def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: + df = pd.DataFrame() + df["conv_rate_plus_val"] = inputs["conv_rate"] + inputs["val_to_add"] + return df +``` + +### FeatureService +Groups features from multiple views for retrieval. + +```python +from feast import FeatureService + +driver_fs = FeatureService( + name="driver_ranking", + features=[driver_hourly_stats, transformed_conv_rate], +) +``` + +## Feature Retrieval + +### Online (low-latency) +```python +from feast import FeatureStore + +store = FeatureStore(repo_path=".") + +features = store.get_online_features( + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + ], + entity_rows=[{"driver_id": 1001}, {"driver_id": 1002}], +).to_dict() +``` + +### Historical (training data with point-in-time joins) +```python +entity_df = pd.DataFrame({ + "driver_id": [1001, 1002], + "event_timestamp": [datetime(2023, 1, 1), datetime(2023, 1, 2)], +}) + +training_df = store.get_historical_features( + entity_df=entity_df, + features=["driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate"], +).to_df() +``` + +Or use a FeatureService: +```python +training_df = store.get_historical_features( + entity_df=entity_df, + features=driver_fs, +).to_df() +``` + +## Materialization + +Load features from offline store into online store: + +```bash +# Full materialization over a time range +feast materialize 2023-01-01T00:00:00 2023-12-31T23:59:59 + +# Incremental (from last materialized timestamp) +feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S") +``` + +Python API: +```python +from datetime import datetime +store.materialize(start_date=datetime(2023, 1, 1), end_date=datetime(2023, 12, 31)) +store.materialize_incremental(end_date=datetime.utcnow()) +``` + +## CLI Commands + +| Command | Purpose | +|---------|---------| +| `feast init [DIR]` | Create new feature repository | +| `feast apply` | Register/update feature definitions | +| `feast plan` | Preview changes without applying | +| `feast materialize START END` | Materialize features to online store | +| `feast materialize-incremental END` | Incremental materialization | +| `feast entities list` | List registered entities | +| `feast feature-views list` | List feature views | +| `feast feature-services list` | List feature services | +| `feast on-demand-feature-views list` | List on-demand feature views | +| `feast teardown` | Remove infrastructure resources | +| `feast version` | Show SDK version | + +Options: `--chdir` / `-c` (run in different directory), `--feature-store-yaml` / `-f` (override config path). + +## Vector Search / RAG + +Define a feature view with vector fields for similarity search: + +```python +from feast.types import Array, Float32 + +wiki_passages = FeatureView( + name="wiki_passages", + entities=[passage_entity], + schema=[ + Field(name="passage_text", dtype=String), + Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=384, + vector_search_metric="COSINE", + ), + ], + source=passages_source, + online=True, +) +``` + +Retrieve similar documents: +```python +results = store.retrieve_online_documents( + feature="wiki_passages:embedding", + query=query_embedding, + top_k=5, +) +``` + +## feature_store.yaml Minimal Config + +```yaml +project: my_project +registry: data/registry.db +provider: local +online_store: + type: sqlite + path: data/online_store.db +``` + +## Common Imports + +```python +from feast import ( + Entity, FeatureView, OnDemandFeatureView, FeatureService, + Field, FileSource, RequestSource, FeatureStore, +) +from feast.on_demand_feature_view import on_demand_feature_view +from feast.types import Float32, Float64, Int64, String, Bool, Array +from feast.value_type import ValueType +from datetime import timedelta +``` + +## Detailed References + +- **Feature definitions** (all types, parameters, patterns): See [references/feature-definitions.md](../references/feature-definitions.md) +- **Configuration** (feature_store.yaml, all store types, auth): See [references/configuration.md](../references/configuration.md) +- **Retrieval & RAG** (online/offline retrieval, vector search, RAG retriever): See [references/retrieval-and-rag.md](../references/retrieval-and-rag.md) diff --git a/skills/references/configuration.md b/skills/references/configuration.md new file mode 100644 index 00000000000..7a63b8429bd --- /dev/null +++ b/skills/references/configuration.md @@ -0,0 +1,284 @@ +# Configuration Reference + +## Table of Contents +- [feature_store.yaml](#feature_storeyaml) +- [RepoConfig Fields](#repoconfig-fields) +- [Registry Configuration](#registry-configuration) +- [Online Store Types](#online-store-types) +- [Offline Store Types](#offline-store-types) +- [Batch Engine Types](#batch-engine-types) +- [Authentication](#authentication) +- [Feature Server](#feature-server) +- [Materialization Config](#materialization-config) +- [OpenLineage Config](#openlineage-config) +- [Feature Repository Layout](#feature-repository-layout) + +## feature_store.yaml + +Minimal local config: +```yaml +project: my_project +registry: data/registry.db +provider: local +online_store: + type: sqlite + path: data/online_store.db +``` + +GCP config: +```yaml +project: my_project +registry: gs://my-bucket/registry.pb +provider: gcp +online_store: + type: datastore +offline_store: + type: bigquery +``` + +AWS config: +```yaml +project: my_project +registry: s3://my-bucket/registry.pb +provider: aws +online_store: + type: dynamodb + region: us-east-1 +offline_store: + type: redshift + cluster_id: my-cluster + region: us-east-1 + database: feast + user: admin + s3_staging_location: s3://my-bucket/feast-staging +``` + +## RepoConfig Fields + +| Field | Alias | Type | Default | Description | +|-------|-------|------|---------|-------------| +| `project` | - | str | required | Project namespace (alphanumeric + underscores) | +| `project_description` | - | str | None | Project description | +| `provider` | - | str | `"local"` | `"local"`, `"gcp"`, or `"aws"` | +| `registry` | `registry_config` | str/dict | required | Registry path or config object | +| `online_store` | `online_config` | str/dict | `"sqlite"` | Online store type or config | +| `offline_store` | `offline_config` | str/dict | `"dask"` | Offline store type or config | +| `batch_engine` | `batch_engine_config` | str/dict | `"local"` | Batch materialization engine | +| `auth` | - | dict | no_auth | Authentication config | +| `feature_server` | - | dict | None | Feature server config | +| `entity_key_serialization_version` | - | int | 3 | Entity key serialization version | +| `coerce_tz_aware` | - | bool | True | Coerce timestamps to timezone-aware | +| `materialization` | `materialization_config` | dict | default | Materialization options | +| `openlineage` | `openlineage_config` | dict | None | OpenLineage config | + +## Registry Configuration + +| Field | Default | Description | +|-------|---------|-------------| +| `registry_type` | `"file"` | `"file"`, `"sql"`, `"snowflake.registry"`, `"remote"` | +| `path` | `""` | Local path, GCS/S3 URI (file), or DB connection URL (sql) | +| `cache_ttl_seconds` | 600 | Registry cache TTL (0 = no expiry) | +| `cache_mode` | `"sync"` | `"sync"` or `"thread"` | +| `s3_additional_kwargs` | None | Extra boto3 kwargs for S3 | + +### File registry +```yaml +registry: data/registry.db +``` +or +```yaml +registry: + registry_type: file + path: data/registry.db + cache_ttl_seconds: 60 +``` + +### SQL registry +```yaml +registry: + registry_type: sql + path: postgresql://user:pass@host:5432/feast # pragma: allowlist secret + cache_ttl_seconds: 60 +``` + +### Remote registry +```yaml +registry: + registry_type: remote + path: grpc://feast-registry-server:6570 +``` + +## Online Store Types + +| Type | Config Key | Use Case | +|------|-----------|----------| +| `sqlite` | `path` | Local development | +| `redis` | `connection_string` | Production, low-latency | +| `dynamodb` | `region` | AWS-native | +| `datastore` | `project_id` | GCP-native | +| `bigtable` | `project_id`, `instance` | GCP, high-throughput | +| `postgres` | `host`, `port`, `database`, `user`, `password` | Self-managed | +| `snowflake.online` | `account`, `database`, `schema` | Snowflake ecosystem | +| `milvus` | `host`, `port` | Vector search | +| `qdrant` | `host`, `port` | Vector search | +| `remote` | `path` | Remote feature server | + +### Examples + +```yaml +# SQLite (local dev) +online_store: + type: sqlite + path: data/online_store.db + +# Redis +online_store: + type: redis + connection_string: redis://localhost:6379 + +# PostgreSQL +online_store: + type: postgres + host: localhost + port: 5432 + database: feast + db_schema: public + user: postgres + password: secret + +# Milvus (vector search) +online_store: + type: milvus + host: localhost + port: 19530 +``` + +## Offline Store Types + +| Type | Use Case | +|------|----------| +| `dask` | Local development (default) | +| `duckdb` | Local, fast analytics | +| `bigquery` | GCP | +| `snowflake.offline` | Snowflake | +| `redshift` | AWS | +| `spark` | Large-scale processing | +| `postgres` | Self-managed | +| `trino` | Federated queries | +| `athena` | AWS serverless | +| `clickhouse` | Analytics | +| `remote` | Remote offline server | + +### Examples + +```yaml +# DuckDB +offline_store: + type: duckdb + +# BigQuery +offline_store: + type: bigquery + project_id: my-gcp-project + dataset: feast_dataset + +# Snowflake +offline_store: + type: snowflake.offline + account: my_account + user: user + password: pass + database: FEAST + schema: PUBLIC + warehouse: COMPUTE_WH + +# Spark +offline_store: + type: spark + spark_conf: + spark.master: "local[*]" +``` + +## Batch Engine Types + +| Type | Description | +|------|-------------| +| `local` | Local Python process (default) | +| `snowflake.engine` | Snowflake-based materialization | +| `spark.engine` | Spark-based materialization | +| `lambda` | AWS Lambda-based | +| `k8s` | Kubernetes job-based | +| `ray.engine` | Ray-based | + +```yaml +batch_engine: + type: local +``` + +## Authentication + +| Type | Description | +|------|-------------| +| `no_auth` | No authentication (default) | +| `kubernetes` | Kubernetes service account | +| `oidc` | OpenID Connect (server-side) | +| `oidc_client` | OpenID Connect (client-side) | + +```yaml +# OIDC example +auth: + type: oidc + client_id: feast-client + auth_server_url: https://auth.example.com + auth_discovery_url: https://auth.example.com/.well-known/openid-configuration +``` + +## Feature Server + +```yaml +feature_server: + type: local +``` + +MCP-based feature server: +```yaml +feature_server: + type: mcp +``` + +## Materialization Config + +```yaml +materialization: + pull_latest_features: false # Only pull latest feature values per entity +``` + +## OpenLineage Config + +```yaml +openlineage: + enabled: true + transport_type: http # http, console, file, kafka (omit to use OpenLineage SDK defaults) + transport_url: http://marquez:5000 + transport_endpoint: api/v1/lineage + namespace: feast + emit_on_apply: true + emit_on_materialize: true +``` + +## Feature Repository Layout + +``` +my_feature_repo/ +├── feature_store.yaml # Required config +├── .feastignore # Optional gitignore-style file +├── driver_features.py # Feature definitions +├── customer_features.py # More definitions +└── data/ + ├── driver_stats.parquet # Data files (for FileSource) + └── registry.db # Auto-generated registry +``` + +- Feast recursively scans all `.py` files for feature definitions +- Use `.feastignore` to exclude files/directories from scanning +- `feast apply` registers all discovered definitions into the registry diff --git a/skills/references/feature-definitions.md b/skills/references/feature-definitions.md new file mode 100644 index 00000000000..d9040e089c0 --- /dev/null +++ b/skills/references/feature-definitions.md @@ -0,0 +1,350 @@ +# Feature Definitions Reference + +## Table of Contents +- [Entity](#entity) +- [Field](#field) +- [Data Sources](#data-sources) +- [FeatureView](#featureview) +- [OnDemandFeatureView](#ondemandfeatureview) +- [StreamFeatureView](#streamfeatureview) +- [FeatureService](#featureservice) +- [Aggregation](#aggregation) + +## Entity + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Unique entity name | +| `join_keys` | List[str] | `[name]` | Join keys for lookup (only one supported) | +| `value_type` | ValueType | - | Deprecated; use `join_keys` instead | +| `description` | str | `""` | Human-readable description | +| `tags` | Dict[str,str] | `{}` | Metadata tags | +| `owner` | str | `""` | Owner/maintainer | + +```python +from feast import Entity +from feast.value_type import ValueType + +driver = Entity(name="driver_id", description="Driver identifier") +customer = Entity(name="customer_id", join_keys=["customer_id"]) +``` + +## Field + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Field name | +| `dtype` | FeastType | required | Data type | +| `description` | str | `""` | Description | +| `vector_index` | bool | False | Enable vector similarity search | +| `vector_length` | int | - | Vector dimension (required if `vector_index=True`) | +| `vector_search_metric` | str | - | `"COSINE"`, `"L2"`, `"INNER_PRODUCT"` | + +### Type System + +**Scalar types** (from `feast.types`): `Float32`, `Float64`, `Int32`, `Int64`, `String`, `Bool`, `Bytes`, `UnixTimestamp`, `ZonedTimestamp` + +**Collection types**: `Array(T)` where T is a scalar type (e.g., `Array(Float32)` for embeddings) + +**ValueType enum** (legacy, from `feast.value_type`): `STRING`, `INT32`, `INT64`, `FLOAT`, `DOUBLE`, `BOOL`, `BYTES`, `UNIX_TIMESTAMP`; plus `_LIST` and `_SET` variants. + +**Python → Feast mapping**: `int` → INT64, `str` → STRING, `float` → DOUBLE, `bytes` → BYTES, `bool` → BOOL, `datetime` → UNIX_TIMESTAMP + +### Vector field example + +```python +Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=384, + vector_search_metric="COSINE", +) +``` + +## Data Sources + +### Batch Sources + +**FileSource**: +```python +from feast import FileSource + +source = FileSource( + name="driver_stats", + path="data/driver_stats.parquet", + timestamp_field="event_timestamp", + created_timestamp_column="created", +) +``` + +**BigQuerySource**: +```python +from feast.infra.offline_stores.contrib.bigquery_offline_store.bigquery_source import BigQuerySource + +source = BigQuerySource( + name="driver_stats_bq", + table="project.dataset.driver_stats", + timestamp_field="event_timestamp", +) +``` + +Other batch sources: `SnowflakeSource`, `RedshiftSource`, `PostgreSQLSource`, `SparkSource`, `TrinoSource`, `AthenaSource`, `ClickhouseSource` + +### Stream Sources + +**KafkaSource**: +```python +from feast.data_source import KafkaSource + +source = KafkaSource( + name="driver_trips_stream", + kafka_bootstrap_servers="broker:9092", + topic="driver_trips", + timestamp_field="event_timestamp", + batch_source=file_source, # for backfill + message_format=AvroFormat(schema_json=schema), +) +``` + +**KinesisSource**: `region`, `stream_name`, `record_format`, `batch_source` + +**PushSource** (for manual push via SDK): +```python +from feast.data_source import PushSource + +push_source = PushSource(name="driver_push", batch_source=file_source) +``` + +### RequestSource (for OnDemandFeatureView) + +```python +from feast import RequestSource, Field +from feast.types import Float64 + +input_request = RequestSource( + name="vals_to_add", + schema=[Field(name="val_to_add", dtype=Float64)], +) +``` + +## FeatureView + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Unique name | +| `source` | DataSource | required | Batch or stream data source | +| `entities` | List[Entity] | `[]` | Associated entities | +| `schema` | List[Field] | `[]` | Feature schema (can be inferred from source) | +| `ttl` | timedelta | `timedelta(0)` | Time-to-live for features | +| `online` | bool | `True` | Available for online retrieval | +| `offline` | bool | `False` | Available for offline retrieval | +| `description` | str | `""` | Description | +| `tags` | Dict[str,str] | `{}` | Metadata | +| `owner` | str | `""` | Owner | +| `mode` | str | - | Transformation mode: `"python"`, `"pandas"`, `"sql"`, `"spark"`, `"ray"`, `"substrait"` | + +```python +from feast import FeatureView, Field +from feast.types import Float32, Int64 +from datetime import timedelta + +driver_hourly_stats = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=365), + schema=[ + Field(name="conv_rate", dtype=Float32), + Field(name="acc_rate", dtype=Float32), + Field(name="avg_daily_trips", dtype=Int64), + ], + online=True, + source=driver_stats_source, +) +``` + +## OnDemandFeatureView + +Features computed at request time from other feature views and/or request data. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Unique name | +| `sources` | List | required | Input FeatureViews and/or RequestSources | +| `schema` | List[Field] | required | Output schema | +| `mode` | str | `"pandas"` | `"pandas"` or `"python"` | +| `singleton` | bool | `False` | Single-row dict input (mode="python" only) | +| `write_to_online_store` | bool | `False` | Precompute on write instead of read | +| `aggregations` | List[Aggregation] | `[]` | Pre-transformation aggregations | + +### Pandas mode (default) + +```python +@on_demand_feature_view( + sources=[driver_hourly_stats, input_request], + schema=[Field(name="conv_rate_plus_val", dtype=Float64)], + mode="pandas", +) +def transformed_conv_rate(inputs: pd.DataFrame) -> pd.DataFrame: + df = pd.DataFrame() + df["conv_rate_plus_val"] = inputs["conv_rate"] + inputs["val_to_add"] + return df +``` + +### Python mode + +```python +@on_demand_feature_view( + sources=[driver_hourly_stats], + schema=[Field(name="conv_rate_category", dtype=String)], + mode="python", +) +def categorize_conv_rate(inputs: dict) -> dict: + output = {"conv_rate_category": []} + for rate in inputs["conv_rate"]: + output["conv_rate_category"].append("high" if rate > 0.5 else "low") + return output +``` + +### Python singleton mode + +```python +@on_demand_feature_view( + sources=[driver_hourly_stats], + schema=[Field(name="conv_rate_category", dtype=String)], + mode="python", + singleton=True, +) +def categorize_conv_rate(inputs: dict) -> dict: + rate = inputs["conv_rate"] + return {"conv_rate_category": "high" if rate > 0.5 else "low"} +``` + +### Write-to-online-store mode + +```python +@on_demand_feature_view( + sources=[push_source], + schema=[Field(name="trips_today_category", dtype=String)], + write_to_online_store=True, +) +def categorize_trips(inputs: pd.DataFrame) -> pd.DataFrame: + df = pd.DataFrame() + df["trips_today_category"] = inputs["trips_today"].apply( + lambda x: "high" if x > 10 else "low" + ) + return df +``` + +### Aggregation-based ODFV + +```python +from feast.aggregation import Aggregation + +@on_demand_feature_view( + sources=[driver_hourly_stats], + schema=[Field(name="sum_trips", dtype=Int64)], + aggregations=[Aggregation(column="avg_daily_trips", function="sum")], +) +def agg_view(inputs: pd.DataFrame) -> pd.DataFrame: + return inputs +``` + +### Validation note + +Use `feast apply --skip-feature-view-validation` if ODFV validation fails with complex logic (validation uses random inputs). + +## StreamFeatureView + +Extends FeatureView for stream sources (Kafka, Kinesis, PushSource). + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Unique name | +| `source` | DataSource | required | KafkaSource, KinesisSource, or PushSource | +| `entities` | List[Entity] | `[]` | Entities | +| `schema` | List[Field] | `[]` | Schema | +| `ttl` | timedelta | `timedelta(0)` | TTL | +| `aggregations` | List[Aggregation] | `[]` | Windowed aggregations | +| `timestamp_field` | str | - | Required if using aggregations | +| `udf` | function | - | Transformation function | +| `mode` | str | - | `"python"`, `"pandas"`, `"spark"`, `"spark_sql"` | + +```python +from feast import StreamFeatureView, Field +from feast.types import Int64 +from feast.aggregation import Aggregation +from datetime import timedelta + +driver_stream = StreamFeatureView( + name="driver_trips_stream", + entities=[driver], + source=kafka_source, + schema=[Field(name="trips", dtype=Int64)], + ttl=timedelta(hours=2), + aggregations=[ + Aggregation(column="trips", function="count", time_window=timedelta(hours=1)), + ], + timestamp_field="event_timestamp", +) +``` + +## FeatureService + +Groups features from one or more feature views for retrieval. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `name` | str | required | Unique name | +| `features` | List | required | Feature views or projections | +| `description` | str | `""` | Description | +| `tags` | Dict[str,str] | `{}` | Metadata | +| `owner` | str | `""` | Owner | +| `logging_config` | LoggingConfig | - | Logging configuration | + +```python +from feast import FeatureService + +driver_activity_service = FeatureService( + name="driver_activity", + features=[ + driver_hourly_stats, + transformed_conv_rate, + ], + description="Features for driver activity model", +) +``` + +### Feature projections (select specific features) + +```python +driver_fs = FeatureService( + name="driver_ranking", + features=[ + driver_hourly_stats[["conv_rate", "acc_rate"]], + ], +) +``` + +## Aggregation + +For StreamFeatureView windowed aggregations. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `column` | str | Source column name | +| `function` | str | `"sum"`, `"max"`, `"min"`, `"count"`, `"mean"` | +| `time_window` | timedelta | Aggregation window | +| `slide_interval` | timedelta | Slide interval (for sliding windows) | + +```python +from feast.aggregation import Aggregation +from datetime import timedelta + +agg = Aggregation( + column="trips", + function="count", + time_window=timedelta(hours=1), + slide_interval=timedelta(minutes=5), +) +``` diff --git a/skills/references/retrieval-and-rag.md b/skills/references/retrieval-and-rag.md new file mode 100644 index 00000000000..8198134e5bc --- /dev/null +++ b/skills/references/retrieval-and-rag.md @@ -0,0 +1,287 @@ +# Retrieval & RAG Reference + +## Table of Contents +- [FeatureStore Construction](#featurestore-construction) +- [Online Feature Retrieval](#online-feature-retrieval) +- [Historical Feature Retrieval](#historical-feature-retrieval) +- [Push and Write Operations](#push-and-write-operations) +- [Vector Similarity Search](#vector-similarity-search) +- [RAG Retriever](#rag-retriever) +- [FeatureStore API Quick Reference](#featurestore-api-quick-reference) + +## FeatureStore Construction + +```python +from feast import FeatureStore + +# From repo path (looks for feature_store.yaml) +store = FeatureStore(repo_path="path/to/feature_repo") + +# From config object +from feast.repo_config import RepoConfig +store = FeatureStore(config=RepoConfig( + project="my_project", + registry="data/registry.db", + provider="local", + online_store={"type": "sqlite", "path": "data/online.db"}, +)) + +# From explicit YAML path +from pathlib import Path +store = FeatureStore(fs_yaml_file=Path("custom/feature_store.yaml")) +``` + +## Online Feature Retrieval + +Low-latency lookup from the online store. Features must be materialized first. + +### By feature references +```python +result = store.get_online_features( + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "driver_hourly_stats:avg_daily_trips", + ], + entity_rows=[ + {"driver_id": 1001}, + {"driver_id": 1002}, + ], +) + +feature_dict = result.to_dict() +feature_df = result.to_df() +``` + +### By FeatureService +```python +result = store.get_online_features( + features=driver_ranking_service, + entity_rows=[{"driver_id": 1001}], +) +``` + +### Feature reference format +`"feature_view_name:feature_name"` — e.g., `"driver_hourly_stats:conv_rate"` + +## Historical Feature Retrieval + +Point-in-time correct joins for training data. Prevents data leakage by joining features based on event timestamps. + +### Basic usage +```python +import pandas as pd +from datetime import datetime + +entity_df = pd.DataFrame({ + "driver_id": [1001, 1002, 1003], + "event_timestamp": [ + datetime(2023, 6, 1), + datetime(2023, 6, 15), + datetime(2023, 7, 1), + ], +}) + +training_df = store.get_historical_features( + entity_df=entity_df, + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + ], +).to_df() +``` + +### With FeatureService +```python +training_df = store.get_historical_features( + entity_df=entity_df, + features=driver_ranking_service, +).to_df() +``` + +### Output +Returns a `RetrievalJob` with methods: +- `.to_df()` — pandas DataFrame +- `.to_arrow()` — PyArrow Table +- `.to_sql_string()` — SQL query (for SQL-based offline stores) + +## Push and Write Operations + +### Push (for PushSource/StreamFeatureView) +```python +store.push( + push_source_name="driver_push", + df=pd.DataFrame({ + "driver_id": [1001], + "trips_today": [15], + "event_timestamp": [datetime.utcnow()], + }), +) +``` + +### Write to online store +```python +store.write_to_online_store( + feature_view_name="driver_hourly_stats", + df=features_df, +) +``` + +### Write to offline store +```python +store.write_to_offline_store( + feature_view_name="driver_hourly_stats", + df=features_df, +) +``` + +## Vector Similarity Search + +Requires a FeatureView with a `vector_index=True` field and an online store that supports vector search (e.g., Milvus, Qdrant, PostgreSQL with pgvector). + +### Define vector feature view +```python +from feast import Entity, FeatureView, Field, FileSource +from feast.types import Array, Float32, String + +passage_entity = Entity(name="passage_id", join_keys=["passage_id"]) + +wiki_passages = FeatureView( + name="wiki_passages", + entities=[passage_entity], + schema=[ + Field(name="passage_text", dtype=String), + Field( + name="embedding", + dtype=Array(Float32), + vector_index=True, + vector_length=384, + vector_search_metric="COSINE", + ), + ], + source=passages_source, + online=True, +) +``` + +### Retrieve similar documents +```python +# v1 API +results = store.retrieve_online_documents( + feature="wiki_passages:embedding", + query=query_embedding_vector, + top_k=5, +) + +# v2 API (supports text, vector, and image queries) +results = store.retrieve_online_documents_v2( + feature_view_name="wiki_passages", + query_string="What is machine learning?", + top_k=5, +) +``` + +### Search metrics +- `"COSINE"` — Cosine similarity (default, best for normalized embeddings) +- `"L2"` — Euclidean distance +- `"INNER_PRODUCT"` — Dot product + +## RAG Retriever + +`FeastRAGRetriever` integrates Feast with HuggingFace for retrieval-augmented generation. + +### Prerequisites +- A FeatureView with a `vector_index=True` embedding field +- Features materialized to the online store +- HuggingFace `transformers` installed + +### Setup +```python +from feast.rag_retriever import FeastRAGRetriever +from transformers import AutoTokenizer, AutoModel, AutoModelForSeq2SeqLM + +question_tokenizer = AutoTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base") +question_encoder = AutoModel.from_pretrained("facebook/dpr-question_encoder-single-nq-base") +generator_tokenizer = AutoTokenizer.from_pretrained("facebook/bart-large") +generator_model = AutoModelForSeq2SeqLM.from_pretrained("facebook/bart-large") + +retriever = FeastRAGRetriever( + question_encoder_tokenizer=question_tokenizer, + question_encoder=question_encoder, + generator_tokenizer=generator_tokenizer, + generator_model=generator_model, + feast_repo_path="path/to/feature_repo", + feature_view="wiki_passages", + features=["passage_text", "embedding"], + search_type="vector", # "text", "vector", or "hybrid" + id_field="passage_id", + text_field="passage_text", +) +``` + +### Retrieve documents +```python +doc_embeddings, doc_ids, doc_dicts = retriever.retrieve( + question_input_ids=question_tokenizer("What is ML?", return_tensors="pt")["input_ids"], + n_docs=5, +) +``` + +### End-to-end answer generation +```python +answer = retriever.generate_answer( + query="What is machine learning?", + top_k=5, + max_new_tokens=200, +) +print(answer) +``` + +### FeastVectorStore (lower-level) + +```python +from feast.vector_store import FeastVectorStore + +vector_store = FeastVectorStore(feast_repo_path="path/to/feature_repo") + +results = vector_store.query( + query_vector=embedding_list, + top_k=10, +) +``` + +Supports `query_vector`, `query_string`, and `query_image_bytes` for different search modalities. + +## FeatureStore API Quick Reference + +| Method | Purpose | +|--------|---------| +| `apply(objects)` | Register entities, FVs, ODFVs, SFVs, services, sources | +| `plan(desired_registry)` | Preview apply changes | +| `get_online_features(features, entity_rows)` | Low-latency online lookup | +| `get_historical_features(entity_df, features)` | Point-in-time training data | +| `materialize(start_date, end_date)` | Load offline → online store | +| `materialize_incremental(end_date)` | Incremental materialization | +| `push(push_source_name, df)` | Push data to online/offline store | +| `write_to_online_store(fv_name, df)` | Direct write to online store | +| `write_to_offline_store(fv_name, df)` | Direct write to offline store | +| `retrieve_online_documents(feature, query, top_k)` | Vector similarity search | +| `retrieve_online_documents_v2(...)` | Vector search v2 (text/vector/image) | +| `list_entities()` | List all entities | +| `list_feature_views()` | List all feature views | +| `list_on_demand_feature_views()` | List on-demand feature views | +| `list_stream_feature_views()` | List stream feature views | +| `list_feature_services()` | List feature services | +| `list_data_sources()` | List data sources | +| `get_entity(name)` | Get entity by name | +| `get_feature_view(name)` | Get feature view by name | +| `get_feature_service(name)` | Get feature service by name | +| `delete_feature_view(name)` | Delete a feature view | +| `delete_feature_service(name)` | Delete a feature service | +| `create_saved_dataset(...)` | Save a dataset for reuse | +| `refresh_registry()` | Force refresh registry cache | +| `teardown()` | Remove all infrastructure resources | +| `serve(port)` | Start feature server | +| `serve_ui(port)` | Start Feast UI | +| `serve_registry(port)` | Start registry server | +| `serve_offline(port)` | Start offline server | diff --git a/ui/.prettierignore b/ui/.prettierignore index d2fa6a8b18e..14a40bc5836 100644 --- a/ui/.prettierignore +++ b/ui/.prettierignore @@ -1,3 +1,4 @@ *.css *.md dist/ +build/ diff --git a/ui/jest.config.js b/ui/jest.config.js index e7d01f6994a..26fa6f33333 100644 --- a/ui/jest.config.js +++ b/ui/jest.config.js @@ -1,4 +1,10 @@ -const transformNodeModules = ["@elastic/eui", "uuid", "msw", "until-async"]; +const transformNodeModules = [ + "@elastic/eui", + "uuid", + "msw", + "until-async", + "chroma-js", +]; module.exports = { roots: ["/src"], @@ -30,7 +36,7 @@ module.exports = { moduleNameMapper: { "^react-native$": "react-native-web", "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy", - "chroma-js": "/node_modules/chroma-js/dist/chroma.min.cjs", + "^chroma-js$": "/node_modules/chroma-js/dist/chroma.min.cjs", "^reactflow/dist/style\\.css$": "identity-obj-proxy", }, moduleFileExtensions: [ diff --git a/ui/package-lock.json b/ui/package-lock.json index 1c6ce720e02..2552b4367bc 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@feast-dev/feast-ui", - "version": "0.57.0", + "version": "0.63.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@feast-dev/feast-ui", - "version": "0.57.0", + "version": "0.63.0", "license": "Apache-2.0", "dependencies": { "@elastic/datemath": "^5.0.3", @@ -163,7 +163,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -860,7 +859,6 @@ "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1802,7 +1800,6 @@ "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", @@ -2753,7 +2750,6 @@ "resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.13.5.tgz", "integrity": "sha512-wQdD0Xhkn3Qy2VNcIzbLP9MR8TafI0MJb7BEAXKp+w4+XqErksWR4OXomuDzPsN4InLdGhVe6EYcn2ZIUCpB8w==", "license": "MIT", - "peer": true, "dependencies": { "@emotion/babel-plugin": "^11.13.5", "@emotion/cache": "^11.13.5", @@ -2794,7 +2790,6 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -4725,7 +4720,6 @@ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -4834,7 +4828,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -5524,7 +5517,6 @@ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -5632,7 +5624,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -5643,7 +5634,6 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -5833,7 +5823,6 @@ "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -5889,7 +5878,6 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -6289,7 +6277,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6387,7 +6374,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -7398,7 +7384,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -8677,7 +8662,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -9612,7 +9596,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -12242,7 +12225,6 @@ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", "devOptional": true, "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -13208,7 +13190,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -15825,7 +15806,6 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", - "peer": true, "engines": { "node": "*" } @@ -16735,7 +16715,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -17885,7 +17864,6 @@ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -18162,7 +18140,6 @@ "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "hasInstallScript": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -18556,7 +18533,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -18791,7 +18767,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -18977,7 +18952,6 @@ "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -19049,7 +19023,6 @@ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", "license": "MIT", - "peer": true, "dependencies": { "@remix-run/router": "1.23.1", "react-router": "6.30.2" @@ -19225,7 +19198,6 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -19685,7 +19657,6 @@ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -20207,7 +20178,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -21874,7 +21844,6 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -21989,7 +21958,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22591,7 +22559,6 @@ "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -22672,7 +22639,6 @@ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -23114,7 +23080,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", diff --git a/ui/package.json b/ui/package.json index d2d8814ca7f..8a254969e24 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.61.0", + "version": "0.64.0", "private": false, "files": [ "dist" diff --git a/ui/public/projects-list.json b/ui/public/projects-list.json index 238df4b5b41..4868adf6d88 100644 --- a/ui/public/projects-list.json +++ b/ui/public/projects-list.json @@ -3,7 +3,7 @@ { "name": "Credit Score Project", "description": "Project for credit scoring team and associated models.", - "id": "credit_score_project", + "id": "credit_scoring_aws", "registryPath": "/registry.db" }, { diff --git a/ui/public/registry.db b/ui/public/registry.db index ae9a05a4a97..0c16e405ccb 100644 Binary files a/ui/public/registry.db and b/ui/public/registry.db differ diff --git a/ui/src/FeastUISansProviders.test.tsx b/ui/src/FeastUISansProviders.test.tsx index cf4a01621de..f0a940e44b3 100644 --- a/ui/src/FeastUISansProviders.test.tsx +++ b/ui/src/FeastUISansProviders.test.tsx @@ -10,33 +10,17 @@ import { import userEvent from "@testing-library/user-event"; import FeastUISansProviders from "./FeastUISansProviders"; -import { - projectsListWithDefaultProject, - creditHistoryRegistry, - creditHistoryRegistryDB, -} from "./mocks/handlers"; +import { allRestHandlers } from "./mocks/handlers"; import { readFileSync } from "fs"; import { feast } from "./protos"; import path from "path"; // declare which API requests to mock -const server = setupServer( - projectsListWithDefaultProject, - creditHistoryRegistry, - creditHistoryRegistryDB, -); +const server = setupServer(...allRestHandlers); const registry = readFileSync(path.resolve(__dirname, "../public/registry.db")); const parsedRegistry = feast.core.Registry.decode(registry); -console.log("Registry Feature Views:", parsedRegistry.featureViews?.length); -if (parsedRegistry.featureViews && parsedRegistry.featureViews.length > 0) { - console.log( - "First Feature View Name:", - parsedRegistry.featureViews[0].spec?.name, - ); -} - // establish API mocking before all tests beforeAll(() => server.listen()); // reset any request handlers that are declared as a part of our tests @@ -64,14 +48,12 @@ test("full app rendering", async () => { // Explore Panel Should Appear expect(screen.getByText(/Explore this Project/i)).toBeInTheDocument(); - const projectNameRegExp = new RegExp( - parsedRegistry.projects[0].spec?.name!, - "i", - ); - // It should load the default project, which is credit_scoring_aws + // The heading shows the display name from projects-list.json await waitFor(() => { - expect(screen.getByText(projectNameRegExp)).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /Credit Score Project/i }), + ).toBeInTheDocument(); }); }); diff --git a/ui/src/FeastUISansProviders.tsx b/ui/src/FeastUISansProviders.tsx index 9a2207e22dd..ace29f9e856 100644 --- a/ui/src/FeastUISansProviders.tsx +++ b/ui/src/FeastUISansProviders.tsx @@ -22,14 +22,20 @@ import FeatureServiceInstance from "./pages/feature-services/FeatureServiceInsta import DataSourceInstance from "./pages/data-sources/DataSourceInstance"; import RootProjectSelectionPage from "./pages/RootProjectSelectionPage"; import DatasetInstance from "./pages/saved-data-sets/DatasetInstance"; -import DocumentLabelingPage from "./pages/document-labeling/DocumentLabelingPage"; +import LabelViewIndex from "./pages/label-views/Index"; +import LabelViewInstance from "./pages/label-views/LabelViewInstance"; import PermissionsIndex from "./pages/permissions/Index"; import LineageIndex from "./pages/lineage/Index"; import NoProjectGuard from "./components/NoProjectGuard"; +import MonitoringIndex from "./pages/monitoring/Index"; +import FeatureMetricsDetail from "./pages/monitoring/FeatureMetricsDetail"; import TabsRegistryContext, { FeastTabsRegistryInterface, } from "./custom-tabs/TabsRegistryContext"; +import MonitoringContext, { + MonitoringConfig, +} from "./contexts/MonitoringContext"; import CurlGeneratorTab from "./pages/feature-views/CurlGeneratorTab"; import FeatureFlagsContext, { FeatureFlags, @@ -38,11 +44,15 @@ import { ProjectListContext, ProjectsListContextInterface, } from "./contexts/ProjectListContext"; +import DataModeContext from "./contexts/DataModeContext"; +import type { DataModeConfig, FetchOptions } from "./contexts/DataModeContext"; interface FeastUIConfigs { tabsRegistry?: FeastTabsRegistryInterface; featureFlags?: FeatureFlags; projectListPromise?: Promise; + fetchOptions?: FetchOptions; + monitoringConfig?: MonitoringConfig; } const defaultProjectListPromise = (basename: string) => { @@ -95,95 +105,134 @@ const FeastUISansProvidersInner = ({ }) => { const { colorMode } = useTheme(); + const dataModeConfig: DataModeConfig = { + fetchOptions: feastUIConfigs?.fetchOptions, + }; + + const monitoringConfig: MonitoringConfig = + feastUIConfigs?.monitoringConfig || { + apiBaseUrl: "/api/v1", + enabled: true, + }; + return ( - - + - - - }> - } /> - }> - } /> - } /> - } - /> - } /> - } - /> - } - > - } - /> - } - /> - } - /> - } /> - } - /> - - } /> - } - /> - } - /> - } /> - } /> - - - } /> - - - - + + + + + }> + } /> + } + > + } /> + } + /> + } + /> + } /> + } + /> + } + > + } + /> + } + /> + } + /> + } /> + } + /> + } + /> + } + /> + } + /> + } /> + } + /> + } + /> + } /> + } + /> + } + /> + + + } /> + + + + + + ); diff --git a/ui/src/components/DataSourceFormModal.tsx b/ui/src/components/DataSourceFormModal.tsx new file mode 100644 index 00000000000..d9fa822d381 --- /dev/null +++ b/ui/src/components/DataSourceFormModal.tsx @@ -0,0 +1,572 @@ +import React, { useState, useEffect } from "react"; +import { + EuiFormRow, + EuiFieldText, + EuiSelect, + EuiSpacer, + EuiHorizontalRule, + EuiText, + EuiCallOut, +} from "@elastic/eui"; +import { feast } from "../protos"; +import FormModal from "./forms/FormModal"; +import TagsEditor, { TagEntry } from "./forms/TagsEditor"; +import NameDescriptionOwnerFields from "./forms/NameDescriptionOwnerFields"; + +const SOURCE_TYPE_OPTIONS = [ + { + value: String(feast.core.DataSource.SourceType.BATCH_FILE), + text: "File (Parquet / CSV)", + }, + { + value: String(feast.core.DataSource.SourceType.BATCH_BIGQUERY), + text: "BigQuery", + }, + { + value: String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE), + text: "Snowflake", + }, + { + value: String(feast.core.DataSource.SourceType.BATCH_REDSHIFT), + text: "Redshift", + }, + { + value: String(feast.core.DataSource.SourceType.STREAM_KAFKA), + text: "Kafka", + }, + { + value: String(feast.core.DataSource.SourceType.BATCH_SPARK), + text: "Spark", + }, + { + value: String(feast.core.DataSource.SourceType.REQUEST_SOURCE), + text: "Request Source", + }, + { + value: String(feast.core.DataSource.SourceType.PUSH_SOURCE), + text: "Push Source", + }, +]; + +interface DataSourceFormData { + name: string; + description: string; + owner: string; + sourceType: string; + timestampField: string; + createdTimestampColumn: string; + tags: TagEntry[]; + fileUri: string; + bigqueryTable: string; + bigqueryQuery: string; + snowflakeTable: string; + snowflakeDatabase: string; + snowflakeSchema: string; + redshiftTable: string; + redshiftDatabase: string; + redshiftSchema: string; + kafkaBootstrapServers: string; + kafkaTopic: string; + sparkTable: string; + sparkPath: string; +} + +interface DataSourceFormModalProps { + onClose: () => void; + onSubmit: (data: DataSourceFormData) => void; + initialData?: DataSourceFormData; + isEdit?: boolean; + isSubmitting?: boolean; + submitError?: string | null; +} + +const EMPTY_FORM: DataSourceFormData = { + name: "", + description: "", + owner: "", + sourceType: String(feast.core.DataSource.SourceType.BATCH_FILE), + timestampField: "", + createdTimestampColumn: "", + tags: [], + fileUri: "", + bigqueryTable: "", + bigqueryQuery: "", + snowflakeTable: "", + snowflakeDatabase: "", + snowflakeSchema: "", + redshiftTable: "", + redshiftDatabase: "", + redshiftSchema: "", + kafkaBootstrapServers: "", + kafkaTopic: "", + sparkTable: "", + sparkPath: "", +}; + +const BATCH_SOURCE_TYPES = new Set([ + String(feast.core.DataSource.SourceType.BATCH_FILE), + String(feast.core.DataSource.SourceType.BATCH_BIGQUERY), + String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE), + String(feast.core.DataSource.SourceType.BATCH_REDSHIFT), + String(feast.core.DataSource.SourceType.BATCH_SPARK), +]); + +const DataSourceFormModal: React.FC = ({ + onClose, + onSubmit, + initialData, + isEdit = false, + isSubmitting = false, + submitError, +}) => { + const [formData, setFormData] = useState( + initialData || EMPTY_FORM, + ); + const [errors, setErrors] = useState>({}); + const [submitted, setSubmitted] = useState(false); + + useEffect(() => { + if (initialData) { + setFormData(initialData); + } + }, [initialData]); + + const isBatchSource = BATCH_SOURCE_TYPES.has(formData.sourceType); + + const validate = (): boolean => { + const newErrors: Record = {}; + const st = formData.sourceType; + + if (!formData.name.trim()) { + newErrors.name = "Data source name is required."; + } else if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(formData.name)) { + newErrors.name = + "Must start with a letter or underscore, and contain only letters, numbers, and underscores."; + } + + // Source-type-specific required fields + if (st === String(feast.core.DataSource.SourceType.BATCH_FILE)) { + if (!formData.fileUri.trim()) { + newErrors.fileUri = "File URI is required."; + } else if ( + !/^(s3|gs|gcs|hdfs|abfs|file):\/\/\S+$/.test(formData.fileUri.trim()) + ) { + newErrors.fileUri = + "Must be a valid URI (e.g. s3://bucket/path, gs://bucket/path, file:///local/path)."; + } + } else if (st === String(feast.core.DataSource.SourceType.BATCH_BIGQUERY)) { + if (!formData.bigqueryTable.trim() && !formData.bigqueryQuery.trim()) { + newErrors.bigqueryTable = + "Either a table reference or a query is required."; + } + } else if ( + st === String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE) + ) { + if (!formData.snowflakeTable.trim()) { + newErrors.snowflakeTable = "Table name is required for Snowflake."; + } + if (!formData.snowflakeDatabase.trim()) { + newErrors.snowflakeDatabase = "Database is required for Snowflake."; + } + } else if (st === String(feast.core.DataSource.SourceType.BATCH_REDSHIFT)) { + if (!formData.redshiftTable.trim()) { + newErrors.redshiftTable = "Table name is required for Redshift."; + } + if (!formData.redshiftDatabase.trim()) { + newErrors.redshiftDatabase = "Database is required for Redshift."; + } + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SPARK)) { + if (!formData.sparkTable.trim() && !formData.sparkPath.trim()) { + newErrors.sparkTable = + "Either a table reference or a path is required for Spark."; + } + } else if (st === String(feast.core.DataSource.SourceType.STREAM_KAFKA)) { + if (!formData.kafkaBootstrapServers.trim()) { + newErrors.kafkaBootstrapServers = "Bootstrap servers are required."; + } else if ( + !/^[\w.-]+:\d+(,[\w.-]+:\d+)*$/.test( + formData.kafkaBootstrapServers.trim(), + ) + ) { + newErrors.kafkaBootstrapServers = + "Must be in host:port format (e.g. localhost:9092)."; + } + if (!formData.kafkaTopic.trim()) { + newErrors.kafkaTopic = "Topic is required."; + } + } + + // Timestamp field required for batch sources (needed for point-in-time correctness) + if (isBatchSource && !formData.timestampField.trim()) { + newErrors.timestampField = + "Timestamp field is required for batch sources. It is used for point-in-time correct feature retrieval."; + } else if ( + formData.timestampField.trim() && + !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(formData.timestampField.trim()) + ) { + newErrors.timestampField = + "Must be a valid column name (letters, numbers, underscores)."; + } + + const tagKeys = formData.tags.map((t) => t.key).filter((k) => k.trim()); + if (new Set(tagKeys).size !== tagKeys.length) { + newErrors.tags = "Tag keys must be unique."; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = () => { + setSubmitted(true); + if (validate()) { + const cleanedData = { + ...formData, + tags: formData.tags.filter((t) => t.key.trim()), + }; + onSubmit(cleanedData); + } + }; + + const updateField = ( + field: K, + value: DataSourceFormData[K], + ) => { + setFormData((prev) => ({ ...prev, [field]: value })); + if (submitted) { + setErrors((prev) => { + const next = { ...prev }; + delete next[field]; + return next; + }); + } + }; + + const renderSourceTypeFields = () => { + const st = formData.sourceType; + + if (st === String(feast.core.DataSource.SourceType.BATCH_FILE)) { + return ( + + updateField("fileUri", e.target.value)} + isInvalid={!!errors.fileUri} + placeholder="s3://bucket/path/to/data.parquet" + /> + + ); + } + + if (st === String(feast.core.DataSource.SourceType.BATCH_BIGQUERY)) { + return ( + <> + + updateField("bigqueryTable", e.target.value)} + isInvalid={!!errors.bigqueryTable} + placeholder="project:dataset.table" + /> + + + updateField("bigqueryQuery", e.target.value)} + placeholder="SELECT * FROM `project.dataset.table`" + /> + + + ); + } + + if (st === String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE)) { + return ( + <> + + updateField("snowflakeDatabase", e.target.value)} + isInvalid={!!errors.snowflakeDatabase} + placeholder="MY_DATABASE" + /> + + + updateField("snowflakeSchema", e.target.value)} + placeholder="PUBLIC" + /> + + + updateField("snowflakeTable", e.target.value)} + isInvalid={!!errors.snowflakeTable} + placeholder="MY_TABLE" + /> + + + ); + } + + if (st === String(feast.core.DataSource.SourceType.BATCH_REDSHIFT)) { + return ( + <> + + updateField("redshiftDatabase", e.target.value)} + isInvalid={!!errors.redshiftDatabase} + placeholder="my_database" + /> + + + updateField("redshiftSchema", e.target.value)} + placeholder="public" + /> + + + updateField("redshiftTable", e.target.value)} + isInvalid={!!errors.redshiftTable} + placeholder="my_table" + /> + + + ); + } + + if (st === String(feast.core.DataSource.SourceType.STREAM_KAFKA)) { + return ( + <> + + + updateField("kafkaBootstrapServers", e.target.value) + } + isInvalid={!!errors.kafkaBootstrapServers} + placeholder="broker1:9092,broker2:9092" + /> + + + updateField("kafkaTopic", e.target.value)} + isInvalid={!!errors.kafkaTopic} + placeholder="my-feature-topic" + /> + + + ); + } + + if (st === String(feast.core.DataSource.SourceType.BATCH_SPARK)) { + return ( + <> + + updateField("sparkTable", e.target.value)} + isInvalid={!!errors.sparkTable} + placeholder="catalog.database.table" + /> + + + updateField("sparkPath", e.target.value)} + placeholder="s3://bucket/path/" + /> + + + ); + } + + if ( + st === String(feast.core.DataSource.SourceType.REQUEST_SOURCE) || + st === String(feast.core.DataSource.SourceType.PUSH_SOURCE) + ) { + return ( + + No additional configuration required for this source type. + + ); + } + + return null; + }; + + return ( + + {submitError && ( + <> + +

{submitError}

+
+ + + )} + + updateField("name", v)} + onChangeDescription={(v) => updateField("description", v)} + onChangeOwner={(v) => updateField("owner", v)} + nameDisabled={isEdit} + nameError={errors.name} + nameHelpText="A unique name for this data source." + namePlaceholder="e.g. customer_transactions" + descriptionPlaceholder="Describe this data source..." + /> + + + { + updateField("sourceType", e.target.value); + // Clear source-specific errors when type changes + setErrors((prev) => { + const next = { ...prev }; + delete next.fileUri; + delete next.bigqueryTable; + delete next.snowflakeTable; + delete next.snowflakeDatabase; + delete next.redshiftTable; + delete next.redshiftDatabase; + delete next.kafkaBootstrapServers; + delete next.kafkaTopic; + delete next.sparkTable; + delete next.timestampField; + return next; + }); + }} + disabled={isEdit} + /> + + + + + +

Source Configuration

+
+ + + {renderSourceTypeFields()} + + {isBatchSource && ( + <> + + + updateField("timestampField", e.target.value)} + isInvalid={!!errors.timestampField} + placeholder="event_timestamp" + /> + + + + updateField("createdTimestampColumn", e.target.value) + } + placeholder="created_at" + /> + + + )} + + + + updateField("tags", tags)} + error={errors.tags} + /> +
+ ); +}; + +export default DataSourceFormModal; +export type { DataSourceFormData }; diff --git a/ui/src/components/EntityFormModal.tsx b/ui/src/components/EntityFormModal.tsx new file mode 100644 index 00000000000..0b64c71d668 --- /dev/null +++ b/ui/src/components/EntityFormModal.tsx @@ -0,0 +1,260 @@ +import React, { useState, useEffect } from "react"; +import { + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiFieldText, + EuiButtonEmpty, + EuiButtonIcon, + EuiText, + EuiHorizontalRule, + EuiCallOut, +} from "@elastic/eui"; +import { feast } from "../protos"; +import FormModal from "./forms/FormModal"; +import TagsEditor, { TagEntry } from "./forms/TagsEditor"; +import NameDescriptionOwnerFields from "./forms/NameDescriptionOwnerFields"; +import ValueTypeSelect from "./forms/ValueTypeSelect"; + +interface EntityFormData { + name: string; + description: string; + joinKeys: string[]; + valueType: string; + tags: TagEntry[]; +} + +interface EntityFormModalProps { + onClose: () => void; + onSubmit: (data: EntityFormData) => void; + initialData?: EntityFormData; + isEdit?: boolean; + isSubmitting?: boolean; + submitError?: string | null; +} + +const EMPTY_FORM: EntityFormData = { + name: "", + description: "", + joinKeys: [""], + valueType: String(feast.types.ValueType.Enum.STRING), + tags: [], +}; + +const EntityFormModal: React.FC = ({ + onClose, + onSubmit, + initialData, + isEdit = false, + isSubmitting = false, + submitError, +}) => { + const [formData, setFormData] = useState( + initialData || EMPTY_FORM, + ); + const [errors, setErrors] = useState>({}); + const [submitted, setSubmitted] = useState(false); + + useEffect(() => { + if (initialData) { + setFormData(initialData); + } + }, [initialData]); + + const validate = (): boolean => { + const newErrors: Record = {}; + + if (!formData.name.trim()) { + newErrors.name = "Entity name is required."; + } else if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(formData.name)) { + newErrors.name = + "Must start with a letter or underscore, and contain only letters, numbers, and underscores."; + } + + const nonEmptyKeys = formData.joinKeys.filter((k) => k.trim()); + if (nonEmptyKeys.length === 0) { + newErrors.joinKeys = "At least one join key is required."; + } else { + if (new Set(nonEmptyKeys).size !== nonEmptyKeys.length) { + newErrors.joinKeys = "Join keys must be unique."; + } + const invalidKey = nonEmptyKeys.find( + (k) => !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(k), + ); + if (invalidKey) { + newErrors.joinKeys = `Invalid join key "${invalidKey}". Use only letters, numbers, and underscores.`; + } + } + + const tagKeys = formData.tags.map((t) => t.key).filter((k) => k.trim()); + if (new Set(tagKeys).size !== tagKeys.length) { + newErrors.tags = "Tag keys must be unique."; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = () => { + setSubmitted(true); + if (validate()) { + const cleanedData = { + ...formData, + joinKeys: formData.joinKeys.filter((k) => k.trim()), + tags: formData.tags.filter((t) => t.key.trim()), + }; + onSubmit(cleanedData); + } + }; + + const updateField = ( + field: K, + value: EntityFormData[K], + ) => { + setFormData((prev) => ({ ...prev, [field]: value })); + if (submitted) { + setErrors((prev) => { + const next = { ...prev }; + delete next[field]; + return next; + }); + } + }; + + const addJoinKey = () => { + updateField("joinKeys", [...formData.joinKeys, ""]); + }; + + const removeJoinKey = (index: number) => { + if (formData.joinKeys.length <= 1) return; + updateField( + "joinKeys", + formData.joinKeys.filter((_, i) => i !== index), + ); + }; + + const updateJoinKey = (index: number, value: string) => { + const updated = [...formData.joinKeys]; + updated[index] = value; + updateField("joinKeys", updated); + }; + + return ( + + {submitError && ( + <> + +

{submitError}

+
+ + + )} + + updateField("name", v)} + onChangeDescription={(v) => updateField("description", v)} + nameDisabled={isEdit} + nameError={errors.name} + nameHelpText="A unique identifier for this entity (e.g. customer_id)." + namePlaceholder="e.g. customer_id" + descriptionPlaceholder="Describe what this entity represents..." + /> + + + + + + + +

Join Keys

+
+
+ + + Add join key + + +
+ + + Column name(s) used to join this entity in data sources. + + + {errors.joinKeys && ( + <> + + + + )} + + {formData.joinKeys.map((key, index) => ( + + + updateJoinKey(index, e.target.value)} + placeholder={ + index === 0 ? "e.g. customer_id" : "e.g. timestamp_field" + } + compressed + isInvalid={!!errors.joinKeys && !key.trim()} + /> + + + removeJoinKey(index)} + disabled={formData.joinKeys.length <= 1} + /> + + + ))} + + + + updateField("valueType", v)} + helpText="Data type of the join key." + /> + + + + updateField("tags", tags)} + error={errors.tags} + /> +
+ ); +}; + +export default EntityFormModal; +export type { EntityFormData, TagEntry }; diff --git a/ui/src/components/FeatureViewFormModal.tsx b/ui/src/components/FeatureViewFormModal.tsx new file mode 100644 index 00000000000..497defbb057 --- /dev/null +++ b/ui/src/components/FeatureViewFormModal.tsx @@ -0,0 +1,508 @@ +import React, { useState, useEffect } from "react"; +import { + EuiFormRow, + EuiFieldText, + EuiFieldNumber, + EuiSelect, + EuiSwitch, + EuiComboBox, + EuiComboBoxOptionOption, + EuiSpacer, + EuiCallOut, + EuiButtonEmpty, +} from "@elastic/eui"; +import { useParams } from "react-router-dom"; +import FormModal from "./forms/FormModal"; +import TagsEditor, { TagEntry } from "./forms/TagsEditor"; +import NameDescriptionOwnerFields from "./forms/NameDescriptionOwnerFields"; +import FeatureFieldEditor, { + FeatureFieldEntry, +} from "./forms/FeatureFieldEditor"; +import EntityFormModal, { EntityFormData } from "./EntityFormModal"; +import DataSourceFormModal, { DataSourceFormData } from "./DataSourceFormModal"; +import { useApplyEntity } from "../queries/mutations/useEntityMutations"; +import { useApplyDataSource } from "../queries/mutations/useDataSourceMutations"; +import { feast } from "../protos"; +import useResourceQuery, { + entityListPath, + dataSourceListPath, +} from "../queries/useResourceQuery"; + +const TTL_UNIT_OPTIONS = [ + { value: "seconds", text: "Seconds" }, + { value: "minutes", text: "Minutes" }, + { value: "hours", text: "Hours" }, + { value: "days", text: "Days" }, +]; + +const TTL_UNITS: Record = { + seconds: 1, + minutes: 60, + hours: 3600, + days: 86400, +}; + +interface FeatureViewFormData { + name: string; + description: string; + owner: string; + entities: string[]; + features: FeatureFieldEntry[]; + batchSource: string; + ttlValue: number; + ttlUnit: string; + online: boolean; + tags: TagEntry[]; +} + +interface FeatureViewFormModalProps { + onClose: () => void; + onSubmit: (data: FeatureViewFormData) => void; + initialData?: FeatureViewFormData; + isEdit?: boolean; + isSubmitting?: boolean; + submitError?: string | null; +} + +const EMPTY_FORM: FeatureViewFormData = { + name: "", + description: "", + owner: "", + entities: [], + features: [], + batchSource: "", + ttlValue: 0, + ttlUnit: "seconds", + online: true, + tags: [], +}; + +const FeatureViewFormModal: React.FC = ({ + onClose, + onSubmit, + initialData, + isEdit = false, + isSubmitting = false, + submitError, +}) => { + const [formData, setFormData] = useState( + initialData || EMPTY_FORM, + ); + const [errors, setErrors] = useState>({}); + const [submitted, setSubmitted] = useState(false); + const [showEntityForm, setShowEntityForm] = useState(false); + const [showDataSourceForm, setShowDataSourceForm] = useState(false); + + const { projectName } = useParams(); + + const entitiesQuery = useResourceQuery({ + resourceType: "entities-list", + project: projectName, + restPath: entityListPath(projectName), + restSelect: (d) => d.entities, + }); + + const dataSourcesQuery = useResourceQuery({ + resourceType: "data-sources-list", + project: projectName, + restPath: dataSourceListPath(projectName), + restSelect: (d) => d.dataSources, + }); + + const applyEntity = useApplyEntity(); + const applyDataSource = useApplyDataSource(); + + // REST API returns objects with spec.name; fall back to top-level name + const entities: any[] = entitiesQuery.data || []; + const dataSources: any[] = dataSourcesQuery.data || []; + + const entityOptions: EuiComboBoxOptionOption[] = entities + .map((e: any) => e?.spec?.name || e?.name || "") + .filter(Boolean) + .map((name: string) => ({ label: name })); + + const dataSourceOptions = dataSources + .map((ds: any) => ds?.spec?.name || ds?.name || "") + .filter(Boolean) + .map((name: string) => ({ value: name, text: name })); + + const hasNoEntities = entitiesQuery.isSuccess && entities.length === 0; + const hasNoDataSources = + dataSourcesQuery.isSuccess && dataSources.length === 0; + + useEffect(() => { + if (initialData) { + setFormData(initialData); + } + }, [initialData]); + + const validate = (): boolean => { + const newErrors: Record = {}; + + if (!formData.name.trim()) { + newErrors.name = "Feature view name is required."; + } else if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(formData.name)) { + newErrors.name = + "Must start with a letter or underscore, and contain only letters, numbers, and underscores."; + } + + if (formData.features.length === 0) { + newErrors.features = "At least one feature is required."; + } else { + const hasEmptyName = formData.features.some((f) => !f.name.trim()); + if (hasEmptyName) { + newErrors.features = "All features must have a name."; + } else { + const featureNames = formData.features.map((f) => f.name.trim()); + if (new Set(featureNames).size !== featureNames.length) { + newErrors.features = "Feature names must be unique."; + } + const invalidName = featureNames.find( + (n) => !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(n), + ); + if (invalidName) { + newErrors.features = `Invalid feature name "${invalidName}". Use only letters, numbers, and underscores.`; + } + } + } + + if (!formData.batchSource.trim()) { + newErrors.batchSource = "A batch source is required."; + } + + if (formData.ttlValue < 0) { + newErrors.ttlValue = "TTL must be 0 (never expire) or a positive number."; + } + + const tagKeys = formData.tags.map((t) => t.key).filter((k) => k.trim()); + if (new Set(tagKeys).size !== tagKeys.length) { + newErrors.tags = "Tag keys must be unique."; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = () => { + setSubmitted(true); + if (validate()) { + const cleanedData = { + ...formData, + tags: formData.tags.filter((t) => t.key.trim()), + }; + onSubmit(cleanedData); + } + }; + + const updateField = ( + field: K, + value: FeatureViewFormData[K], + ) => { + setFormData((prev) => ({ ...prev, [field]: value })); + if (submitted) { + setErrors((prev) => { + const next = { ...prev }; + delete next[field]; + return next; + }); + } + }; + + const handleInlineEntityCreate = (entityData: EntityFormData) => { + const payload = { + name: entityData.name, + project: projectName || "", + join_key: entityData.joinKeys[0] || entityData.name, + value_type: parseInt(entityData.valueType, 10), + description: entityData.description, + tags: Object.fromEntries( + entityData.tags + .filter((t) => t.key.trim()) + .map((t) => [t.key, t.value]), + ), + }; + applyEntity.mutate(payload, { + onSuccess: () => { + setShowEntityForm(false); + updateField("entities", [...formData.entities, entityData.name]); + }, + }); + }; + + const handleInlineDataSourceCreate = (dsData: DataSourceFormData) => { + const payload: Record = { + name: dsData.name, + project: projectName || "", + type: parseInt(dsData.sourceType, 10), + timestamp_field: dsData.timestampField, + created_timestamp_column: dsData.createdTimestampColumn, + description: dsData.description, + owner: dsData.owner, + tags: Object.fromEntries( + dsData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + }; + + const st = dsData.sourceType; + if (st === String(feast.core.DataSource.SourceType.BATCH_FILE)) { + payload.file_options = { uri: dsData.fileUri }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_BIGQUERY)) { + payload.bigquery_options = { + table: dsData.bigqueryTable, + query: dsData.bigqueryQuery, + }; + } else if ( + st === String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE) + ) { + payload.snowflake_options = { + table: dsData.snowflakeTable, + database: dsData.snowflakeDatabase, + schema_: dsData.snowflakeSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_REDSHIFT)) { + payload.redshift_options = { + table: dsData.redshiftTable, + database: dsData.redshiftDatabase, + schema_: dsData.redshiftSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.STREAM_KAFKA)) { + payload.kafka_options = { + kafka_bootstrap_servers: dsData.kafkaBootstrapServers, + topic: dsData.kafkaTopic, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SPARK)) { + payload.spark_options = { + table: dsData.sparkTable, + path: dsData.sparkPath, + }; + } + + applyDataSource.mutate(payload as any, { + onSuccess: () => { + setShowDataSourceForm(false); + updateField("batchSource", dsData.name); + }, + }); + }; + + const selectedEntityOptions = formData.entities.map((e) => ({ label: e })); + + return ( + <> + + {submitError && ( + <> + +

{submitError}

+
+ + + )} + + updateField("name", v)} + onChangeDescription={(v) => updateField("description", v)} + onChangeOwner={(v) => updateField("owner", v)} + nameDisabled={isEdit} + nameError={errors.name} + nameHelpText="A unique name for this feature view." + namePlaceholder="e.g. customer_features" + descriptionPlaceholder="Describe what this feature view provides..." + /> + + {hasNoEntities && ( + <> + + +

+ Feature views typically reference entities. You can create one + now. +

+ setShowEntityForm(true)} + > + Create Entity + +
+ + + )} + + + + updateField( + "entities", + selected.map((s) => s.label), + ) + } + isClearable + isLoading={entitiesQuery.isLoading} + /> + + + {hasNoDataSources && ( + <> + + +

+ A batch source is required. You can create a data source now. +

+ setShowDataSourceForm(true)} + > + Create Data Source + +
+ + + )} + + + {dataSourceOptions.length > 0 ? ( + updateField("batchSource", e.target.value)} + isInvalid={!!errors.batchSource} + isLoading={dataSourcesQuery.isLoading} + /> + ) : ( + updateField("batchSource", e.target.value)} + isInvalid={!!errors.batchSource} + placeholder={ + dataSourcesQuery.isLoading + ? "Loading data sources..." + : "Enter data source name" + } + /> + )} + + + + + updateField("features", features)} + error={errors.features} + /> + + + + +
+ + updateField("ttlValue", parseInt(e.target.value) || 0) + } + min={0} + isInvalid={!!errors.ttlValue} + style={{ width: 120 }} + /> + updateField("ttlUnit", e.target.value)} + style={{ width: 140 }} + /> +
+
+ + + updateField("online", e.target.checked)} + /> + + + + + updateField("tags", tags)} + error={errors.tags} + /> +
+ + {showEntityForm && ( + setShowEntityForm(false)} + onSubmit={handleInlineEntityCreate} + /> + )} + + {showDataSourceForm && ( + setShowDataSourceForm(false)} + onSubmit={handleInlineDataSourceCreate} + /> + )} + + ); +}; + +export default FeatureViewFormModal; +export type { FeatureViewFormData }; +export { TTL_UNITS }; diff --git a/ui/src/components/FeaturesInServiceDisplay.tsx b/ui/src/components/FeaturesInServiceDisplay.tsx index 14731caa0b8..6d772b78f34 100644 --- a/ui/src/components/FeaturesInServiceDisplay.tsx +++ b/ui/src/components/FeaturesInServiceDisplay.tsx @@ -12,39 +12,53 @@ interface IFeatureColumnInService { featureViewName: string; name: string; valueType: feast.types.ValueType.Enum; + viewType?: string; } const FeaturesInServiceList = ({ featureViews }: FeatureViewsListInterace) => { const { projectName } = useParams(); - const items: IFeatureColumnInService[] = featureViews.flatMap((featureView) => - featureView.featureColumns!.map((featureColumn) => ({ - featureViewName: featureView.featureViewName!, - name: featureColumn.name!, - valueType: featureColumn.valueType!, - })), + + const items: IFeatureColumnInService[] = featureViews.flatMap( + (featureView: any) => + (featureView.featureColumns || []).map((featureColumn: any) => ({ + featureViewName: featureView.featureViewName!, + name: featureColumn.name!, + valueType: featureColumn.valueType!, + viewType: featureView.viewType || "featureView", + })), ); + const isLabelMode = items.length > 0 && items[0].viewType === "labelView"; + const columns = [ { - name: "Feature View", + name: isLabelMode ? "Label View" : "Feature View", field: "featureViewName", - render: (name: string) => { - return ( - - {name} - - ); + render: (name: string, item: IFeatureColumnInService) => { + const isLabelView = item.viewType === "labelView"; + const path = isLabelView + ? `/p/${projectName}/label-view/${name}` + : `/p/${projectName}/feature-view/${name}`; + return {name}; }, }, { - name: "Feature Column", + name: isLabelMode ? "Label" : "Feature", field: "name", + render: (name: string, item: IFeatureColumnInService) => { + const isLabelView = item.viewType === "labelView"; + const path = isLabelView + ? `/p/${projectName}/label-view/${item.featureViewName}/label/${name}` + : `/p/${projectName}/feature-view/${item.featureViewName}/feature/${name}`; + return {name}; + }, }, { name: "Value Type", field: "valueType", - render: (valueType: feast.types.ValueType.Enum) => { - return feast.types.ValueType.Enum[valueType]; + render: (valueType: feast.types.ValueType.Enum | string) => { + if (typeof valueType === "string") return valueType; + return feast.types.ValueType.Enum[valueType] || String(valueType); }, }, ]; diff --git a/ui/src/components/FeaturesListDisplay.tsx b/ui/src/components/FeaturesListDisplay.tsx index 61f57b478d6..51bc62e8e2b 100644 --- a/ui/src/components/FeaturesListDisplay.tsx +++ b/ui/src/components/FeaturesListDisplay.tsx @@ -30,8 +30,9 @@ const FeaturesList = ({ { name: "Value Type", field: "valueType", - render: (valueType: feast.types.ValueType.Enum) => { - return feast.types.ValueType.Enum[valueType]; + render: (valueType: feast.types.ValueType.Enum | string) => { + if (typeof valueType === "string") return valueType; + return feast.types.ValueType.Enum[valueType] || String(valueType || ""); }, }, ]; diff --git a/ui/src/components/ObjectsCountStats.tsx b/ui/src/components/ObjectsCountStats.tsx index bf1dd2dc9dd..92dc690798c 100644 --- a/ui/src/components/ObjectsCountStats.tsx +++ b/ui/src/components/ObjectsCountStats.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React from "react"; import { EuiFlexGroup, EuiFlexItem, @@ -7,45 +7,78 @@ import { EuiTitle, EuiSpacer, } from "@elastic/eui"; -import useLoadRegistry from "../queries/useLoadRegistry"; import { useNavigate, useParams } from "react-router-dom"; -import RegistryPathContext from "../contexts/RegistryPathContext"; - -const useLoadObjectStats = () => { - const registryUrl = useContext(RegistryPathContext); - const query = useLoadRegistry(registryUrl); - - const data = - query.isSuccess && query.data - ? { - featureServices: query.data.objects.featureServices?.length || 0, - featureViews: query.data.mergedFVList.length, - entities: query.data.objects.entities?.length || 0, - dataSources: query.data.objects.dataSources?.length || 0, - } - : undefined; - - return { - ...query, - data, - }; -}; +import useResourceQuery, { + entityListPath, + featureViewListPath, + featureServiceListPath, + dataSourceListPath, + labelViewListPath, + featuresListPath, + restFeatureViewsToMergedList, + restLabelViewsFromResponse, +} from "../queries/useResourceQuery"; +import type { genericFVType } from "../parsers/mergedFVTypes"; const statStyle = { cursor: "pointer" }; const ObjectsCountStats = () => { - const { isLoading, isSuccess, isError, data } = useLoadObjectStats(); const { projectName } = useParams(); - const navigate = useNavigate(); + const { data: featureServices, isSuccess: fsOk } = useResourceQuery({ + resourceType: "stats-fs", + project: projectName, + restPath: featureServiceListPath(projectName), + restSelect: (d) => d.featureServices, + }); + + const { data: featureViews, isSuccess: fvOk } = useResourceQuery< + genericFVType[] + >({ + resourceType: "stats-fvs", + project: projectName, + restPath: featureViewListPath(projectName), + restSelect: restFeatureViewsToMergedList, + }); + + const { data: entities, isSuccess: entOk } = useResourceQuery({ + resourceType: "stats-ent", + project: projectName, + restPath: entityListPath(projectName), + restSelect: (d) => d.entities, + }); + + const { data: dataSources, isSuccess: dsOk } = useResourceQuery({ + resourceType: "stats-ds", + project: projectName, + restPath: dataSourceListPath(projectName), + restSelect: (d) => d.dataSources, + }); + + const { data: features, isSuccess: featOk } = useResourceQuery({ + resourceType: "stats-feat", + project: projectName, + restPath: featuresListPath(projectName), + restSelect: (d) => d.features || [], + }); + + const { data: labelViews, isSuccess: lvOk } = useResourceQuery({ + resourceType: "stats-lv", + project: projectName, + restPath: labelViewListPath(projectName), + restSelect: restLabelViewsFromResponse, + }); + + const allOk = fsOk && fvOk && entOk && dsOk && featOk && lvOk; + const hasLabelViews = (labelViews?.length || 0) > 0; + return ( - {isLoading &&

Loading

} - {isError &&

There was an error in loading registry information.

} - {isSuccess && data && ( + {!allOk &&

Loading

} + {allOk && (

Registered in this Feast project are …

@@ -57,7 +90,7 @@ const ObjectsCountStats = () => { style={statStyle} onClick={() => navigate(`/p/${projectName}/feature-service`)} description="Feature Services→" - title={data.featureServices} + title={featureServices?.length || 0} reverse /> @@ -66,7 +99,16 @@ const ObjectsCountStats = () => { style={statStyle} description="Feature Views→" onClick={() => navigate(`/p/${projectName}/feature-view`)} - title={data.featureViews} + title={featureViews?.length || 0} + reverse + /> + + + navigate(`/p/${projectName}/features`)} + title={features?.length || 0} reverse /> @@ -75,7 +117,7 @@ const ObjectsCountStats = () => { style={statStyle} description="Entities→" onClick={() => navigate(`/p/${projectName}/entity`)} - title={data.entities} + title={entities?.length || 0} reverse /> @@ -84,11 +126,30 @@ const ObjectsCountStats = () => { style={statStyle} description="Data Sources→" onClick={() => navigate(`/p/${projectName}/data-source`)} - title={data.dataSources} + title={dataSources?.length || 0} reverse /> + {hasLabelViews && ( + + + + + navigate(`/p/${projectName}/label-view`)} + description="Label Views→" + title={labelViews?.length || 0} + reverse + /> + + + + + + + )}
)}
diff --git a/ui/src/components/PermissionsDisplay.tsx b/ui/src/components/PermissionsDisplay.tsx index 47af120a1cd..d4b35cb5d33 100644 --- a/ui/src/components/PermissionsDisplay.tsx +++ b/ui/src/components/PermissionsDisplay.tsx @@ -3,13 +3,9 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, - EuiPanel, EuiText, - EuiTitle, - EuiHorizontalRule, EuiToolTip, } from "@elastic/eui"; -import { formatPermissions } from "../utils/permissionUtils"; interface PermissionsDisplayProps { permissions: any[] | undefined; diff --git a/ui/src/components/ProjectSelector.test.tsx b/ui/src/components/ProjectSelector.test.tsx index 40d89cde93c..d311e7ef980 100644 --- a/ui/src/components/ProjectSelector.test.tsx +++ b/ui/src/components/ProjectSelector.test.tsx @@ -5,18 +5,10 @@ import userEvent from "@testing-library/user-event"; import FeastUISansProviders from "../FeastUISansProviders"; -import { - projectsListWithDefaultProject, - creditHistoryRegistry, - creditHistoryRegistryDB, -} from "../mocks/handlers"; +import { allRestHandlers } from "../mocks/handlers"; // declare which API requests to mock -const server = setupServer( - projectsListWithDefaultProject, - creditHistoryRegistry, - creditHistoryRegistryDB, -); +const server = setupServer(...allRestHandlers); // establish API mocking before all tests beforeAll(() => server.listen()); @@ -48,12 +40,12 @@ test("in a full App render, it shows the right initial project", async () => { // Wait for Project Data from Registry to Load await screen.findAllByRole("heading", { - name: /Project: credit_scoring_aws/i, + name: /Project: Credit Score Project/i, }); // Before User Event: Heading is the credit scoring project screen.getByRole("heading", { - name: /credit_scoring_aws/i, + name: /Credit Score Project/i, }); // Do the select option user event @@ -78,6 +70,6 @@ test("in a full App render, it shows the right initial project", async () => { // ... and the new heading should appear // meaning we successfully navigated await screen.findByRole("heading", { - name: /Project: credit_scoring_aws/i, + name: /Project: Credit Score Project/i, }); }); diff --git a/ui/src/components/RegistrySearch.tsx b/ui/src/components/RegistrySearch.tsx index 46d72966713..ed3b987240e 100644 --- a/ui/src/components/RegistrySearch.tsx +++ b/ui/src/components/RegistrySearch.tsx @@ -3,6 +3,7 @@ import React, { useRef, forwardRef, useImperativeHandle, + useCallback, } from "react"; import { EuiText, @@ -17,8 +18,6 @@ import { } from "@elastic/eui"; import EuiCustomLink from "./EuiCustomLink"; -import { css } from "@emotion/react"; - const searchResultsStyles = { searchResults: { marginTop: "8px", @@ -68,11 +67,11 @@ const RegistrySearch = forwardRef( const [searchText, setSearchText] = useState(""); const inputRef = useRef(null); - const focusSearchInput = () => { + const focusSearchInput = useCallback(() => { if (inputRef.current) { inputRef.current.focus(); } - }; + }, []); useImperativeHandle( ref, diff --git a/ui/src/components/RegistryVisualization.test.tsx b/ui/src/components/RegistryVisualization.test.tsx new file mode 100644 index 00000000000..01da8f415a3 --- /dev/null +++ b/ui/src/components/RegistryVisualization.test.tsx @@ -0,0 +1,372 @@ +import React from "react"; +import { render, screen, within } from "../test-utils"; +import { waitFor } from "@testing-library/react"; +import RegistryVisualization from "./RegistryVisualization"; +import { feast } from "../protos"; +import { FEAST_FCO_TYPES } from "../parsers/types"; +import { EntityRelation } from "../parsers/parseEntityRelationships"; +import { ThemeProvider } from "../contexts/ThemeContext"; + +// ReactFlow requires ResizeObserver +class ResizeObserverMock { + observe() {} + unobserve() {} + disconnect() {} +} +(global as any).ResizeObserver = ResizeObserverMock; + +// Helper to build minimal registry data +const makeRegistry = ( + overrides: Partial = {}, +): feast.core.Registry => { + return feast.core.Registry.create({ + featureViews: [], + onDemandFeatureViews: [], + streamFeatureViews: [], + featureServices: [], + entities: [], + dataSources: [], + ...overrides, + }); +}; + +const makeRelationship = ( + sourceName: string, + sourceType: FEAST_FCO_TYPES, + targetName: string, + targetType: FEAST_FCO_TYPES, +): EntityRelation => ({ + source: { name: sourceName, type: sourceType }, + target: { name: targetName, type: targetType }, +}); + +const renderVisualization = ( + registryData: feast.core.Registry, + relationships: EntityRelation[] = [], + indirectRelationships: EntityRelation[] = [], +) => { + return render( + + + , + ); +}; + +describe("RegistryVisualization version indicators", () => { + test("renders version badge on feature view with currentVersionNumber > 1", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "my_feature_view" }, + meta: { currentVersionNumber: 3 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "my_feature_view", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("v3")).toBeInTheDocument(); + }); + }); + + test("does not render version badge when currentVersionNumber is 0", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "unversioned_fv" }, + meta: { currentVersionNumber: 0 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "unversioned_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("unversioned_fv")).toBeInTheDocument(); + }); + + expect(screen.queryByText("v0")).not.toBeInTheDocument(); + }); + + test("does not render version badge when currentVersionNumber is 1 (initial version)", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "initial_fv" }, + meta: { currentVersionNumber: 1 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "initial_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("initial_fv")).toBeInTheDocument(); + }); + + expect(screen.queryByText("v1")).not.toBeInTheDocument(); + }); + + test("does not render version badge when meta has no version", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "no_version_fv" }, + meta: {}, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "no_version_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("no_version_fv")).toBeInTheDocument(); + }); + + // No version badges should exist at all + const badges = screen.queryAllByText(/^v\d+$/); + expect(badges).toHaveLength(0); + }); + + test("renders version badge on on-demand feature view", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "regular_fv" }, + }), + ], + onDemandFeatureViews: [ + feast.core.OnDemandFeatureView.create({ + spec: { name: "odfv_versioned" }, + meta: { currentVersionNumber: 2 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + // Connect regular FV to entity so nodes render, and ODFV to regular FV + const relationships = [ + makeRelationship( + "regular_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + // Use the full component and toggle isolated nodes to show ODFV + render( + + + , + ); + + // Enable isolated nodes to show the ODFV + const isolatedCheckbox = screen.getByLabelText( + /Show Objects Without Relationships/i, + ); + isolatedCheckbox.click(); + + await waitFor(() => { + expect(screen.getByText("v2")).toBeInTheDocument(); + }); + }); + + test("renders version badge on stream feature view", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "regular_fv" }, + }), + ], + streamFeatureViews: [ + feast.core.StreamFeatureView.create({ + spec: { name: "sfv_versioned" }, + meta: { currentVersionNumber: 5 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "regular_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + render( + + + , + ); + + // Enable isolated nodes to show the SFV + const isolatedCheckbox = screen.getByLabelText( + /Show Objects Without Relationships/i, + ); + isolatedCheckbox.click(); + + await waitFor(() => { + expect(screen.getByText("v5")).toBeInTheDocument(); + }); + }); + + test("renders version history info from featureViewVersionHistory", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "versioned_fv" }, + meta: { currentVersionNumber: 2 }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "my_entity" }, + }), + ], + featureViewVersionHistory: feast.core.FeatureViewVersionHistory.create({ + records: [ + feast.core.FeatureViewVersionRecord.create({ + featureViewName: "versioned_fv", + versionNumber: 1, + description: "Initial version", + }), + feast.core.FeatureViewVersionRecord.create({ + featureViewName: "versioned_fv", + versionNumber: 2, + description: "Added new features", + }), + ], + }), + }); + + const relationships = [ + makeRelationship( + "versioned_fv", + FEAST_FCO_TYPES.featureView, + "my_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("v2")).toBeInTheDocument(); + }); + }); +}); + +describe("RegistryVisualization legend", () => { + test("renders Version Changed entry in legend", async () => { + const registry = makeRegistry({ + featureViews: [ + feast.core.FeatureView.create({ + spec: { name: "some_fv" }, + }), + ], + entities: [ + feast.core.Entity.create({ + spec: { name: "some_entity" }, + }), + ], + }); + + const relationships = [ + makeRelationship( + "some_fv", + FEAST_FCO_TYPES.featureView, + "some_entity", + FEAST_FCO_TYPES.entity, + ), + ]; + + renderVisualization(registry, relationships); + + await waitFor(() => { + expect(screen.getByText("Version Changed")).toBeInTheDocument(); + }); + + expect(screen.getByText("vN")).toBeInTheDocument(); + }); +}); diff --git a/ui/src/components/RegistryVisualization.tsx b/ui/src/components/RegistryVisualization.tsx index 64dc9f5f9b2..a974f335bda 100644 --- a/ui/src/components/RegistryVisualization.tsx +++ b/ui/src/components/RegistryVisualization.tsx @@ -21,9 +21,11 @@ import { EuiSpacer, EuiLoadingSpinner, EuiToolTip, + EuiBadge, } from "@elastic/eui"; import { FEAST_FCO_TYPES } from "../parsers/types"; import { EntityRelation } from "../parsers/parseEntityRelationships"; +import { MlflowRunData } from "../queries/useLoadMlflowRuns"; import { feast } from "../protos"; import { useTheme } from "../contexts/ThemeContext"; import { @@ -64,6 +66,8 @@ interface NodeData { type: FEAST_FCO_TYPES; metadata: any; permissions?: any[]; // Add permissions field + versionNumber?: number; + versionInfo?: { totalVersions: number; latestDescription?: string }; } const getNodeColor = (type: FEAST_FCO_TYPES) => { @@ -76,6 +80,12 @@ const getNodeColor = (type: FEAST_FCO_TYPES) => { return "#ff8000"; // Orange case FEAST_FCO_TYPES.dataSource: return "#cc0000"; // Red + case FEAST_FCO_TYPES.labelView: + return "#e6570e"; // Deep orange for label views + case FEAST_FCO_TYPES.mlflowRun: + return "#0194e2"; // MLflow brand blue + case FEAST_FCO_TYPES.mlflowModel: + return "#7b2d8e"; // Purple default: return "#666666"; // Gray } @@ -91,6 +101,12 @@ const getLightNodeColor = (type: FEAST_FCO_TYPES) => { return "#fff2e6"; // Light orange case FEAST_FCO_TYPES.dataSource: return "#ffe6e6"; // Light red + case FEAST_FCO_TYPES.labelView: + return "#fde8dc"; // Light deep orange + case FEAST_FCO_TYPES.mlflowRun: + return "#e6f6fd"; // Light MLflow blue + case FEAST_FCO_TYPES.mlflowModel: + return "#f3e6f9"; // Light purple default: return "#f0f0f0"; // Light gray } @@ -106,6 +122,12 @@ const getNodeIcon = (type: FEAST_FCO_TYPES) => { return "▲"; // Triangle for entity case FEAST_FCO_TYPES.dataSource: return "◆"; // Diamond for data source + case FEAST_FCO_TYPES.labelView: + return "◉"; // Bullseye for label view + case FEAST_FCO_TYPES.mlflowRun: + return "⬡"; // Hexagon for MLflow run + case FEAST_FCO_TYPES.mlflowModel: + return "⬢"; // Filled hexagon for registered model default: return "●"; // Default circle } @@ -119,8 +141,17 @@ const CustomNode = ({ data }: { data: NodeData }) => { const icon = getNodeIcon(data.type); const [isHovered, setIsHovered] = useState(false); const hasPermissions = data.permissions && data.permissions.length > 0; + const hasVersion = data.versionNumber != null && data.versionNumber > 1; const handleClick = () => { + if ( + (data.type === FEAST_FCO_TYPES.mlflowRun || + data.type === FEAST_FCO_TYPES.mlflowModel) && + data.metadata?.mlflow_url + ) { + window.open(data.metadata.mlflow_url, "_blank", "noopener,noreferrer"); + return; + } let path; switch (data.type) { case FEAST_FCO_TYPES.dataSource: @@ -135,6 +166,9 @@ const CustomNode = ({ data }: { data: NodeData }) => { case FEAST_FCO_TYPES.featureService: path = `/p/${projectName}/feature-service/${data.label}`; break; + case FEAST_FCO_TYPES.labelView: + path = `/p/${projectName}/label-view/${data.label}`; + break; default: return; } @@ -179,7 +213,10 @@ const CustomNode = ({ data }: { data: NodeData }) => { zIndex: 5, }} > - View Details + {data.type === FEAST_FCO_TYPES.mlflowRun || + data.type === FEAST_FCO_TYPES.mlflowModel + ? "Open in MLflow ↗" + : "View Details"}
)} @@ -207,6 +244,40 @@ const CustomNode = ({ data }: { data: NodeData }) => { )} + {/* Version indicator */} + {hasVersion && ( + +
Version: {data.versionNumber}
+ {data.versionInfo && ( + <> +
Total versions: {data.versionInfo.totalVersions}
+ {data.versionInfo.latestDescription && ( +
Latest: {data.versionInfo.latestDescription}
+ )} + + )} +
+ Click node for full history +
+ + } + > +
+ v{data.versionNumber} +
+
+ )} + { @@ -414,8 +488,11 @@ const Legend = () => { const types = [ { type: FEAST_FCO_TYPES.featureService, label: "Feature Service" }, { type: FEAST_FCO_TYPES.featureView, label: "Feature View" }, + { type: FEAST_FCO_TYPES.labelView, label: "Label View" }, { type: FEAST_FCO_TYPES.entity, label: "Entity" }, { type: FEAST_FCO_TYPES.dataSource, label: "Data Source" }, + { type: FEAST_FCO_TYPES.mlflowRun, label: "MLflow Run" }, + { type: FEAST_FCO_TYPES.mlflowModel, label: "Registered Model" }, ]; const isDarkMode = colorMode === "dark"; @@ -474,6 +551,20 @@ const Legend = () => {
{item.label}
))} +
+ + vN + +
Version Changed
+
); }; @@ -482,10 +573,43 @@ const registryToFlow = ( objects: feast.core.Registry, relationships: EntityRelation[], permissions?: any[], + versionHistory?: feast.core.IFeatureViewVersionRecord[], + mlflowRuns?: MlflowRunData[], ) => { const nodes: Node[] = []; const edges: Edge[] = []; + // Build a lookup of version info by feature view name + const versionInfoMap = new Map< + string, + { totalVersions: number; latestDescription?: string } + >(); + if (versionHistory) { + const grouped: Record = {}; + for (let i = 0; i < versionHistory.length; i++) { + const record = versionHistory[i]; + const name = record.featureViewName; + if (!name) continue; + if (!grouped[name]) grouped[name] = []; + grouped[name].push(record); + } + const groupedNames = Object.keys(grouped); + for (let i = 0; i < groupedNames.length; i++) { + const name = groupedNames[i]; + const records = grouped[name]; + records.sort( + ( + a: feast.core.IFeatureViewVersionRecord, + b: feast.core.IFeatureViewVersionRecord, + ) => (b.versionNumber ?? 0) - (a.versionNumber ?? 0), + ); + versionInfoMap.set(name, { + totalVersions: records.length, + latestDescription: records[0]?.description ?? undefined, + }); + } + } + objects.featureServices?.forEach((fs) => { nodes.push({ id: `fs-${fs.spec?.name}`, @@ -507,60 +631,69 @@ const registryToFlow = ( }); objects.featureViews?.forEach((fv) => { + const fvName = fv.spec?.name; nodes.push({ - id: `fv-${fv.spec?.name}`, + id: `fv-${fvName}`, type: "custom", data: { - label: fv.spec?.name, + label: fvName, type: FEAST_FCO_TYPES.featureView, metadata: fv, permissions: permissions ? getEntityPermissions( permissions, FEAST_FCO_TYPES.featureView, - fv.spec?.name, + fvName, ) : [], + versionNumber: fv.meta?.currentVersionNumber ?? undefined, + versionInfo: fvName ? versionInfoMap.get(fvName) : undefined, }, position: { x: 0, y: 0 }, }); }); objects.onDemandFeatureViews?.forEach((odfv) => { + const odfvName = odfv.spec?.name; nodes.push({ - id: `odfv-${odfv.spec?.name}`, + id: `odfv-${odfvName}`, type: "custom", data: { - label: odfv.spec?.name, + label: odfvName, type: FEAST_FCO_TYPES.featureView, metadata: odfv, permissions: permissions ? getEntityPermissions( permissions, FEAST_FCO_TYPES.featureView, - odfv.spec?.name, + odfvName, ) : [], + versionNumber: odfv.meta?.currentVersionNumber ?? undefined, + versionInfo: odfvName ? versionInfoMap.get(odfvName) : undefined, }, position: { x: 0, y: 0 }, }); }); objects.streamFeatureViews?.forEach((sfv) => { + const sfvName = sfv.spec?.name; nodes.push({ - id: `sfv-${sfv.spec?.name}`, + id: `sfv-${sfvName}`, type: "custom", data: { - label: sfv.spec?.name, + label: sfvName, type: FEAST_FCO_TYPES.featureView, metadata: sfv, permissions: permissions ? getEntityPermissions( permissions, FEAST_FCO_TYPES.featureView, - sfv.spec?.name, + sfvName, ) : [], + versionNumber: sfv.meta?.currentVersionNumber ?? undefined, + versionInfo: sfvName ? versionInfoMap.get(sfvName) : undefined, }, position: { x: 0, y: 0 }, }); @@ -586,6 +719,25 @@ const registryToFlow = ( }); }); + objects.labelViews?.forEach((lv: any) => { + const lvName = lv.spec?.name; + nodes.push({ + id: `lv-${lvName}`, + type: "custom", + data: { + label: lvName, + type: FEAST_FCO_TYPES.labelView, + metadata: lv, + permissions: permissions + ? getEntityPermissions(permissions, FEAST_FCO_TYPES.labelView, lvName) + : [], + versionNumber: lv.meta?.currentVersionNumber ?? undefined, + versionInfo: lvName ? versionInfoMap.get(lvName) : undefined, + }, + position: { x: 0, y: 0 }, + }); + }); + const dataSources = new Set(); objects.featureViews?.forEach((fv) => { @@ -603,6 +755,18 @@ const registryToFlow = ( } }); + (objects as any).labelViews?.forEach((lv: any) => { + if (lv.spec?.source?.name) { + dataSources.add(lv.spec.source.name); + } + if (lv.spec?.source?.batchSource?.name) { + dataSources.add(lv.spec.source.batchSource.name); + } + if (lv.spec?.batchSource?.name) { + dataSources.add(lv.spec.batchSource.name); + } + }); + Array.from(dataSources).forEach((dsName) => { nodes.push({ id: `ds-${dsName}`, @@ -650,6 +814,101 @@ const registryToFlow = ( }); }); + if (mlflowRuns && mlflowRuns.length > 0) { + mlflowRuns.forEach((run) => { + const runLabel = run.run_name || run.run_id.substring(0, 8); + nodes.push({ + id: `mlflow-${run.run_id}`, + type: "custom", + data: { + label: runLabel, + type: FEAST_FCO_TYPES.mlflowRun, + metadata: { + mlflow_url: run.mlflow_url, + retrieval_type: run.retrieval_type, + status: run.status, + run_id: run.run_id, + }, + }, + position: { x: 0, y: 0 }, + }); + + if (run.feature_service) { + const fsNodeId = `fs-${run.feature_service}`; + const fsNodeExists = nodes.some((n) => n.id === fsNodeId); + if (fsNodeExists) { + edges.push({ + id: `edge-mlflow-${run.run_id}`, + source: fsNodeId, + sourceHandle: "source", + target: `mlflow-${run.run_id}`, + targetHandle: "target", + animated: true, + style: { + strokeWidth: 3, + stroke: "#0194e2", + strokeDasharray: "10 5", + animation: "dataflow 2s linear infinite", + }, + type: "smoothstep", + markerEnd: { + type: MarkerType.ArrowClosed, + width: 20, + height: 20, + color: "#0194e2", + }, + }); + } + } + + if (run.registered_models && run.registered_models.length > 0) { + run.registered_models.forEach((model) => { + const modelNodeId = `model-${model.model_name}-v${model.version}`; + const modelExists = nodes.some((n) => n.id === modelNodeId); + if (!modelExists) { + nodes.push({ + id: modelNodeId, + type: "custom", + data: { + label: `${model.model_name} v${model.version}`, + type: FEAST_FCO_TYPES.mlflowModel, + metadata: { + mlflow_url: model.mlflow_url, + model_name: model.model_name, + version: model.version, + stage: model.stage, + }, + }, + position: { x: 0, y: 0 }, + }); + } + + edges.push({ + id: `edge-model-${run.run_id}-${model.model_name}-v${model.version}`, + source: `mlflow-${run.run_id}`, + sourceHandle: "source", + target: modelNodeId, + targetHandle: "target", + animated: true, + style: { + strokeWidth: 3, + stroke: "#7b2d8e", + strokeDasharray: "10 5", + animation: "dataflow 2s linear infinite", + }, + type: "smoothstep", + markerEnd: { + type: MarkerType.ArrowClosed, + width: 20, + height: 20, + color: "#7b2d8e", + }, + }); + }); + } + }); + } + return { nodes, edges }; }; @@ -663,6 +922,12 @@ const getNodePrefix = (type: FEAST_FCO_TYPES) => { return "entity"; case FEAST_FCO_TYPES.dataSource: return "ds"; + case FEAST_FCO_TYPES.labelView: + return "lv"; + case FEAST_FCO_TYPES.mlflowRun: + return "mlflow"; + case FEAST_FCO_TYPES.mlflowModel: + return "model"; default: return "unknown"; } @@ -673,7 +938,8 @@ interface RegistryVisualizationProps { relationships: EntityRelation[]; indirectRelationships: EntityRelation[]; filterNode?: { type: FEAST_FCO_TYPES; name: string }; - permissions?: any[]; // Add permissions field + permissions?: any[]; + mlflowRuns?: MlflowRunData[]; } const RegistryVisualization: React.FC = ({ @@ -682,6 +948,7 @@ const RegistryVisualization: React.FC = ({ indirectRelationships, filterNode, permissions, + mlflowRuns, }) => { const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); @@ -750,10 +1017,15 @@ const RegistryVisualization: React.FC = ({ return rel.source && rel.target && rel.source.name && rel.target.name; }); + const versionRecords = + registryData.featureViewVersionHistory?.records ?? undefined; + const { nodes: initialNodes, edges: initialEdges } = registryToFlow( registryData, validRelationships, permissions, + versionRecords as feast.core.IFeatureViewVersionRecord[] | undefined, + mlflowRuns, ); const { nodes: layoutedNodes, edges: layoutedEdges } = @@ -775,6 +1047,8 @@ const RegistryVisualization: React.FC = ({ showIndirectRelationships, showIsolatedNodes, filterNode, + permissions, + mlflowRuns, setNodes, setEdges, ]); diff --git a/ui/src/components/RegistryVisualizationTab.tsx b/ui/src/components/RegistryVisualizationTab.tsx index ebc77604322..5afdce0c223 100644 --- a/ui/src/components/RegistryVisualizationTab.tsx +++ b/ui/src/components/RegistryVisualizationTab.tsx @@ -10,6 +10,7 @@ import { EuiFlexItem, } from "@elastic/eui"; import useLoadRegistry from "../queries/useLoadRegistry"; +import useLoadMlflowRuns from "../queries/useLoadMlflowRuns"; import RegistryPathContext from "../contexts/RegistryPathContext"; import RegistryVisualization from "./RegistryVisualization"; import { FEAST_FCO_TYPES } from "../parsers/types"; @@ -22,6 +23,7 @@ const RegistryVisualizationTab = () => { registryUrl, projectName, ); + const { data: mlflowData } = useLoadMlflowRuns(); const [selectedObjectType, setSelectedObjectType] = useState(""); const [selectedObjectName, setSelectedObjectName] = useState(""); const [selectedPermissionAction, setSelectedPermissionAction] = useState(""); @@ -40,6 +42,13 @@ const RegistryVisualizationTab = () => { if (sfv.spec?.streamSource?.name) dataSources.add(sfv.spec.streamSource.name); }); + objects.labelViews?.forEach((lv: any) => { + if (lv.spec?.source?.name) dataSources.add(lv.spec.source.name); + if (lv.spec?.source?.batchSource?.name) + dataSources.add(lv.spec.source.batchSource.name); + if (lv.spec?.batchSource?.name) + dataSources.add(lv.spec.batchSource.name); + }); return Array.from(dataSources); case "entity": return objects.entities?.map((entity: any) => entity.spec?.name) || []; @@ -52,6 +61,8 @@ const RegistryVisualizationTab = () => { ...(objects.streamFeatureViews?.map((sfv: any) => sfv.spec?.name) || []), ]; + case "labelView": + return objects.labelViews?.map((lv: any) => lv.spec?.name) || []; case "featureService": return objects.featureServices?.map((fs: any) => fs.spec?.name) || []; default: @@ -91,7 +102,11 @@ const RegistryVisualizationTab = () => { { value: "dataSource", text: "Data Source" }, { value: "entity", text: "Entity" }, { value: "featureView", text: "Feature View" }, + { value: "labelView", text: "Label View" }, { value: "featureService", text: "Feature Service" }, + ...(mlflowData?.runs?.length + ? [{ value: "mlflowRun", text: "MLflow Run" }] + : []), ]} value={selectedObjectType} onChange={(e) => { @@ -162,6 +177,7 @@ const RegistryVisualizationTab = () => { } : undefined } + mlflowRuns={mlflowData?.runs?.length ? mlflowData.runs : undefined} /> )} diff --git a/ui/src/components/forms/FeatureFieldEditor.tsx b/ui/src/components/forms/FeatureFieldEditor.tsx new file mode 100644 index 00000000000..be8b4f9f210 --- /dev/null +++ b/ui/src/components/forms/FeatureFieldEditor.tsx @@ -0,0 +1,163 @@ +import React from "react"; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFieldText, + EuiSelect, + EuiButtonEmpty, + EuiButtonIcon, + EuiText, + EuiHorizontalRule, + EuiSpacer, + EuiCallOut, +} from "@elastic/eui"; +import { VALUE_TYPE_OPTIONS } from "./ValueTypeSelect"; +import { feast } from "../../protos"; + +interface FeatureFieldEntry { + name: string; + valueType: string; + description: string; +} + +interface FeatureFieldEditorProps { + features: FeatureFieldEntry[]; + onChange: (features: FeatureFieldEntry[]) => void; + error?: string; +} + +const EMPTY_FEATURE: FeatureFieldEntry = { + name: "", + valueType: String(feast.types.ValueType.Enum.INT64), + description: "", +}; + +const FeatureFieldEditor: React.FC = ({ + features, + onChange, + error, +}) => { + const addFeature = () => { + onChange([...features, { ...EMPTY_FEATURE }]); + }; + + const removeFeature = (index: number) => { + onChange(features.filter((_, i) => i !== index)); + }; + + const updateFeature = ( + index: number, + field: keyof FeatureFieldEntry, + val: string, + ) => { + const updated = [...features]; + updated[index] = { ...updated[index], [field]: val }; + onChange(updated); + }; + + return ( + <> + + + + +

Features

+
+
+ + + Add feature + + +
+ + {error && ( + <> + + + + )} + + {features.length > 0 && ( + + + + Name + + + + + Type + + + + + Description + + + + + )} + + {features.map((feature, index) => ( + + + updateFeature(index, "name", e.target.value)} + compressed + /> + + + + updateFeature(index, "valueType", e.target.value) + } + compressed + /> + + + + updateFeature(index, "description", e.target.value) + } + compressed + /> + + + removeFeature(index)} + /> + + + ))} + + {features.length === 0 && ( + + No features added yet. Click "Add feature" above. + + )} + + ); +}; + +export default FeatureFieldEditor; +export type { FeatureFieldEntry }; diff --git a/ui/src/components/forms/FormModal.tsx b/ui/src/components/forms/FormModal.tsx new file mode 100644 index 00000000000..b205f9f35a2 --- /dev/null +++ b/ui/src/components/forms/FormModal.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import { + EuiModal, + EuiModalHeader, + EuiModalHeaderTitle, + EuiModalBody, + EuiModalFooter, + EuiButton, + EuiButtonEmpty, + EuiForm, +} from "@elastic/eui"; + +interface FormModalProps { + title: string; + submitLabel: string; + onClose: () => void; + onSubmit: () => void; + children: React.ReactNode; + width?: number; + isSubmitting?: boolean; +} + +const FormModal: React.FC = ({ + title, + submitLabel, + onClose, + onSubmit, + children, + width = 600, + isSubmitting = false, +}) => { + return ( + + + {title} + + + + {children} + + + + + Cancel + + + {submitLabel} + + + + ); +}; + +export default FormModal; diff --git a/ui/src/components/forms/NameDescriptionOwnerFields.tsx b/ui/src/components/forms/NameDescriptionOwnerFields.tsx new file mode 100644 index 00000000000..46d21c369ba --- /dev/null +++ b/ui/src/components/forms/NameDescriptionOwnerFields.tsx @@ -0,0 +1,70 @@ +import React from "react"; +import { EuiFormRow, EuiFieldText, EuiTextArea } from "@elastic/eui"; + +interface NameDescriptionOwnerFieldsProps { + name: string; + description: string; + owner?: string; + onChangeName: (value: string) => void; + onChangeDescription: (value: string) => void; + onChangeOwner?: (value: string) => void; + nameDisabled?: boolean; + nameError?: string; + nameHelpText?: string; + namePlaceholder?: string; + descriptionPlaceholder?: string; +} + +const NameDescriptionOwnerFields: React.FC = ({ + name, + description, + owner, + onChangeName, + onChangeDescription, + onChangeOwner, + nameDisabled = false, + nameError, + nameHelpText, + namePlaceholder = "e.g. my_resource", + descriptionPlaceholder = "Describe this resource...", +}) => { + return ( + <> + + onChangeName(e.target.value)} + isInvalid={!!nameError} + disabled={nameDisabled} + placeholder={namePlaceholder} + /> + + + + onChangeDescription(e.target.value)} + placeholder={descriptionPlaceholder} + rows={2} + /> + + + {onChangeOwner !== undefined && ( + + onChangeOwner(e.target.value)} + placeholder="e.g. team-ml-platform" + /> + + )} + + ); +}; + +export default NameDescriptionOwnerFields; diff --git a/ui/src/components/forms/TagsEditor.tsx b/ui/src/components/forms/TagsEditor.tsx new file mode 100644 index 00000000000..73ea5df9c82 --- /dev/null +++ b/ui/src/components/forms/TagsEditor.tsx @@ -0,0 +1,112 @@ +import React from "react"; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFieldText, + EuiButtonEmpty, + EuiButtonIcon, + EuiText, + EuiHorizontalRule, + EuiSpacer, + EuiCallOut, +} from "@elastic/eui"; + +interface TagEntry { + key: string; + value: string; +} + +interface TagsEditorProps { + tags: TagEntry[]; + onChange: (tags: TagEntry[]) => void; + error?: string; +} + +const TagsEditor: React.FC = ({ tags, onChange, error }) => { + const addTag = () => { + onChange([...tags, { key: "", value: "" }]); + }; + + const removeTag = (index: number) => { + onChange(tags.filter((_, i) => i !== index)); + }; + + const updateTag = (index: number, field: "key" | "value", val: string) => { + const updated = [...tags]; + updated[index] = { ...updated[index], [field]: val }; + onChange(updated); + }; + + return ( + <> + + + + +

Labels

+
+
+ + + Add label + + +
+ + {error && ( + <> + + + + )} + + {tags.map((tag, index) => ( + + + updateTag(index, "key", e.target.value)} + compressed + /> + + + updateTag(index, "value", e.target.value)} + compressed + /> + + + removeTag(index)} + /> + + + ))} + + {tags.length === 0 && ( + + No labels added yet. + + )} + + ); +}; + +export default TagsEditor; +export type { TagEntry }; diff --git a/ui/src/components/forms/ValueTypeSelect.tsx b/ui/src/components/forms/ValueTypeSelect.tsx new file mode 100644 index 00000000000..2718b7c027e --- /dev/null +++ b/ui/src/components/forms/ValueTypeSelect.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { EuiFormRow, EuiSelect } from "@elastic/eui"; +import { feast } from "../../protos"; + +const VALUE_TYPE_OPTIONS = [ + { value: String(feast.types.ValueType.Enum.STRING), text: "STRING" }, + { value: String(feast.types.ValueType.Enum.INT32), text: "INT32" }, + { value: String(feast.types.ValueType.Enum.INT64), text: "INT64" }, + { value: String(feast.types.ValueType.Enum.FLOAT), text: "FLOAT" }, + { value: String(feast.types.ValueType.Enum.DOUBLE), text: "DOUBLE" }, + { value: String(feast.types.ValueType.Enum.BOOL), text: "BOOL" }, + { value: String(feast.types.ValueType.Enum.BYTES), text: "BYTES" }, + { + value: String(feast.types.ValueType.Enum.UNIX_TIMESTAMP), + text: "UNIX_TIMESTAMP", + }, +]; + +interface ValueTypeSelectProps { + value: string; + onChange: (value: string) => void; + label?: string; + helpText?: string; + compressed?: boolean; +} + +const ValueTypeSelect: React.FC = ({ + value, + onChange, + label = "Value Type", + helpText, + compressed = false, +}) => { + return ( + + onChange(e.target.value)} + compressed={compressed} + /> + + ); +}; + +export default ValueTypeSelect; +export { VALUE_TYPE_OPTIONS }; diff --git a/ui/src/contexts/DataModeContext.tsx b/ui/src/contexts/DataModeContext.tsx new file mode 100644 index 00000000000..c8ef4ea0bab --- /dev/null +++ b/ui/src/contexts/DataModeContext.tsx @@ -0,0 +1,20 @@ +import React, { useContext } from "react"; + +interface FetchOptions { + headers?: Record; + credentials?: RequestCredentials; +} + +interface DataModeConfig { + fetchOptions?: FetchOptions; +} + +const defaultConfig: DataModeConfig = {}; + +const DataModeContext = React.createContext(defaultConfig); + +const useDataMode = () => useContext(DataModeContext); + +export default DataModeContext; +export { useDataMode }; +export type { DataModeConfig, FetchOptions }; diff --git a/ui/src/contexts/MonitoringContext.ts b/ui/src/contexts/MonitoringContext.ts new file mode 100644 index 00000000000..f701cbcd5bf --- /dev/null +++ b/ui/src/contexts/MonitoringContext.ts @@ -0,0 +1,14 @@ +import React from "react"; + +interface MonitoringConfig { + apiBaseUrl: string; + enabled: boolean; +} + +const MonitoringContext = React.createContext({ + apiBaseUrl: "/api/v1", + enabled: false, +}); + +export default MonitoringContext; +export type { MonitoringConfig }; diff --git a/ui/src/contexts/ProjectListContext.ts b/ui/src/contexts/ProjectListContext.ts index c42b22f6611..a230300be3b 100644 --- a/ui/src/contexts/ProjectListContext.ts +++ b/ui/src/contexts/ProjectListContext.ts @@ -13,6 +13,7 @@ const ProjectEntrySchema = z.object({ const ProjectsListSchema = z.object({ default: z.string().optional(), projects: z.array(ProjectEntrySchema), + mode: z.string().optional(), }); type ProjectsListType = z.infer; diff --git a/ui/src/custom-tabs/TabsRegistryContext.tsx b/ui/src/custom-tabs/TabsRegistryContext.tsx index 38c9ccea486..4152edd832d 100644 --- a/ui/src/custom-tabs/TabsRegistryContext.tsx +++ b/ui/src/custom-tabs/TabsRegistryContext.tsx @@ -16,7 +16,6 @@ import FeatureCustomTabLoadingWrapper from "../utils/custom-tabs/FeatureCustomTa import DataSourceCustomTabLoadingWrapper from "../utils/custom-tabs/DataSourceCustomTabLoadingWrapper"; import EntityCustomTabLoadingWrapper from "../utils/custom-tabs/EntityCustomTabLoadingWrapper"; import DatasetCustomTabLoadingWrapper from "../utils/custom-tabs/DatasetCustomTabLoadingWrapper"; -import CurlGeneratorTab from "../pages/feature-views/CurlGeneratorTab"; import { RegularFeatureViewCustomTabRegistrationInterface, diff --git a/ui/src/graphics/LabelViewIcon.tsx b/ui/src/graphics/LabelViewIcon.tsx new file mode 100644 index 00000000000..d154e8731a1 --- /dev/null +++ b/ui/src/graphics/LabelViewIcon.tsx @@ -0,0 +1,28 @@ +import React from "react"; + +const LabelViewIcon = (props: React.SVGProps) => { + return ( + + + + + + ); +}; + +export { LabelViewIcon }; diff --git a/ui/src/hooks/useFCOExploreSuggestions.ts b/ui/src/hooks/useFCOExploreSuggestions.ts index 43a0e1bea3f..9068eefa0d4 100644 --- a/ui/src/hooks/useFCOExploreSuggestions.ts +++ b/ui/src/hooks/useFCOExploreSuggestions.ts @@ -22,6 +22,9 @@ const FCO_TO_URL_NAME_MAP: Record = { entity: "/entity", featureView: "/feature-view", featureService: "/feature-service", + labelView: "/label-view", + mlflowRun: "/mlflow-run", + mlflowModel: "/mlflow-model", }; const createSearchLink = ( diff --git a/ui/src/hooks/useTagsAggregation.ts b/ui/src/hooks/useTagsAggregation.ts index 5d36fd54285..9ad0d78d6f5 100644 --- a/ui/src/hooks/useTagsAggregation.ts +++ b/ui/src/hooks/useTagsAggregation.ts @@ -1,13 +1,13 @@ -import { useContext, useMemo } from "react"; -import RegistryPathContext from "../contexts/RegistryPathContext"; -import useLoadRegistry from "../queries/useLoadRegistry"; -import { feast } from "../protos"; +import { useMemo } from "react"; +import { useParams } from "react-router-dom"; +import useResourceQuery, { + featureViewListPath, + featureServiceListPath, +} from "../queries/useResourceQuery"; -// Usage of generic type parameter T -// https://stackoverflow.com/questions/53203409/how-to-tell-typescript-that-im-returning-an-array-of-arrays-of-the-input-type const buildTagCollection = ( array: T[], - recordExtractor: (unknownFCO: T) => Record | undefined, // Assumes that tags are always a Record + recordExtractor: (unknownFCO: T) => Record | undefined, ): Record> => { const tagCollection = array.reduce( (memo: Record>, fco: T) => { @@ -38,17 +38,17 @@ const buildTagCollection = ( }; const useFeatureViewTagsAggregation = () => { - const registryUrl = useContext(RegistryPathContext); - const query = useLoadRegistry(registryUrl); + const { projectName } = useParams(); + const query = useResourceQuery({ + resourceType: "tags-fvs", + project: projectName, + restPath: featureViewListPath(projectName), + restSelect: (d) => d.featureViews, + }); const data = useMemo(() => { - return query.data && query.data.objects && query.data.objects.featureViews - ? buildTagCollection( - query.data.objects.featureViews!, - (fv) => { - return fv.spec?.tags!; - }, - ) + return query.data + ? buildTagCollection(query.data, (fv) => fv.spec?.tags) : undefined; }, [query.data]); @@ -59,19 +59,17 @@ const useFeatureViewTagsAggregation = () => { }; const useFeatureServiceTagsAggregation = () => { - const registryUrl = useContext(RegistryPathContext); - const query = useLoadRegistry(registryUrl); + const { projectName } = useParams(); + const query = useResourceQuery({ + resourceType: "tags-fss", + project: projectName, + restPath: featureServiceListPath(projectName), + restSelect: (d) => d.featureServices, + }); const data = useMemo(() => { - return query.data && - query.data.objects && - query.data.objects.featureServices - ? buildTagCollection( - query.data.objects.featureServices, - (fs) => { - return fs.spec?.tags!; - }, - ) + return query.data + ? buildTagCollection(query.data, (fs) => fs.spec?.tags) : undefined; }, [query.data]); diff --git a/ui/src/mocks/handlers.ts b/ui/src/mocks/handlers.ts index 1c32bb2cf87..d9fb8a031b7 100644 --- a/ui/src/mocks/handlers.ts +++ b/ui/src/mocks/handlers.ts @@ -1,10 +1,48 @@ import { http, HttpResponse } from "msw"; import { readFileSync } from "fs"; import path from "path"; +import { feast } from "../protos"; -const registry = readFileSync( +const registryBuf = readFileSync( path.resolve(__dirname, "../../public/registry.db"), ); +const parsedRegistry = feast.core.Registry.decode(registryBuf); + +const toJSON = (obj: any) => (obj && obj.toJSON ? obj.toJSON() : obj); + +const entitiesJSON = (parsedRegistry.entities || []).map(toJSON); +const featureViewsJSON = (parsedRegistry.featureViews || []).map((fv) => ({ + ...toJSON(fv), + type: "featureView", +})); +const onDemandFVsJSON = (parsedRegistry.onDemandFeatureViews || []).map( + (fv) => ({ + ...toJSON(fv), + type: "onDemandFeatureView", + }), +); +const streamFVsJSON = (parsedRegistry.streamFeatureViews || []).map((fv) => ({ + ...toJSON(fv), + type: "streamFeatureView", +})); +const allFeatureViewsJSON = [ + ...featureViewsJSON, + ...onDemandFVsJSON, + ...streamFVsJSON, +]; +const featureServicesJSON = (parsedRegistry.featureServices || []).map(toJSON); +const dataSourcesJSON = (parsedRegistry.dataSources || []).map(toJSON); +const savedDatasetsJSON = (parsedRegistry.savedDatasets || []).map(toJSON); +const projectsJSON = (parsedRegistry.projects || []).map(toJSON); + +const allFeatures = featureViewsJSON.flatMap((fv: any) => + (fv?.spec?.features || []).map((f: any) => ({ + name: f.name, + featureViewName: fv.spec?.name, + valueType: f.valueType, + project: fv.spec?.project, + })), +); const projectsListWithDefaultProject = http.get("/projects-list.json", () => HttpResponse.json({ @@ -14,22 +52,266 @@ const projectsListWithDefaultProject = http.get("/projects-list.json", () => name: "Credit Score Project", description: "Project for credit scoring team and associated models.", id: "credit_scoring_aws", - registryPath: "/registry.db", // Changed to match what the test expects + registryPath: "/api/v1", }, ], }), ); -const creditHistoryRegistryPB = http.get("/registry.pb", () => { - return HttpResponse.arrayBuffer(registry.buffer); -}); +// REST API list endpoints +const restEntities = http.get("/api/v1/entities", () => + HttpResponse.json({ + entities: entitiesJSON, + pagination: {}, + relationships: {}, + }), +); + +const restFeatureViews = http.get("/api/v1/feature_views", () => + HttpResponse.json({ + featureViews: allFeatureViewsJSON, + pagination: {}, + relationships: {}, + }), +); + +const restFeatureServices = http.get("/api/v1/feature_services", () => + HttpResponse.json({ + featureServices: featureServicesJSON, + pagination: {}, + relationships: {}, + }), +); + +const restDataSources = http.get("/api/v1/data_sources", () => + HttpResponse.json({ + dataSources: dataSourcesJSON, + pagination: {}, + relationships: {}, + }), +); + +const restSavedDatasets = http.get("/api/v1/saved_datasets", () => + HttpResponse.json({ + savedDatasets: savedDatasetsJSON, + pagination: {}, + }), +); + +const restProjects = http.get("/api/v1/projects", () => + HttpResponse.json({ + projects: projectsJSON, + pagination: {}, + }), +); + +const restFeatures = http.get("/api/v1/features", () => + HttpResponse.json({ + features: allFeatures, + pagination: {}, + }), +); -const creditHistoryRegistryDB = http.get("/registry.db", () => { - return HttpResponse.arrayBuffer(registry.buffer); +const restPermissions = http.get("/api/v1/permissions", () => + HttpResponse.json({ + permissions: [], + pagination: {}, + }), +); + +// Detail endpoints +const restFeatureViewDetail = http.get( + "/api/v1/feature_views/:name", + ({ params }) => { + const name = params.name as string; + const fv = allFeatureViewsJSON.find((f: any) => f.spec?.name === name); + if (!fv) return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json(fv); + }, +); + +const restEntityDetail = http.get("/api/v1/entities/:name", ({ params }) => { + const name = params.name as string; + const entity = entitiesJSON.find((e: any) => e.spec?.name === name); + if (!entity) + return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json(entity); }); -export { +const restFeatureServiceDetail = http.get( + "/api/v1/feature_services/:name", + ({ params }) => { + const name = params.name as string; + const fs = featureServicesJSON.find((f: any) => f.spec?.name === name); + if (!fs) return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json(fs); + }, +); + +const restDataSourceDetail = http.get( + "/api/v1/data_sources/:name", + ({ params }) => { + const name = params.name as string; + const ds = dataSourcesJSON.find((d: any) => d.name === name); + if (!ds) return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json(ds); + }, +); + +const restFeatureDetail = http.get( + "/api/v1/features/:fvName/:featureName", + ({ params }) => { + const fvName = params.fvName as string; + const featureName = params.featureName as string; + const fv = allFeatureViewsJSON.find((f: any) => f.spec?.name === fvName); + if (!fv) return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + const feature = (fv as any).spec?.features?.find( + (f: any) => f.name === featureName, + ); + if (!feature) + return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json({ + featureViewName: fvName, + featureName, + feature, + featureView: fv, + }); + }, +); + +// "all" endpoints (for global search / all-projects view) +const restEntitiesAll = http.get("/api/v1/entities/all", () => + HttpResponse.json({ + entities: entitiesJSON.map((e: any) => ({ + ...e, + project: e.spec?.project, + })), + pagination: {}, + relationships: {}, + }), +); + +const restFeatureViewsAll = http.get("/api/v1/feature_views/all", () => + HttpResponse.json({ + featureViews: allFeatureViewsJSON.map((fv: any) => ({ + ...fv, + project: fv.spec?.project, + })), + pagination: {}, + relationships: {}, + }), +); + +const restFeatureServicesAll = http.get("/api/v1/feature_services/all", () => + HttpResponse.json({ + featureServices: featureServicesJSON.map((fs: any) => ({ + ...fs, + project: fs.spec?.project, + })), + pagination: {}, + relationships: {}, + }), +); + +const restDataSourcesAll = http.get("/api/v1/data_sources/all", () => + HttpResponse.json({ + dataSources: dataSourcesJSON.map((ds: any) => ({ + ...ds, + project: ds.project, + })), + pagination: {}, + relationships: {}, + }), +); + +const restSavedDatasetsAll = http.get("/api/v1/saved_datasets/all", () => + HttpResponse.json({ + savedDatasets: savedDatasetsJSON, + pagination: {}, + }), +); + +const restFeaturesAll = http.get("/api/v1/features/all", () => + HttpResponse.json({ + features: allFeatures, + pagination: {}, + }), +); + +const restSavedDatasetDetail = http.get( + "/api/v1/saved_datasets/:name", + ({ params }) => { + const name = params.name as string; + const sd = savedDatasetsJSON.find((d: any) => d.spec?.name === name); + if (!sd) return HttpResponse.json({ detail: "Not found" }, { status: 404 }); + return HttpResponse.json(sd); + }, +); + +const restLabelViews = http.get("/api/v1/label_views", () => + HttpResponse.json({ + featureViews: [], + pagination: {}, + relationships: {}, + }), +); + +const restLabelViewsAll = http.get("/api/v1/label_views/all", () => + HttpResponse.json({ + featureViews: [], + pagination: {}, + relationships: {}, + }), +); + +const restLabels = http.get("/api/v1/labels", () => + HttpResponse.json({ + labels: [], + pagination: {}, + }), +); + +const restLabelsAll = http.get("/api/v1/labels/all", () => + HttpResponse.json({ + labels: [], + pagination: {}, + }), +); + +const restMetrics = http.get("/api/v1/metrics/:type", () => + HttpResponse.json({}), +); + +const allRestHandlers = [ projectsListWithDefaultProject, - creditHistoryRegistryPB as creditHistoryRegistry, - creditHistoryRegistryDB, -}; + // "all" endpoints must come before parameterized detail routes + restEntitiesAll, + restFeatureViewsAll, + restFeatureServicesAll, + restDataSourcesAll, + restSavedDatasetsAll, + restFeaturesAll, + restLabelViewsAll, + restLabelsAll, + // List endpoints + restEntities, + restFeatureViews, + restFeatureServices, + restDataSources, + restSavedDatasets, + restProjects, + restFeatures, + restLabelViews, + restLabels, + restPermissions, + // Detail endpoints + restFeatureViewDetail, + restEntityDetail, + restFeatureServiceDetail, + restDataSourceDetail, + restSavedDatasetDetail, + restFeatureDetail, + restMetrics, +]; + +export { projectsListWithDefaultProject, allRestHandlers }; diff --git a/ui/src/pages/Layout.tsx b/ui/src/pages/Layout.tsx index 0e3341b8820..d59c865ad88 100644 --- a/ui/src/pages/Layout.tsx +++ b/ui/src/pages/Layout.tsx @@ -54,47 +54,6 @@ const Layout = () => { // Load unfiltered data for global search (across all projects) const { data: globalData } = useLoadRegistry(globalRegistryPath); - // Categories for page-level search (filtered to current project) - const categories = data - ? [ - { - name: "Data Sources", - data: data.objects.dataSources || [], - getLink: (item: any) => `/p/${projectName}/data-source/${item.name}`, - }, - { - name: "Entities", - data: data.objects.entities || [], - getLink: (item: any) => `/p/${projectName}/entity/${item.name}`, - }, - { - name: "Features", - data: data.allFeatures || [], - getLink: (item: any) => { - const featureView = item?.featureView; - return featureView - ? `/p/${projectName}/feature-view/${featureView}/feature/${item.name}` - : "#"; - }, - }, - { - name: "Feature Views", - data: data.mergedFVList || [], - getLink: (item: any) => `/p/${projectName}/feature-view/${item.name}`, - }, - { - name: "Feature Services", - data: data.objects.featureServices || [], - getLink: (item: any) => { - const serviceName = item?.name || item?.spec?.name; - return serviceName - ? `/p/${projectName}/feature-service/${serviceName}` - : "#"; - }, - }, - ] - : []; - // Helper function to extract project ID from an item const getProjectId = (item: any): string => { // Try different possible locations for the project field @@ -151,6 +110,18 @@ const Layout = () => { return `/p/${project}/feature-view/${item.name}`; }, }, + { + name: "Label Views", + data: (globalData.objects.labelViews || []).map((item: any) => ({ + ...item, + projectId: getProjectId(item), + })), + getLink: (item: any) => { + const lvName = item?.name || item?.spec?.name; + const project = item?.projectId || getProjectId(item); + return `/p/${project}/label-view/${lvName}`; + }, + }, { name: "Feature Services", data: (globalData.objects.featureServices || []).map((item: any) => ({ @@ -246,7 +217,7 @@ const Layout = () => { width: "100%", }} > - + { categories={globalCategories} /> + )} diff --git a/ui/src/pages/ProjectOverviewPage.tsx b/ui/src/pages/ProjectOverviewPage.tsx index 839fbcc5d89..ef4b39427ce 100644 --- a/ui/src/pages/ProjectOverviewPage.tsx +++ b/ui/src/pages/ProjectOverviewPage.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React from "react"; import { EuiPageTemplate, EuiText, @@ -7,8 +7,6 @@ import { EuiTitle, EuiSpacer, EuiSkeletonText, - EuiEmptyPrompt, - EuiFieldSearch, EuiPanel, EuiStat, EuiCard, @@ -17,54 +15,86 @@ import { import { useDocumentTitle } from "../hooks/useDocumentTitle"; import ObjectsCountStats from "../components/ObjectsCountStats"; import ExplorePanel from "../components/ExplorePanel"; -import useLoadRegistry from "../queries/useLoadRegistry"; -import RegistryPathContext from "../contexts/RegistryPathContext"; -import RegistryVisualizationTab from "../components/RegistryVisualizationTab"; -import RegistrySearch from "../components/RegistrySearch"; +import useResourceQuery, { + restFeatureViewsToMergedList, + restLabelViewsFromResponse, +} from "../queries/useResourceQuery"; import { useParams, useNavigate } from "react-router-dom"; import { useLoadProjectsList } from "../contexts/ProjectListContext"; +import type { genericFVType } from "../parsers/mergedFVTypes"; + +const getItemProject = (item: any): string => + item?.project || item?.spec?.project || ""; // Component for "All Projects" view const AllProjectsDashboard = () => { - const registryUrl = useContext(RegistryPathContext); const navigate = useNavigate(); const { data: projectsData } = useLoadProjectsList(); - const { data: registryData } = useLoadRegistry(registryUrl); - if (!registryData) { + const { data: allFVs } = useResourceQuery({ + resourceType: "all-proj-fvs", + restPath: "/feature_views/all?limit=100&include_relationships=true", + restSelect: restFeatureViewsToMergedList, + }); + + const { data: allEntities } = useResourceQuery({ + resourceType: "all-proj-entities", + restPath: "/entities/all?limit=100", + restSelect: (d) => d.entities, + }); + + const { data: allDS } = useResourceQuery({ + resourceType: "all-proj-ds", + restPath: "/data_sources/all?limit=100", + restSelect: (d) => d.dataSources, + }); + + const { data: allFS } = useResourceQuery({ + resourceType: "all-proj-fs", + restPath: "/feature_services/all?limit=100", + restSelect: (d) => d.featureServices, + }); + + const { data: allFeatures } = useResourceQuery({ + resourceType: "all-proj-features", + restPath: "/features/all?limit=100", + restSelect: (d) => d.features, + }); + + const { data: allLabelViews } = useResourceQuery({ + resourceType: "all-proj-lvs", + restPath: "/label_views/all?limit=100&include_relationships=true", + restSelect: restLabelViewsFromResponse, + }); + + const loaded = + allFVs && allEntities && allDS && allFS && allFeatures && allLabelViews; + + if (!loaded) { return ; } - // Calculate total counts across all projects const totalCounts = { - featureViews: registryData.objects.featureViews?.length || 0, - entities: registryData.objects.entities?.length || 0, - dataSources: registryData.objects.dataSources?.length || 0, - featureServices: registryData.objects.featureServices?.length || 0, - features: registryData.allFeatures?.length || 0, + featureViews: allFVs.length, + entities: allEntities.length, + dataSources: allDS.length, + featureServices: allFS.length, + features: allFeatures.length, + labelViews: allLabelViews?.length || 0, }; - // Get projects from registry and count their objects const projects = projectsData?.projects.filter((p) => p.id !== "all") || []; const projectStats = projects.map((project) => { - const projectFVs = - registryData.objects.featureViews?.filter( - (fv: any) => fv?.spec?.project === project.id, - ) || []; - const projectEntities = - registryData.objects.entities?.filter( - (e: any) => e?.spec?.project === project.id, - ) || []; - const projectFeatures = - registryData.allFeatures?.filter((f: any) => f?.project === project.id) || - []; + const matchesProject = (item: any) => getItemProject(item) === project.id; return { ...project, counts: { - featureViews: projectFVs.length, - entities: projectEntities.length, - features: projectFeatures.length, + featureViews: allFVs.filter((fv) => matchesProject(fv.object || fv)) + .length, + entities: allEntities.filter(matchesProject).length, + features: allFeatures.filter(matchesProject).length, + labelViews: (allLabelViews || []).filter(matchesProject).length, }, }; }); @@ -133,6 +163,25 @@ const AllProjectsDashboard = () => { /> + {totalCounts.labelViews > 0 && ( + + + + + + + + + + + + + )} @@ -183,6 +232,17 @@ const AllProjectsDashboard = () => { + {project.counts.labelViews > 0 && ( + + + {project.counts.labelViews} +
+ + Label Views + +
+
+ )} @@ -195,112 +255,59 @@ const AllProjectsDashboard = () => { const ProjectOverviewPage = () => { useDocumentTitle("Feast Home"); - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams<{ projectName: string }>(); - const { isLoading, isSuccess, isError, data } = useLoadRegistry( - registryUrl, - projectName, - ); + const { data: projectsData } = useLoadProjectsList(); // Show aggregated dashboard for "All Projects" view if (projectName === "all") { return ; } - const categories = [ - { - name: "Data Sources", - data: data?.objects.dataSources || [], - getLink: (item: any) => `/p/${projectName}/data-source/${item.name}`, - }, - { - name: "Entities", - data: data?.objects.entities || [], - getLink: (item: any) => `/p/${projectName}/entity/${item.name}`, - }, - { - name: "Features", - data: data?.allFeatures || [], - getLink: (item: any) => { - const featureView = item?.featureView; - return featureView - ? `/p/${projectName}/feature-view/${featureView}/feature/${item.name}` - : "#"; - }, - }, - { - name: "Feature Views", - data: data?.mergedFVList || [], - getLink: (item: any) => `/p/${projectName}/feature-view/${item.name}`, - }, - { - name: "Feature Services", - data: data?.objects.featureServices || [], - getLink: (item: any) => { - const serviceName = item?.name || item?.spec?.name; - return serviceName - ? `/p/${projectName}/feature-service/${serviceName}` - : "#"; - }, - }, - ]; + const currentProject = projectsData?.projects.find( + (p) => p.id === projectName, + ); return (

- {isLoading && } - {isSuccess && data?.project && `Project: ${data.project}`} + {currentProject + ? `Project: ${currentProject.name}` + : projectName + ? `Project: ${projectName}` + : ""}

- {isLoading && } - {isError && ( - Error Loading Project Configs} - body={ -

- There was an error loading the Project Configurations. - Please check that feature_store.yaml file is - available and well-formed. -

- } - /> + {currentProject?.description ? ( + +
{currentProject.description}
+
+ ) : ( + +

+ Welcome to your new Feast project. In this UI, you can see + Data Sources, Entities, Features, Feature Views, and Feature + Services registered in Feast. +

+

+ It looks like this project already has some objects + registered. If you are new to this project, we suggest + starting by exploring the Feature Services, as they represent + the collection of Feature Views serving a particular model. +

+

+ Note: We encourage you to replace this + welcome message with more suitable content for your team. You + can do so by specifying a project_description in + your feature_store.yaml file. +

+
)} - {isSuccess && - (data?.description ? ( - -
{data.description}
-
- ) : ( - -

- Welcome to your new Feast project. In this UI, you can see - Data Sources, Entities, Features, Feature Views, and Feature - Services registered in Feast. -

-

- It looks like this project already has some objects - registered. If you are new to this project, we suggest - starting by exploring the Feature Services, as they - represent the collection of Feature Views serving a - particular model. -

-

- Note: We encourage you to replace this - welcome message with more suitable content for your team. - You can do so by specifying a{" "} - project_description in your{" "} - feature_store.yaml file. -

-
- ))}
diff --git a/ui/src/pages/Sidebar.tsx b/ui/src/pages/Sidebar.tsx index 55c8ec805c9..c7fffeb1fd4 100644 --- a/ui/src/pages/Sidebar.tsx +++ b/ui/src/pages/Sidebar.tsx @@ -1,10 +1,19 @@ -import React, { useContext, useState } from "react"; +import React, { useState } from "react"; import { EuiIcon, EuiSideNav, htmlIdGenerator } from "@elastic/eui"; import { Link, useParams } from "react-router-dom"; import { useMatchSubpath } from "../hooks/useMatchSubpath"; -import useLoadRegistry from "../queries/useLoadRegistry"; -import RegistryPathContext from "../contexts/RegistryPathContext"; +import useResourceQuery, { + entityListPath, + featureViewListPath, + featureServiceListPath, + dataSourceListPath, + savedDatasetListPath, + featuresListPath, + labelViewListPath, + restFeatureViewsToMergedList, + restLabelViewsFromResponse, +} from "../queries/useResourceQuery"; import { DataSourceIcon } from "../graphics/DataSourceIcon"; import { EntityIcon } from "../graphics/EntityIcon"; @@ -14,11 +23,66 @@ import { DatasetIcon } from "../graphics/DatasetIcon"; import { FeatureIcon } from "../graphics/FeatureIcon"; import { HomeIcon } from "../graphics/HomeIcon"; import { PermissionsIcon } from "../graphics/PermissionsIcon"; +import { LabelViewIcon } from "../graphics/LabelViewIcon"; +import type { genericFVType } from "../parsers/mergedFVTypes"; const SideNav = () => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const { isSuccess, data } = useLoadRegistry(registryUrl, projectName); + + const { isSuccess: dsSuccess, data: dataSources } = useResourceQuery({ + resourceType: "sidebar-ds", + project: projectName, + restPath: dataSourceListPath(projectName), + restSelect: (d) => d.dataSources, + }); + + const { isSuccess: entSuccess, data: entities } = useResourceQuery({ + resourceType: "sidebar-entities", + project: projectName, + restPath: entityListPath(projectName), + restSelect: (d) => d.entities, + }); + + const { isSuccess: fvSuccess, data: featureViews } = useResourceQuery< + genericFVType[] + >({ + resourceType: "sidebar-fvs", + project: projectName, + restPath: featureViewListPath(projectName), + restSelect: restFeatureViewsToMergedList, + }); + + const { isSuccess: featSuccess, data: features } = useResourceQuery({ + resourceType: "sidebar-features", + project: projectName, + restPath: featuresListPath(projectName), + restSelect: (d) => d.features, + }); + + const { isSuccess: fsSuccess, data: featureServices } = useResourceQuery< + any[] + >({ + resourceType: "sidebar-fs", + project: projectName, + restPath: featureServiceListPath(projectName), + restSelect: (d) => d.featureServices, + }); + + const { isSuccess: sdSuccess, data: savedDatasets } = useResourceQuery( + { + resourceType: "sidebar-sd", + project: projectName, + restPath: savedDatasetListPath(projectName), + restSelect: (d) => d.savedDatasets, + }, + ); + + const { isSuccess: lvSuccess, data: labelViews } = useResourceQuery({ + resourceType: "sidebar-lvs", + project: projectName, + restPath: labelViewListPath(projectName), + restSelect: restLabelViewsFromResponse, + }); const [isSideNavOpenOnMobile, setisSideNavOpenOnMobile] = useState(false); @@ -26,43 +90,16 @@ const SideNav = () => { setisSideNavOpenOnMobile(!isSideNavOpenOnMobile); }; - const dataSourcesLabel = `Data Sources ${ - isSuccess && data?.objects.dataSources - ? `(${data?.objects.dataSources?.length})` - : "" - }`; - - const entitiesLabel = `Entities ${ - isSuccess && data?.objects.entities - ? `(${data?.objects.entities?.length})` - : "" - }`; - - const featureViewsLabel = `Feature Views ${ - isSuccess && data?.mergedFVList && data?.mergedFVList.length > 0 - ? `(${data?.mergedFVList.length})` - : "" - }`; - - const featureListLabel = `Features ${ - isSuccess && data?.allFeatures && data?.allFeatures.length > 0 - ? `(${data?.allFeatures.length})` - : "" - }`; - - const featureServicesLabel = `Feature Services ${ - isSuccess && data?.objects.featureServices - ? `(${data?.objects.featureServices?.length})` - : "" - }`; - - const savedDatasetsLabel = `Datasets ${ - isSuccess && data?.objects.savedDatasets - ? `(${data?.objects.savedDatasets?.length})` - : "" - }`; + const dataSourcesLabel = `Data Sources ${dsSuccess && dataSources ? `(${dataSources.length})` : ""}`; + const entitiesLabel = `Entities ${entSuccess && entities ? `(${entities.length})` : ""}`; + const featureViewsLabel = `Feature Views ${fvSuccess && featureViews && featureViews.length > 0 ? `(${featureViews.length})` : ""}`; + const featureListLabel = `Features ${featSuccess && features && features.length > 0 ? `(${features.length})` : ""}`; + const featureServicesLabel = `Feature Services ${fsSuccess && featureServices ? `(${featureServices.length})` : ""}`; + const savedDatasetsLabel = `Datasets ${sdSuccess && savedDatasets ? `(${savedDatasets.length})` : ""}`; + const labelViewsLabel = `Label Views ${lvSuccess && labelViews && labelViews.length > 0 ? `(${labelViews.length})` : ""}`; const baseUrl = `/p/${projectName}`; + const monitoringSelected = useMatchSubpath(`${baseUrl}/monitoring`); const sideNav: React.ComponentProps["items"] = [ { @@ -124,6 +161,15 @@ const SideNav = () => { ), isSelected: useMatchSubpath(`${baseUrl}/feature-service`), }, + { + name: labelViewsLabel, + id: htmlIdGenerator("labelViews")(), + icon: , + renderItem: (props) => ( + + ), + isSelected: useMatchSubpath(`${baseUrl}/label-view`), + }, { name: savedDatasetsLabel, id: htmlIdGenerator("savedDatasets")(), @@ -131,15 +177,6 @@ const SideNav = () => { renderItem: (props) => , isSelected: useMatchSubpath(`${baseUrl}/data-set`), }, - { - name: "Data Labeling", - id: htmlIdGenerator("dataLabeling")(), - icon: , - renderItem: (props) => ( - - ), - isSelected: useMatchSubpath(`${baseUrl}/data-labeling`), - }, { name: "Permissions", id: htmlIdGenerator("permissions")(), @@ -149,6 +186,15 @@ const SideNav = () => { ), isSelected: useMatchSubpath(`${baseUrl}/permissions`), }, + { + name: "Monitoring", + id: htmlIdGenerator("monitoring")(), + icon: , + renderItem: (props: any) => ( + + ), + isSelected: monitoringSelected, + }, ], }, ]; diff --git a/ui/src/pages/data-sources/DataSourceOverviewTab.tsx b/ui/src/pages/data-sources/DataSourceOverviewTab.tsx index d702034a558..6ee71f9a65c 100644 --- a/ui/src/pages/data-sources/DataSourceOverviewTab.tsx +++ b/ui/src/pages/data-sources/DataSourceOverviewTab.tsx @@ -4,6 +4,8 @@ import { EuiLoadingSpinner, EuiText, EuiTitle, + EuiButtonEmpty, + EuiCallOut, } from "@elastic/eui"; import { EuiPanel, @@ -13,29 +15,157 @@ import { EuiDescriptionListDescription, EuiSpacer, } from "@elastic/eui"; -import React, { useContext } from "react"; +import React, { useState } from "react"; import { useParams } from "react-router-dom"; -import PermissionsDisplay from "../../components/PermissionsDisplay"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import { FEAST_FCO_TYPES } from "../../parsers/types"; +import DataSourceFormModal, { + DataSourceFormData, +} from "../../components/DataSourceFormModal"; import { feast } from "../../protos"; -import useLoadRegistry from "../../queries/useLoadRegistry"; -import { getEntityPermissions } from "../../utils/permissionUtils"; +import { useApplyDataSource } from "../../queries/mutations/useDataSourceMutations"; import BatchSourcePropertiesView from "./BatchSourcePropertiesView"; import FeatureViewEdgesList from "../entities/FeatureViewEdgesList"; import RequestDataSourceSchemaTable from "./RequestDataSourceSchemaTable"; import useLoadDataSource from "./useLoadDataSource"; +const buildEditFormData = (ds: any): DataSourceFormData => { + const spec = ds.spec || ds; + const tags = spec.tags + ? Object.entries(spec.tags).map(([key, value]) => ({ + key, + value: value as string, + })) + : []; + + return { + name: spec.name || ds.name || "", + description: spec.description || ds.description || "", + owner: spec.owner || ds.owner || "", + sourceType: String(spec.type ?? ds.type ?? 0), + timestampField: spec.timestampField || ds.timestampField || "", + createdTimestampColumn: + spec.createdTimestampColumn || ds.createdTimestampColumn || "", + tags, + fileUri: spec.fileOptions?.uri || ds.fileOptions?.uri || "", + bigqueryTable: + spec.bigqueryOptions?.table || ds.bigqueryOptions?.table || "", + bigqueryQuery: + spec.bigqueryOptions?.query || ds.bigqueryOptions?.query || "", + snowflakeTable: + spec.snowflakeOptions?.table || ds.snowflakeOptions?.table || "", + snowflakeDatabase: + spec.snowflakeOptions?.database || ds.snowflakeOptions?.database || "", + snowflakeSchema: + spec.snowflakeOptions?.schema || ds.snowflakeOptions?.schema || "", + redshiftTable: + spec.redshiftOptions?.table || ds.redshiftOptions?.table || "", + redshiftDatabase: + spec.redshiftOptions?.database || ds.redshiftOptions?.database || "", + redshiftSchema: + spec.redshiftOptions?.schema || ds.redshiftOptions?.schema || "", + kafkaBootstrapServers: + spec.kafkaOptions?.kafkaBootstrapServers || + ds.kafkaOptions?.kafkaBootstrapServers || + "", + kafkaTopic: spec.kafkaOptions?.topic || ds.kafkaOptions?.topic || "", + sparkTable: spec.sparkOptions?.table || ds.sparkOptions?.table || "", + sparkPath: spec.sparkOptions?.path || ds.sparkOptions?.path || "", + }; +}; + +const formDataToPayload = (formData: DataSourceFormData, project: string) => { + const payload: Record = { + name: formData.name, + project, + type: parseInt(formData.sourceType, 10), + timestamp_field: formData.timestampField, + created_timestamp_column: formData.createdTimestampColumn, + description: formData.description, + owner: formData.owner, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + }; + + const st = formData.sourceType; + if (st === String(feast.core.DataSource.SourceType.BATCH_FILE)) { + payload.file_options = { uri: formData.fileUri }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_BIGQUERY)) { + payload.bigquery_options = { + table: formData.bigqueryTable, + query: formData.bigqueryQuery, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE)) { + payload.snowflake_options = { + table: formData.snowflakeTable, + database: formData.snowflakeDatabase, + schema_: formData.snowflakeSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_REDSHIFT)) { + payload.redshift_options = { + table: formData.redshiftTable, + database: formData.redshiftDatabase, + schema_: formData.redshiftSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.STREAM_KAFKA)) { + payload.kafka_options = { + kafka_bootstrap_servers: formData.kafkaBootstrapServers, + topic: formData.kafkaTopic, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SPARK)) { + payload.spark_options = { + table: formData.sparkTable, + path: formData.sparkPath, + }; + } + + return payload; +}; + const DataSourceOverviewTab = () => { - let { dataSourceName, projectName } = useParams(); - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl, projectName); + const { dataSourceName, projectName } = useParams(); const dsName = dataSourceName === undefined ? "" : dataSourceName; const { isLoading, isSuccess, isError, data, consumingFeatureViews } = useLoadDataSource(dsName); const isEmpty = data === undefined; + const viewTypesForDs: Record | undefined = + consumingFeatureViews && consumingFeatureViews.length > 0 + ? consumingFeatureViews.reduce((acc: Record, f: any) => { + acc[f.target.name] = + f.target.type === "labelView" ? "labelView" : "featureView"; + return acc; + }, {}) + : undefined; + + const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [errorMessage, setErrorMessage] = useState(null); + const applyDataSource = useApplyDataSource(); + + const handleEditSubmit = (formData: DataSourceFormData) => { + const payload = formDataToPayload(formData, projectName || ""); + applyDataSource.mutate(payload as any, { + onSuccess: () => { + setIsEditModalOpen(false); + setErrorMessage(null); + setSuccessMessage( + `Data source "${formData.name}" updated successfully.`, + ); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + // Error shown inside the modal via submitError prop + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setErrorMessage(message); + }, + }); + }; + + const spec = data?.spec || data; + const sourceType = spec?.type; + return ( {isLoading && ( @@ -47,6 +177,39 @@ const DataSourceOverviewTab = () => { {isError &&

Error loading data source: {dataSourceName}

} {isSuccess && data && ( + {successMessage && ( + <> + + + + )} + {errorMessage && ( + <> + + + + )} + + + setIsEditModalOpen(true)} + > + Edit Data Source + + + + @@ -56,16 +219,16 @@ const DataSourceOverviewTab = () => {

Properties

- {data.fileOptions || data.bigqueryOptions ? ( - - ) : data.type ? ( + {spec?.fileOptions || spec?.bigqueryOptions ? ( + + ) : sourceType ? ( Source Type - {feast.core.DataSource.SourceType[data.type]} + {sourceType} @@ -78,7 +241,7 @@ const DataSourceOverviewTab = () => { - {data.requestDataOptions ? ( + {spec?.requestDataOptions ? (

Request Source Schema

@@ -86,7 +249,7 @@ const DataSourceOverviewTab = () => { { + data?.requestDataOptions?.schema!.map((obj: any) => { return { fieldName: obj.name!, valueType: obj.valueType!, @@ -104,43 +267,38 @@ const DataSourceOverviewTab = () => { -

Consuming Feature Views

+

Consuming Views

{consumingFeatureViews && consumingFeatureViews.length > 0 ? ( { + fvNames={consumingFeatureViews.map((f: any) => { return f.target.name; })} + viewTypes={viewTypesForDs} /> ) : ( - No consuming feature views - )} -
- - - -

Permissions

-
- - {registryQuery.data?.permissions ? ( - - ) : ( - - No permissions defined for this data source. - + No consuming views )}
)} + + {isEditModalOpen && data && ( + { + setIsEditModalOpen(false); + setErrorMessage(null); + }} + onSubmit={handleEditSubmit} + initialData={buildEditFormData(data)} + isEdit + isSubmitting={applyDataSource.isLoading} + submitError={errorMessage} + /> + )}
); }; diff --git a/ui/src/pages/data-sources/DataSourcesListingTable.tsx b/ui/src/pages/data-sources/DataSourcesListingTable.tsx index c314a4dfb94..c08060dd0e4 100644 --- a/ui/src/pages/data-sources/DataSourcesListingTable.tsx +++ b/ui/src/pages/data-sources/DataSourcesListingTable.tsx @@ -32,8 +32,11 @@ const DatasourcesListingTable = ({ name: "Type", field: "type", sortable: true, - render: (valueType: feast.core.DataSource.SourceType) => { - return feast.core.DataSource.SourceType[valueType]; + render: (valueType: feast.core.DataSource.SourceType | string) => { + if (typeof valueType === "string") { + return valueType; + } + return feast.core.DataSource.SourceType[valueType] || String(valueType); }, }, ]; diff --git a/ui/src/pages/data-sources/Index.tsx b/ui/src/pages/data-sources/Index.tsx index 96aef712aec..cf44de1770f 100644 --- a/ui/src/pages/data-sources/Index.tsx +++ b/ui/src/pages/data-sources/Index.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React, { useState } from "react"; import { useParams } from "react-router-dom"; import { @@ -9,52 +9,106 @@ import { EuiTitle, EuiFieldSearch, EuiSpacer, + EuiButton, + EuiCallOut, } from "@elastic/eui"; -import useLoadRegistry from "../../queries/useLoadRegistry"; import DatasourcesListingTable from "./DataSourcesListingTable"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; import DataSourceIndexEmptyState from "./DataSourceIndexEmptyState"; import { DataSourceIcon } from "../../graphics/DataSourceIcon"; import { useSearchQuery } from "../../hooks/useSearchInputWithTags"; import { feast } from "../../protos"; import ExportButton from "../../components/ExportButton"; +import DataSourceFormModal, { + DataSourceFormData, +} from "../../components/DataSourceFormModal"; +import { useApplyDataSource } from "../../queries/mutations/useDataSourceMutations"; +import useResourceQuery, { + dataSourceListPath, +} from "../../queries/useResourceQuery"; const useLoadDatasources = () => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.dataSources; - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: "data-sources-list", + project: projectName, + restPath: dataSourceListPath(projectName), + restSelect: (d) => d.dataSources, + }); }; -const filterFn = (data: feast.core.IDataSource[], searchTokens: string[]) => { - let filteredByTags = data; - +const filterFn = (data: any[], searchTokens: string[]) => { if (searchTokens.length) { - return filteredByTags.filter((entry) => { + return data.filter((entry) => { + const name = entry.name || entry.spec?.name || ""; return searchTokens.find((token) => { - return ( - token.length >= 3 && entry.name && entry.name.indexOf(token) >= 0 - ); + return token.length >= 3 && name.indexOf(token) >= 0; }); }); } - return filteredByTags; + return data; +}; + +const formDataToPayload = (formData: DataSourceFormData, project: string) => { + const payload: Record = { + name: formData.name, + project, + type: parseInt(formData.sourceType, 10), + timestamp_field: formData.timestampField, + created_timestamp_column: formData.createdTimestampColumn, + description: formData.description, + owner: formData.owner, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + }; + + const st = formData.sourceType; + if (st === String(feast.core.DataSource.SourceType.BATCH_FILE)) { + payload.file_options = { uri: formData.fileUri }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_BIGQUERY)) { + payload.bigquery_options = { + table: formData.bigqueryTable, + query: formData.bigqueryQuery, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SNOWFLAKE)) { + payload.snowflake_options = { + table: formData.snowflakeTable, + database: formData.snowflakeDatabase, + schema_: formData.snowflakeSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_REDSHIFT)) { + payload.redshift_options = { + table: formData.redshiftTable, + database: formData.redshiftDatabase, + schema_: formData.redshiftSchema, + }; + } else if (st === String(feast.core.DataSource.SourceType.STREAM_KAFKA)) { + payload.kafka_options = { + kafka_bootstrap_servers: formData.kafkaBootstrapServers, + topic: formData.kafkaTopic, + }; + } else if (st === String(feast.core.DataSource.SourceType.BATCH_SPARK)) { + payload.spark_options = { + table: formData.sparkTable, + path: formData.sparkPath, + }; + } + + return payload; }; const Index = () => { + const { projectName } = useParams(); const { isLoading, isSuccess, isError, data } = useLoadDatasources(); + const isAllProjects = projectName === "all"; + + const [isModalOpen, setIsModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [errorMessage, setErrorMessage] = useState(null); + const applyDataSource = useApplyDataSource(); useDocumentTitle(`Data Sources | Feast`); @@ -62,6 +116,26 @@ const Index = () => { const filterResult = data ? filterFn(data, searchTokens) : data; + const handleCreateSubmit = (formData: DataSourceFormData) => { + const payload = formDataToPayload(formData, projectName || ""); + applyDataSource.mutate(payload as any, { + onSuccess: () => { + setIsModalOpen(false); + setErrorMessage(null); + setSuccessMessage( + `Data source "${formData.name}" created successfully.`, + ); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + // Error shown inside the modal via submitError prop + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setErrorMessage(message); + }, + }); + }; + return ( { iconType={DataSourceIcon} pageTitle="Data Sources" rightSideItems={[ + ...(isAllProjects + ? [] + : [ + setIsModalOpen(true)} + key="create" + > + Create Data Source + , + ]), , ]} /> + {successMessage && ( + <> + + + + )} + {errorMessage && ( + <> + + + + )} {isLoading && (

Loading @@ -105,6 +214,18 @@ const Index = () => { )} + + {isModalOpen && ( + { + setIsModalOpen(false); + setErrorMessage(null); + }} + onSubmit={handleCreateSubmit} + isSubmitting={applyDataSource.isLoading} + submitError={errorMessage} + /> + )} ); }; diff --git a/ui/src/pages/data-sources/RequestDataSourceSchemaTable.tsx b/ui/src/pages/data-sources/RequestDataSourceSchemaTable.tsx index a55aeac0280..f671042dd85 100644 --- a/ui/src/pages/data-sources/RequestDataSourceSchemaTable.tsx +++ b/ui/src/pages/data-sources/RequestDataSourceSchemaTable.tsx @@ -20,8 +20,9 @@ const RequestDataSourceSchemaTable = ({ fields }: RequestDataSourceSchema) => { { name: "Value Type", field: "valueType", - render: (valueType: feast.types.ValueType.Enum) => { - return feast.types.ValueType.Enum[valueType]; + render: (valueType: feast.types.ValueType.Enum | string) => { + if (typeof valueType === "string") return valueType; + return feast.types.ValueType.Enum[valueType] || String(valueType || ""); }, }, ]; diff --git a/ui/src/pages/data-sources/useLoadDataSource.ts b/ui/src/pages/data-sources/useLoadDataSource.ts index 43f697fca03..c099e78f917 100644 --- a/ui/src/pages/data-sources/useLoadDataSource.ts +++ b/ui/src/pages/data-sources/useLoadDataSource.ts @@ -1,35 +1,35 @@ -import { useContext } from "react"; import { useParams } from "react-router-dom"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import { FEAST_FCO_TYPES } from "../../parsers/types"; -import useLoadRegistry from "../../queries/useLoadRegistry"; +import useResourceQuery, { + dataSourceDetailPath, +} from "../../queries/useResourceQuery"; const useLoadDataSource = (dataSourceName: string) => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.dataSources?.find( - (ds) => ds.name === dataSourceName, - ); + const dsQuery = useResourceQuery({ + resourceType: `data-source:${dataSourceName}`, + project: projectName, + restPath: dataSourceDetailPath(dataSourceName, projectName || ""), + restSelect: (d) => ({ + dataSource: d, + relationships: d?.relationships || [], + }), + enabled: !!dataSourceName, + }); - const consumingFeatureViews = - registryQuery.data === undefined - ? undefined - : registryQuery.data.relationships.filter((relationship) => { - return ( - relationship.source.type === FEAST_FCO_TYPES.dataSource && - relationship.source.name === data?.name && - relationship.target.type === FEAST_FCO_TYPES.featureView - ); - }); + const dataSource = dsQuery.data?.dataSource; + const relationships = dsQuery.data?.relationships || []; + + const consumingFeatureViews = relationships.filter( + (rel: any) => + rel?.source?.type === "dataSource" && + (rel?.target?.type === "featureView" || + rel?.target?.type === "labelView"), + ); return { - ...registryQuery, - data, + ...dsQuery, + data: dataSource, consumingFeatureViews, }; }; diff --git a/ui/src/pages/document-labeling/ClassificationTab.tsx b/ui/src/pages/document-labeling/ClassificationTab.tsx deleted file mode 100644 index 302b03cd9fa..00000000000 --- a/ui/src/pages/document-labeling/ClassificationTab.tsx +++ /dev/null @@ -1,310 +0,0 @@ -import React, { useState } from "react"; -import { - EuiPageSection, - EuiCallOut, - EuiSpacer, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiFieldText, - EuiButton, - EuiPanel, - EuiTitle, - EuiText, - EuiTable, - EuiTableHeader, - EuiTableHeaderCell, - EuiTableBody, - EuiTableRow, - EuiTableRowCell, - EuiSelect, - EuiLoadingSpinner, -} from "@elastic/eui"; - -interface ClassificationData { - id: number; - text: string; - currentClass: string; - originalClass?: string; -} - -const ClassificationTab = () => { - const [csvPath, setCsvPath] = useState("./src/sample-data.csv"); - const [isLoading, setIsLoading] = useState(false); - const [data, setData] = useState([]); - const [error, setError] = useState(null); - const [availableClasses] = useState(["positive", "negative", "neutral"]); - - const loadCsvData = async () => { - if (!csvPath) return; - - setIsLoading(true); - setError(null); - - try { - if (csvPath === "./src/sample-data.csv") { - const sampleData: ClassificationData[] = [ - { - id: 1, - text: "This product is amazing! I love the quality and design.", - currentClass: "positive", - originalClass: "positive", - }, - { - id: 2, - text: "The service was terrible and the food was cold.", - currentClass: "negative", - originalClass: "negative", - }, - { - id: 3, - text: "It's an okay product, nothing special but does the job.", - currentClass: "neutral", - originalClass: "neutral", - }, - { - id: 4, - text: "Excellent customer support and fast delivery!", - currentClass: "positive", - originalClass: "positive", - }, - { - id: 5, - text: "I'm not sure how I feel about this purchase.", - currentClass: "neutral", - originalClass: "positive", - }, - ]; - - setData(sampleData); - } else { - throw new Error( - "CSV file not found. Please use the sample data path: ./src/sample-data.csv", - ); - } - } catch (err) { - setError( - err instanceof Error - ? err.message - : "An error occurred while loading the CSV data", - ); - } finally { - setIsLoading(false); - } - }; - - const handleClassChange = (id: number, newClass: string) => { - setData( - data.map((item) => - item.id === id ? { ...item, currentClass: newClass } : item, - ), - ); - }; - - const getChangedItems = () => { - return data.filter((item) => item.currentClass !== item.originalClass); - }; - - const resetChanges = () => { - setData( - data.map((item) => ({ ...item, currentClass: item.originalClass || "" })), - ); - }; - - const saveChanges = () => { - const changedItems = getChangedItems(); - console.log("Saving classification changes:", changedItems); - alert(`Saved ${changedItems.length} classification changes!`); - }; - - const columns = [ - { - field: "id", - name: "ID", - width: "60px", - }, - { - field: "text", - name: "Text", - width: "60%", - }, - { - field: "originalClass", - name: "Original Class", - width: "15%", - }, - { - field: "currentClass", - name: "Current Class", - width: "20%", - }, - ]; - - return ( - - -

- Load a CSV file containing text samples and edit their classification - labels. This helps improve your classification models by providing - corrected training data. -

-
- - - - - - - setCsvPath(e.target.value)} - /> - - - - - - Load CSV Data - - - - - - - - {isLoading && ( - - - - - - Loading CSV data... - - - )} - - {error && ( - -

{error}

-
- )} - - {data.length > 0 && ( - <> - - - -

Classification Data ({data.length} samples)

-
-
- - - - - Reset Changes - - - - - Save Changes ({getChangedItems().length}) - - - - -
- - - - - - - {columns.map((column, index) => ( - - {column.name} - - ))} - - - {data.map((item) => ( - - {item.id} - - {item.text} - - - - {item.originalClass} - - - - ({ - value: cls, - text: cls, - }))} - value={item.currentClass} - onChange={(e) => - handleClassChange(item.id, e.target.value) - } - compressed - /> - - - ))} - - - - - {getChangedItems().length > 0 && ( - <> - - -

- You have unsaved changes. Click "Save Changes" to persist your - modifications. -

-
- - )} - - )} - - ); -}; - -export default ClassificationTab; diff --git a/ui/src/pages/document-labeling/DocumentLabelingPage.tsx b/ui/src/pages/document-labeling/DocumentLabelingPage.tsx deleted file mode 100644 index 5563d6328c1..00000000000 --- a/ui/src/pages/document-labeling/DocumentLabelingPage.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React, { useState } from "react"; -import { - EuiPage, - EuiPageBody, - EuiPageSection, - EuiPageHeader, - EuiTitle, - EuiSpacer, - EuiTabs, - EuiTab, -} from "@elastic/eui"; -import RagTab from "./RagTab"; -import ClassificationTab from "./ClassificationTab"; - -const DocumentLabelingPage = () => { - const [selectedTab, setSelectedTab] = useState("rag"); - - const tabs = [ - { - id: "rag", - name: "RAG", - content: , - }, - { - id: "classification", - name: "Classification", - content: , - }, - ]; - - const selectedTabContent = tabs.find( - (tab) => tab.id === selectedTab, - )?.content; - - return ( - - - - -

Data Labeling

-
-
- - - - {tabs.map((tab) => ( - setSelectedTab(tab.id)} - isSelected={tab.id === selectedTab} - > - {tab.name} - - ))} - - - - - {selectedTabContent} - -
-
- ); -}; - -export default DocumentLabelingPage; diff --git a/ui/src/pages/document-labeling/RagTab.tsx b/ui/src/pages/document-labeling/RagTab.tsx deleted file mode 100644 index ae5fd22aea7..00000000000 --- a/ui/src/pages/document-labeling/RagTab.tsx +++ /dev/null @@ -1,615 +0,0 @@ -import React, { useState } from "react"; -import { - EuiPageSection, - EuiCallOut, - EuiSpacer, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiFieldText, - EuiButton, - EuiPanel, - EuiTitle, - EuiText, - EuiLoadingSpinner, - EuiButtonGroup, - EuiCode, - EuiTextArea, -} from "@elastic/eui"; -import { useTheme } from "../../contexts/ThemeContext"; - -interface DocumentContent { - content: string; - file_path: string; -} - -interface TextSelection { - text: string; - start: number; - end: number; -} - -interface DocumentLabel { - text: string; - start: number; - end: number; - label: string; - timestamp: number; - groundTruthLabel: string; -} - -const RagTab = () => { - const { colorMode } = useTheme(); - const [filePath, setFilePath] = useState("./src/test-document.txt"); - const [selectedText, setSelectedText] = useState(null); - const [labelingMode, setLabelingMode] = useState("relevant"); - const [labels, setLabels] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [documentContent, setDocumentContent] = - useState(null); - const [error, setError] = useState(null); - const [prompt, setPrompt] = useState(""); - const [query, setQuery] = useState(""); - const [groundTruthLabel, setGroundTruthLabel] = useState(""); - const [isSaving, setIsSaving] = useState(false); - const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); - - const loadDocument = async () => { - if (!filePath) return; - - setIsLoading(true); - setError(null); - - try { - if (filePath === "./src/test-document.txt") { - const testContent = `This is a sample document for testing the data labeling functionality in Feast UI. - -The document contains multiple paragraphs and sections that can be used to test the text highlighting and labeling features. - -This paragraph discusses machine learning and artificial intelligence concepts. It covers topics like neural networks, deep learning, and natural language processing. Users should be able to select and label relevant portions of this text for RAG retrieval systems. - -Another section focuses on data engineering and ETL pipelines. This content explains how to process large datasets and build scalable data infrastructure. The labeling system should allow users to mark this as relevant or irrelevant for their specific use cases. - -The final paragraph contains information about feature stores and real-time machine learning systems. This text can be used to test the highlighting functionality and ensure that labels are properly stored and displayed in the user interface.`; - - setDocumentContent({ - content: testContent, - file_path: filePath, - }); - - loadSavedLabels(); - } else { - throw new Error( - "Document not found. Please use the test document path: ./src/test-document.txt", - ); - } - } catch (err) { - setError( - err instanceof Error - ? err.message - : "An error occurred while loading the document", - ); - } finally { - setIsLoading(false); - } - }; - - const handleTextSelection = () => { - const selection = window.getSelection(); - if (selection && selection.toString().trim() && documentContent) { - const selectedTextContent = selection.toString().trim(); - const range = selection.getRangeAt(0); - - const textContent = documentContent.content; - - let startIndex = -1; - let endIndex = -1; - - const rangeText = range.toString(); - if (rangeText) { - startIndex = textContent.indexOf(rangeText); - if (startIndex !== -1) { - endIndex = startIndex + rangeText.length; - } - } - - if (startIndex !== -1 && endIndex !== -1) { - setSelectedText({ - text: selectedTextContent, - start: startIndex, - end: endIndex, - }); - } - } - }; - - const handleLabelSelection = () => { - if (selectedText) { - const newLabel: DocumentLabel = { - text: selectedText.text, - start: selectedText.start, - end: selectedText.end, - label: labelingMode, - timestamp: Date.now(), - groundTruthLabel: groundTruthLabel, - }; - - setLabels([...labels, newLabel]); - setSelectedText(null); - setHasUnsavedChanges(true); - - const selection = window.getSelection(); - if (selection) { - selection.removeAllRanges(); - } - } - }; - - const handleRemoveLabel = (index: number) => { - setLabels(labels.filter((_: DocumentLabel, i: number) => i !== index)); - setHasUnsavedChanges(true); - }; - - const saveLabels = () => { - setIsSaving(true); - - setTimeout(() => { - try { - const saveData = { - filePath: filePath, - prompt: prompt, - query: query, - groundTruthLabel: groundTruthLabel, - labels: labels, - timestamp: new Date().toISOString(), - }; - - const pathParts = filePath.split("/"); - const filename = pathParts[pathParts.length - 1]; - const nameWithoutExt = filename.replace(/\.[^/.]+$/, ""); - const downloadFilename = `${nameWithoutExt}-labels.json`; - - const jsonString = JSON.stringify(saveData, null, 2); - const blob = new Blob([jsonString], { type: "application/json" }); - const url = URL.createObjectURL(blob); - - const link = document.createElement("a"); - link.href = url; - link.download = downloadFilename; - link.style.display = "none"; - - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - URL.revokeObjectURL(url); - - setHasUnsavedChanges(false); - alert( - `Successfully saved ${labels.length} labels. File downloaded as ${downloadFilename}`, - ); - } catch (error) { - console.error("Error saving labels:", error); - alert("Error saving labels. Please try again."); - } finally { - setIsSaving(false); - } - }, 100); - }; - - const loadSavedLabels = () => { - try { - const savedData = JSON.parse(localStorage.getItem("ragLabels") || "[]"); - const fileData = savedData.find( - (item: any) => item.filePath === filePath, - ); - - if (fileData) { - setPrompt(fileData.prompt || ""); - setQuery(fileData.query || ""); - setGroundTruthLabel(fileData.groundTruthLabel || ""); - setLabels(fileData.labels || []); - setHasUnsavedChanges(false); - } - } catch (error) { - console.error("Error loading saved labels:", error); - } - }; - - const renderDocumentWithHighlights = ( - content: string, - ): (string | React.ReactElement)[] => { - const allHighlights = [...labels]; - - if (selectedText) { - allHighlights.push({ - text: selectedText.text, - start: selectedText.start, - end: selectedText.end, - label: "temp-selection", - timestamp: 0, - groundTruthLabel: "", - }); - } - - if (allHighlights.length === 0) { - return [content]; - } - - const sortedHighlights = [...allHighlights].sort( - (a, b) => a.start - b.start, - ); - const result: (string | React.ReactElement)[] = []; - let lastIndex = 0; - - sortedHighlights.forEach((highlight, index) => { - result.push(content.slice(lastIndex, highlight.start)); - - let highlightColor, borderColor; - - if (highlight.label === "temp-selection") { - if (colorMode === "dark") { - highlightColor = "#1a4d66"; - borderColor = "#2d6b8a"; - } else { - highlightColor = "#add8e6"; - borderColor = "#87ceeb"; - } - } else if (highlight.label === "irrelevant") { - if (colorMode === "dark") { - highlightColor = "#4d1a1a"; - borderColor = "#6b2d2d"; - } else { - highlightColor = "#f8d7da"; - borderColor = "#f5c6cb"; - } - } else { - if (colorMode === "dark") { - highlightColor = "#1a4d1a"; - borderColor = "#2d6b2d"; - } else { - highlightColor = "#d4edda"; - borderColor = "#c3e6cb"; - } - } - - result.push( - - {highlight.text} - , - ); - - lastIndex = highlight.end; - }); - - result.push(content.slice(lastIndex)); - return result; - }; - - const labelingOptions = [ - { - id: "relevant", - label: "Relevant", - }, - { - id: "irrelevant", - label: "Irrelevant", - }, - ]; - - return ( - - -

- Load a document and highlight text chunks to label them for chunk - extraction/retrieval. Add prompt and query context, then provide - ground truth labels for generation evaluation. -

-
- - - - - - - setFilePath(e.target.value)} - /> - - - - - - Load Document - - - - - - - - {isLoading && ( - - - - - - Loading document... - - - )} - - {error && ( - -

{error}

-
- )} - - {documentContent && ( - <> - - -

RAG Context

-
- - - - - { - setPrompt(e.target.value); - setHasUnsavedChanges(true); - }} - rows={3} - /> - - - - - { - setQuery(e.target.value); - setHasUnsavedChanges(true); - }} - rows={3} - /> - - - -
- - - - -

Step 1: Label for Chunk Extraction

-
- - - - - - setLabelingMode(id)} - buttonSize="s" - /> - - - - - - Label Selected Text - - - - - - - - {selectedText && ( - - {selectedText.text} - - )} - - - - - -

Document Content

-
- - -
- {renderDocumentWithHighlights(documentContent.content)} -
-
-
- - - - -

Step 2: Label for Generation

-
- - - - { - setGroundTruthLabel(e.target.value); - setHasUnsavedChanges(true); - }} - rows={3} - /> - - - - - - - - Save Labels - - - - - - - {(labels.length > 0 || groundTruthLabel || prompt || query) && ( - <> - -

- Click "Save Labels" to download your labeled data as a JSON - file. -

-
- - - )} - - - - {hasUnsavedChanges && ( - <> - -

- You have unsaved changes. Click "Save Labels" to persist your - work. -

-
- - - )} - - {labels.length > 0 && ( - <> - - - -

Extracted Chunk Labels ({labels.length})

-
- - {labels.map((label, index) => ( - - - - Chunk: {label.label} - - - {label.groundTruthLabel && ( - - - GT: {label.groundTruthLabel} - - - )} - - - "{label.text.substring(0, 80)} - {label.text.length > 80 ? "..." : ""}" - - - - handleRemoveLabel(index)} - > - Remove - - - - ))} -
- - )} - - )} -
- ); -}; - -export default RagTab; diff --git a/ui/src/pages/document-labeling/index.ts b/ui/src/pages/document-labeling/index.ts deleted file mode 100644 index f3f4012b362..00000000000 --- a/ui/src/pages/document-labeling/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./DocumentLabelingPage"; diff --git a/ui/src/pages/entities/EntitiesListingTable.tsx b/ui/src/pages/entities/EntitiesListingTable.tsx index 51ffb7c8609..625ec7d5fbb 100644 --- a/ui/src/pages/entities/EntitiesListingTable.tsx +++ b/ui/src/pages/entities/EntitiesListingTable.tsx @@ -20,7 +20,8 @@ const EntitiesListingTable = ({ entities }: EntitiesListingTableProps) => { sortable: true, render: (name: string, item: feast.core.IEntity) => { // For "All Projects" view, link to the specific project - const itemProject = item?.spec?.project || projectName; + const itemProject = + item?.spec?.project || (item as any)?.project || projectName; return ( {name} @@ -28,12 +29,19 @@ const EntitiesListingTable = ({ entities }: EntitiesListingTableProps) => { ); }, }, + { + name: "Join Key", + field: "spec.joinKey", + sortable: true, + }, { name: "Type", field: "spec.valueType", sortable: true, - render: (valueType: feast.types.ValueType.Enum) => { - return feast.types.ValueType.Enum[valueType]; + render: (valueType: feast.types.ValueType.Enum | string | undefined) => { + if (!valueType) return "—"; + if (typeof valueType === "string") return valueType; + return feast.types.ValueType.Enum[valueType] || String(valueType); }, }, { @@ -52,7 +60,7 @@ const EntitiesListingTable = ({ entities }: EntitiesListingTableProps) => { if (projectName === "all") { columns.splice(1, 0, { name: "Project", - field: "spec.project", + field: "project", sortable: true, render: (project: string) => { return {project || "Unknown"}; diff --git a/ui/src/pages/entities/EntityOverviewTab.tsx b/ui/src/pages/entities/EntityOverviewTab.tsx index 8a20688d140..0304d9e6511 100644 --- a/ui/src/pages/entities/EntityOverviewTab.tsx +++ b/ui/src/pages/entities/EntityOverviewTab.tsx @@ -3,6 +3,8 @@ import { EuiHorizontalRule, EuiLoadingSpinner, EuiTitle, + EuiButtonEmpty, + EuiCallOut, } from "@elastic/eui"; import { EuiPanel, @@ -13,19 +15,43 @@ import { EuiDescriptionListTitle, EuiDescriptionListDescription, } from "@elastic/eui"; -import React, { useContext } from "react"; +import React, { useContext, useState } from "react"; import { useParams } from "react-router-dom"; import PermissionsDisplay from "../../components/PermissionsDisplay"; +import EntityFormModal, { + EntityFormData, +} from "../../components/EntityFormModal"; import TagsDisplay from "../../components/TagsDisplay"; import RegistryPathContext from "../../contexts/RegistryPathContext"; import { FEAST_FCO_TYPES } from "../../parsers/types"; -import { feast } from "../../protos"; + import useLoadRegistry from "../../queries/useLoadRegistry"; import { getEntityPermissions } from "../../utils/permissionUtils"; import { toDate } from "../../utils/timestamp"; +import { feast } from "../../protos"; import FeatureViewEdgesList from "./FeatureViewEdgesList"; import useFeatureViewEdgesByEntity from "./useFeatureViewEdgesByEntity"; import useLoadEntity from "./useLoadEntity"; +import { useApplyEntity } from "../../queries/mutations/useEntityMutations"; + +const buildEditFormData = (entity: feast.core.IEntity): EntityFormData => { + const tags = entity.spec?.tags + ? Object.entries(entity.spec.tags).map(([key, value]) => ({ + key, + value: String(value), + })) + : []; + + const joinKeys = entity.spec?.joinKey ? [entity.spec.joinKey] : [""]; + + return { + name: entity.spec?.name || "", + description: entity.spec?.description || "", + joinKeys, + valueType: String(entity.spec?.valueType ?? 0), + tags, + }; +}; const EntityOverviewTab = () => { let { entityName, projectName } = useParams(); @@ -40,6 +66,48 @@ const EntityOverviewTab = () => { const fvEdgesSuccess = fvEdges.isSuccess; const fvEdgesData = fvEdges.data; + const viewTypesForEntity: Record | undefined = + fvEdgesSuccess && fvEdgesData && fvEdgesData[eName] + ? fvEdgesData[eName].reduce((acc: Record, r) => { + acc[r.target.name] = + r.target.type === "labelView" ? "labelView" : "featureView"; + return acc; + }, {}) + : undefined; + + const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [errorMessage, setErrorMessage] = useState(null); + const applyEntity = useApplyEntity(); + + const handleEditSubmit = (formData: EntityFormData) => { + const payload = { + name: formData.name, + project: projectName || "", + join_key: formData.joinKeys[0] || formData.name, + value_type: parseInt(formData.valueType, 10), + description: formData.description, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + owner: "", + }; + applyEntity.mutate(payload, { + onSuccess: () => { + setIsEditModalOpen(false); + setErrorMessage(null); + setSuccessMessage(`Entity "${formData.name}" updated successfully.`); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + // Error shown inside the modal via submitError prop + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setErrorMessage(message); + }, + }); + }; + return ( {isLoading && ( @@ -51,6 +119,39 @@ const EntityOverviewTab = () => { {isError &&

Error loading entity: {entityName}

} {isSuccess && data && ( + {successMessage && ( + <> + + + + )} + {errorMessage && ( + <> + + + + )} + + + setIsEditModalOpen(true)} + > + Edit Entity + + + + @@ -64,14 +165,22 @@ const EntityOverviewTab = () => { {data?.spec?.joinKey} - Description - - {data?.spec?.description} - + {data?.spec?.valueType && ( + <> + + Value Type + + + {typeof data.spec.valueType === "string" + ? data.spec.valueType + : String(data.spec.valueType)} + + + )} - Value Type + Description - {feast.types.ValueType.Enum[data?.spec?.valueType!]} + {data?.spec?.description || "—"} @@ -109,7 +218,7 @@ const EntityOverviewTab = () => { -

Feature Views

+

Consuming Views

{fvEdgesSuccess && fvEdgesData ? ( @@ -118,13 +227,14 @@ const EntityOverviewTab = () => { fvNames={fvEdgesData[eName].map((r) => { return r.target.name; })} + viewTypes={viewTypesForEntity} /> ) : ( - No feature views have this entity + No views consume this entity ) ) : ( - Error loading feature views that have this entity. + Error loading views that consume this entity. )}
@@ -162,6 +272,20 @@ const EntityOverviewTab = () => {
)} + + {isEditModalOpen && data && ( + { + setIsEditModalOpen(false); + setErrorMessage(null); + }} + onSubmit={handleEditSubmit} + initialData={buildEditFormData(data)} + isEdit + isSubmitting={applyEntity.isLoading} + submitError={errorMessage} + /> + )}
); }; diff --git a/ui/src/pages/entities/FeatureViewEdgesList.tsx b/ui/src/pages/entities/FeatureViewEdgesList.tsx index eca599c852a..79f8eb89251 100644 --- a/ui/src/pages/entities/FeatureViewEdgesList.tsx +++ b/ui/src/pages/entities/FeatureViewEdgesList.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { EuiBasicTable, EuiLoadingSpinner } from "@elastic/eui"; +import { EuiBasicTable, EuiBadge, EuiLoadingSpinner } from "@elastic/eui"; import EuiCustomLink from "../../components/EuiCustomLink"; import { useParams } from "react-router-dom"; import useLoadRelationshipData from "../../queries/useLoadRelationshipsData"; @@ -8,6 +8,7 @@ import { FEAST_FCO_TYPES } from "../../parsers/types"; interface FeatureViewEdgesListInterace { fvNames: string[]; + viewTypes?: Record; } const whereFSconsumesThisFv = (fvName: string) => { @@ -42,7 +43,10 @@ const useGetFSConsumersOfFV = (fvList: string[]) => { }; }; -const FeatureViewEdgesList = ({ fvNames }: FeatureViewEdgesListInterace) => { +const FeatureViewEdgesList = ({ + fvNames, + viewTypes, +}: FeatureViewEdgesListInterace) => { const { projectName } = useParams(); const { isLoading, data } = useGetFSConsumersOfFV(fvNames); @@ -52,10 +56,20 @@ const FeatureViewEdgesList = ({ fvNames }: FeatureViewEdgesListInterace) => { name: "Name", field: "", render: ({ name }: { name: string }) => { + const isLabelView = viewTypes?.[name] === "labelView"; + const path = isLabelView + ? `/p/${projectName}/label-view/${name}` + : `/p/${projectName}/feature-view/${name}`; return ( - - {name} - + + {name} + {isLabelView && ( + <> + {" "} + label view + + )} + ); }, }, diff --git a/ui/src/pages/entities/Index.tsx b/ui/src/pages/entities/Index.tsx index 070c53d38fa..32d812e1539 100644 --- a/ui/src/pages/entities/Index.tsx +++ b/ui/src/pages/entities/Index.tsx @@ -1,38 +1,82 @@ -import React, { useContext } from "react"; +import React, { useState } from "react"; import { useParams } from "react-router-dom"; -import { EuiPageTemplate, EuiLoadingSpinner } from "@elastic/eui"; +import { + EuiPageTemplate, + EuiLoadingSpinner, + EuiButton, + EuiCallOut, + EuiSpacer, +} from "@elastic/eui"; import { EntityIcon } from "../../graphics/EntityIcon"; -import useLoadRegistry from "../../queries/useLoadRegistry"; import EntitiesListingTable from "./EntitiesListingTable"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; import EntityIndexEmptyState from "./EntityIndexEmptyState"; import ExportButton from "../../components/ExportButton"; +import EntityFormModal, { + EntityFormData, +} from "../../components/EntityFormModal"; +import { useApplyEntity } from "../../queries/mutations/useEntityMutations"; +import useResourceQuery, { + entityListPath, +} from "../../queries/useResourceQuery"; const useLoadEntities = () => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.entities; - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: "entities-list", + project: projectName, + restPath: entityListPath(projectName), + restSelect: (d) => d.entities, + }); }; +const formDataToPayload = (formData: EntityFormData, project: string) => ({ + name: formData.name, + project, + join_key: formData.joinKeys[0] || formData.name, + value_type: parseInt(formData.valueType, 10), + description: formData.description, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + owner: "", +}); + const Index = () => { + const { projectName } = useParams(); const { isLoading, isSuccess, isError, data } = useLoadEntities(); + const isAllProjects = projectName === "all"; + + const [isModalOpen, setIsModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [submitErrorMessage, setSubmitErrorMessage] = useState( + null, + ); + const applyEntity = useApplyEntity(); useDocumentTitle(`Entities | Feast`); + const handleCreateSubmit = (formData: EntityFormData) => { + setSubmitErrorMessage(null); + const payload = formDataToPayload(formData, projectName || ""); + applyEntity.mutate(payload, { + onSuccess: () => { + setIsModalOpen(false); + setSubmitErrorMessage(null); + setSuccessMessage(`Entity "${formData.name}" created successfully.`); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setSubmitErrorMessage(message); + }, + }); + }; + return ( { iconType={EntityIcon} pageTitle="Entities" rightSideItems={[ + ...(isAllProjects + ? [] + : [ + setIsModalOpen(true)} + key="create" + > + Create Entity + , + ]), , ]} /> + {successMessage && ( + <> + + + + )} {isLoading && (

Loading @@ -57,6 +125,18 @@ const Index = () => { {isSuccess && !data && } {isSuccess && data && } + + {isModalOpen && ( + { + setIsModalOpen(false); + setSubmitErrorMessage(null); + }} + onSubmit={handleCreateSubmit} + isSubmitting={applyEntity.isLoading} + submitError={submitErrorMessage} + /> + )} ); }; diff --git a/ui/src/pages/entities/useLoadEntity.ts b/ui/src/pages/entities/useLoadEntity.ts index fdb4a7968f1..cf20c33bd8f 100644 --- a/ui/src/pages/entities/useLoadEntity.ts +++ b/ui/src/pages/entities/useLoadEntity.ts @@ -1,24 +1,18 @@ -import { useContext } from "react"; import { useParams } from "react-router-dom"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import useLoadRegistry from "../../queries/useLoadRegistry"; +import useResourceQuery, { + entityDetailPath, +} from "../../queries/useResourceQuery"; const useLoadEntity = (entityName: string) => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.entities?.find( - (fv) => fv?.spec?.name === entityName, - ); - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: `entity:${entityName}`, + project: projectName, + restPath: entityDetailPath(entityName, projectName || ""), + restSelect: (d) => d, + enabled: !!entityName, + }); }; export default useLoadEntity; diff --git a/ui/src/pages/feature-services/FeatureServiceListingTable.tsx b/ui/src/pages/feature-services/FeatureServiceListingTable.tsx index acc68b6e619..8dd8b299d74 100644 --- a/ui/src/pages/feature-services/FeatureServiceListingTable.tsx +++ b/ui/src/pages/feature-services/FeatureServiceListingTable.tsx @@ -30,7 +30,8 @@ const FeatureServiceListingTable = ({ field: "spec.name", render: (name: string, item: feast.core.IFeatureService) => { // For "All Projects" view, link to the specific project - const itemProject = item?.spec?.project || projectName; + const itemProject = + item?.spec?.project || (item as any)?.project || projectName; return ( {name} @@ -62,7 +63,7 @@ const FeatureServiceListingTable = ({ if (projectName === "all") { columns.splice(1, 0, { name: "Project", - field: "spec.project", + field: "project", sortable: true, render: (project: string) => { return project || "Unknown"; diff --git a/ui/src/pages/feature-services/FeatureServiceOverviewTab.tsx b/ui/src/pages/feature-services/FeatureServiceOverviewTab.tsx index be922e41261..bbea04a07bc 100644 --- a/ui/src/pages/feature-services/FeatureServiceOverviewTab.tsx +++ b/ui/src/pages/feature-services/FeatureServiceOverviewTab.tsx @@ -34,11 +34,18 @@ const FeatureServiceOverviewTab = () => { const isEmpty = data === undefined; let numFeatures = 0; - let numFeatureViews = 0; + let numLabels = 0; + const featureProjections: any[] = []; + const labelProjections: any[] = []; if (data) { - data?.spec?.features?.forEach((featureView) => { - numFeatureViews += 1; - numFeatures += featureView?.featureColumns!.length; + data?.spec?.features?.forEach((featureView: any) => { + if (featureView.viewType === "labelView") { + numLabels += featureView?.featureColumns!.length; + labelProjections.push(featureView); + } else { + numFeatures += featureView?.featureColumns!.length; + featureProjections.push(featureView); + } }); } @@ -57,7 +64,7 @@ const FeatureServiceOverviewTab = () => { - + @@ -66,7 +73,7 @@ const FeatureServiceOverviewTab = () => { @@ -90,14 +97,43 @@ const FeatureServiceOverviewTab = () => {

Features

- {data?.spec?.features ? ( - + {featureProjections.length > 0 ? ( + ) : ( No features specified for this feature service. )} + {labelProjections.length > 0 && ( + + + + + + + + +

from

+
+
+ + + +
+ + + +

Labels

+
+ + +
+
+ )}
@@ -153,16 +189,28 @@ const FeatureServiceOverviewTab = () => { -

All Feature Views

+

All Views

{data?.spec?.features?.length! > 0 ? ( { + data?.spec?.features?.map((f: any) => { return f.featureViewName!; })! } + viewTypes={ + data?.spec?.features?.reduce( + (acc: Record, f: any) => { + if (f.featureViewName) { + acc[f.featureViewName] = + f.viewType || "featureView"; + } + return acc; + }, + {}, + ) || {} + } /> ) : ( No feature views in this feature service diff --git a/ui/src/pages/feature-services/Index.tsx b/ui/src/pages/feature-services/Index.tsx index 260a9b821dc..b68bb9697e3 100644 --- a/ui/src/pages/feature-services/Index.tsx +++ b/ui/src/pages/feature-services/Index.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; import { @@ -13,7 +13,6 @@ import { import { FeatureServiceIcon } from "../../graphics/FeatureServiceIcon"; -import useLoadRegistry from "../../queries/useLoadRegistry"; import FeatureServiceListingTable from "./FeatureServiceListingTable"; import { useSearchQuery, @@ -22,27 +21,23 @@ import { tagTokenGroupsType, } from "../../hooks/useSearchInputWithTags"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; import FeatureServiceIndexEmptyState from "./FeatureServiceIndexEmptyState"; import TagSearch from "../../components/TagSearch"; import ExportButton from "../../components/ExportButton"; import { useFeatureServiceTagsAggregation } from "../../hooks/useTagsAggregation"; import { feast } from "../../protos"; +import useResourceQuery, { + featureServiceListPath, +} from "../../queries/useResourceQuery"; const useLoadFeatureServices = () => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.featureServices; - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: "feature-services-list", + project: projectName, + restPath: featureServiceListPath(projectName), + restSelect: (d) => d.featureServices, + }); }; const shouldIncludeFSsGivenTokenGroups = ( diff --git a/ui/src/pages/feature-services/useLoadFeatureService.ts b/ui/src/pages/feature-services/useLoadFeatureService.ts index 004ab35b927..81fff2e931d 100644 --- a/ui/src/pages/feature-services/useLoadFeatureService.ts +++ b/ui/src/pages/feature-services/useLoadFeatureService.ts @@ -1,53 +1,50 @@ -import { FEAST_FCO_TYPES } from "../../parsers/types"; -import { useContext } from "react"; import { useParams } from "react-router-dom"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; - -import useLoadRegistry from "../../queries/useLoadRegistry"; import { EntityReference } from "../../parsers/parseEntityRelationships"; +import useResourceQuery, { + featureServiceDetailPath, +} from "../../queries/useResourceQuery"; const useLoadFeatureService = (featureServiceName: string) => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.featureServices?.find( - (fs) => fs?.spec?.name === featureServiceName, - ); + const fsQuery = useResourceQuery({ + resourceType: `feature-service:${featureServiceName}`, + project: projectName, + restPath: featureServiceDetailPath(featureServiceName, projectName || ""), + restSelect: (d) => ({ + featureService: d, + indirectRelationships: d?.relationships || [], + permissions: d?.permissions || [], + }), + enabled: !!featureServiceName, + }); + + const featureService = fsQuery.data?.featureService; + const indirectRelationships = fsQuery.data?.indirectRelationships || []; + const permissions = fsQuery.data?.permissions || []; - let entities = - data === undefined + let entities: EntityReference[] | undefined = + featureService === undefined ? undefined - : registryQuery.data?.indirectRelationships - .filter((relationship) => { - return ( - relationship.target.type === FEAST_FCO_TYPES.featureService && - relationship.target.name === data?.spec?.name && - relationship.source.type === FEAST_FCO_TYPES.entity - ); - }) - .map((relationship) => { - return relationship.source; - }); - // Deduplicate on name of entity + : indirectRelationships + .filter( + (rel: any) => + rel?.target?.type === "featureService" && + rel?.source?.type === "entity", + ) + .map((rel: any) => rel.source); + if (entities) { - let entityToName: { [key: string]: EntityReference } = {}; - for (let entity of entities) { + const entityToName: { [key: string]: EntityReference } = {}; + for (const entity of entities) { entityToName[entity.name] = entity; } entities = Object.values(entityToName); } + return { - ...registryQuery, - data: data - ? { - ...data, - permissions: registryQuery.data?.permissions, - } - : undefined, + ...fsQuery, + data: featureService ? { ...featureService, permissions } : undefined, entities, }; }; diff --git a/ui/src/pages/feature-views/CurlGeneratorTab.tsx b/ui/src/pages/feature-views/CurlGeneratorTab.tsx index 147921458ee..5c83440a2a0 100644 --- a/ui/src/pages/feature-views/CurlGeneratorTab.tsx +++ b/ui/src/pages/feature-views/CurlGeneratorTab.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState } from "react"; import { EuiPanel, EuiTitle, @@ -16,23 +16,22 @@ import { import { CodeBlock, github } from "react-code-blocks"; import { RegularFeatureViewCustomTabProps } from "../../custom-tabs/types"; +const defaultServerUrl = + process.env.REACT_APP_FEAST_FEATURE_SERVER_URL || "http://localhost:6566"; + const CurlGeneratorTab = ({ feastObjectQuery, }: RegularFeatureViewCustomTabProps) => { const data = feastObjectQuery.data as any; const [serverUrl, setServerUrl] = useState(() => { const savedUrl = localStorage.getItem("feast-feature-server-url"); - return savedUrl || "http://localhost:6566"; + return savedUrl || defaultServerUrl; }); const [entityValues, setEntityValues] = useState>({}); const [selectedFeatures, setSelectedFeatures] = useState< Record >({}); - useEffect(() => { - localStorage.setItem("feast-feature-server-url", serverUrl); - }, [serverUrl]); - if (feastObjectQuery.isLoading) { return Loading...; } @@ -106,8 +105,12 @@ const CurlGeneratorTab = ({ setServerUrl(e.target.value)} - placeholder="http://localhost:6566" + onChange={(e) => { + const nextValue = e.target.value; + setServerUrl(nextValue); + localStorage.setItem("feast-feature-server-url", nextValue); + }} + placeholder={defaultServerUrl} /> diff --git a/ui/src/pages/feature-views/FeatureViewListingTable.tsx b/ui/src/pages/feature-views/FeatureViewListingTable.tsx index e865abe6e74..9fd6f8f8fd7 100644 --- a/ui/src/pages/feature-views/FeatureViewListingTable.tsx +++ b/ui/src/pages/feature-views/FeatureViewListingTable.tsx @@ -31,7 +31,10 @@ const FeatureViewListingTable = ({ sortable: true, render: (name: string, item: genericFVType) => { // For "All Projects" view, link to the specific project - const itemProject = item.object?.spec?.project || projectName; + const itemProject = + item.object?.spec?.project || + (item.object as any)?.project || + projectName; return ( {name}{" "} @@ -49,6 +52,13 @@ const FeatureViewListingTable = ({ return features.length; }, }, + { + name: "Version", + render: (item: genericFVType) => { + const ver = (item.object as any)?.meta?.currentVersionNumber; + return ver != null && ver > 0 ? `v${ver}` : "—"; + }, + }, ]; // Add Project column when viewing all projects @@ -56,7 +66,13 @@ const FeatureViewListingTable = ({ columns.splice(1, 0, { name: "Project", render: (item: genericFVType) => { - return {item.object?.spec?.project || "Unknown"}; + return ( + + {item.object?.spec?.project || + (item.object as any)?.project || + "Unknown"} + + ); }, }); } diff --git a/ui/src/pages/feature-views/FeatureViewUsagePanel.tsx b/ui/src/pages/feature-views/FeatureViewUsagePanel.tsx new file mode 100644 index 00000000000..71eaebedd02 --- /dev/null +++ b/ui/src/pages/feature-views/FeatureViewUsagePanel.tsx @@ -0,0 +1,130 @@ +import React from "react"; +import { + EuiBadge, + EuiBasicTable, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiLoadingSpinner, + EuiPanel, + EuiText, + EuiTitle, + EuiToolTip, +} from "@elastic/eui"; +import useLoadFeatureUsage, { + FeatureUsageEntry, +} from "../../queries/useLoadFeatureUsage"; + +interface FeatureViewUsagePanelProps { + featureViewName: string; +} + +const formatTimestamp = (ts: number | null): string => { + if (ts == null) return "Never"; + const date = new Date(ts); + return date.toLocaleString(); +}; + +const formatRelativeTime = (ts: number | null): string => { + if (ts == null) return ""; + const now = Date.now(); + const diffMs = now - ts; + const diffMin = Math.floor(diffMs / 60000); + if (diffMin < 1) return "just now"; + if (diffMin < 60) return `${diffMin}m ago`; + const diffHr = Math.floor(diffMin / 60); + if (diffHr < 24) return `${diffHr}h ago`; + const diffDays = Math.floor(diffHr / 24); + return `${diffDays}d ago`; +}; + +const FeatureViewUsagePanel = ({ + featureViewName, +}: FeatureViewUsagePanelProps) => { + const { data, isLoading, isError } = useLoadFeatureUsage(); + + if (isLoading) { + return ( + + +

MLflow Usage

+
+ + + + + + +
+ ); + } + + if (isError || !data || !data.mlflow_enabled) { + return null; + } + + const usage: FeatureUsageEntry | undefined = + data.feature_usage?.[featureViewName]; + + if (!usage || usage.run_count === 0) { + return ( + + +

MLflow Usage

+
+ + + No MLflow training runs have used this feature view. + +
+ ); + } + + const modelItems = usage.models.map((name) => ({ name })); + + const modelColumns = [ + { + name: "Registered Model", + field: "name", + render: (name: string) => {name}, + }, + ]; + + return ( + + +

MLflow Usage

+
+ + + + + Training runs: {usage.run_count} + + + + + + Last used: {formatRelativeTime(usage.last_used)} + + + + + {modelItems.length > 0 && ( + <> + + + Registered models using this feature view: + + + + )} +
+ ); +}; + +export default FeatureViewUsagePanel; diff --git a/ui/src/pages/feature-views/FeatureViewVersionsTab.tsx b/ui/src/pages/feature-views/FeatureViewVersionsTab.tsx new file mode 100644 index 00000000000..f388d247da4 --- /dev/null +++ b/ui/src/pages/feature-views/FeatureViewVersionsTab.tsx @@ -0,0 +1,268 @@ +import React, { useContext, useState, useMemo } from "react"; +import { + EuiBasicTable, + EuiText, + EuiPanel, + EuiTitle, + EuiHorizontalRule, + EuiCodeBlock, + EuiFlexGroup, + EuiFlexItem, + EuiBadge, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadRegistry from "../../queries/useLoadRegistry"; +import { feast } from "../../protos"; +import { toDate } from "../../utils/timestamp"; +import { useParams } from "react-router-dom"; + +interface FeatureViewVersionsTabProps { + featureViewName: string; +} + +interface DecodedVersion { + record: feast.core.IFeatureViewVersionRecord; + features: feast.core.IFeatureSpecV2[]; + entities: string[]; + description: string; + udfBody: string | null; +} + +const decodeVersionProto = ( + record: feast.core.IFeatureViewVersionRecord, +): DecodedVersion => { + const result: DecodedVersion = { + record, + features: [], + entities: [], + description: "", + udfBody: null, + }; + + if (!record.featureViewProto || record.featureViewProto.length === 0) { + return result; + } + + try { + const bytes = + record.featureViewProto instanceof Uint8Array + ? record.featureViewProto + : new Uint8Array(record.featureViewProto); + + if (record.featureViewType === "on_demand_feature_view") { + const odfv = feast.core.OnDemandFeatureView.decode(bytes); + result.features = odfv.spec?.features || []; + result.description = odfv.spec?.description || ""; + result.udfBody = + odfv.spec?.featureTransformation?.userDefinedFunction?.bodyText || + odfv.spec?.userDefinedFunction?.bodyText || + null; + } else if (record.featureViewType === "stream_feature_view") { + const sfv = feast.core.StreamFeatureView.decode(bytes); + result.features = sfv.spec?.features || []; + result.entities = sfv.spec?.entities || []; + result.description = sfv.spec?.description || ""; + } else if (record.featureViewType === "label_view") { + const lv = feast.core.LabelView.decode(bytes); + result.features = lv.spec?.features || []; + result.entities = lv.spec?.entities || []; + result.description = lv.spec?.description || ""; + } else { + const fv = feast.core.FeatureView.decode(bytes); + result.features = fv.spec?.features || []; + result.entities = fv.spec?.entities || []; + result.description = fv.spec?.description || ""; + } + } catch (e) { + console.error("Failed to decode version proto:", e); + } + + return result; +}; + +const VersionDetail = ({ decoded }: { decoded: DecodedVersion }) => { + return ( + + {decoded.description && ( + + + {decoded.description} + + + )} + {decoded.udfBody && ( + + + +

Transformation

+
+ + + {decoded.udfBody} + +
+
+ )} + + + + +

Features ({decoded.features.length})

+
+ + {decoded.features.length > 0 ? ( + + typeof vt === "string" + ? vt + : feast.types.ValueType.Enum[vt] || String(vt || ""), + }, + ]} + /> + ) : ( + No features in this version. + )} +
+
+ {decoded.entities.length > 0 && ( + + + +

Entities

+
+ + + {decoded.entities.map((entity) => ( + + {entity} + + ))} + +
+
+ )} +
+
+ ); +}; + +const FeatureViewVersionsTab = ({ + featureViewName, +}: FeatureViewVersionsTabProps) => { + const registryUrl = useContext(RegistryPathContext); + const { projectName } = useParams(); + const registryQuery = useLoadRegistry(registryUrl, projectName); + const [expandedRows, setExpandedRows] = useState>({}); + + const records = useMemo( + () => + registryQuery.data?.objects?.featureViewVersionHistory?.records?.filter( + (r: feast.core.IFeatureViewVersionRecord) => + r.featureViewName === featureViewName, + ) || [], + [ + registryQuery.data?.objects?.featureViewVersionHistory?.records, + featureViewName, + ], + ); + + const decodedVersions: DecodedVersion[] = useMemo( + () => records.map(decodeVersionProto), + [records], + ); + + if (records.length === 0) { + return No version history available.; + } + + const toggleRow = (versionNumber: number) => { + setExpandedRows((prev) => ({ + ...prev, + [versionNumber]: !prev[versionNumber], + })); + }; + + const columns = [ + { + field: "record.versionNumber", + name: "Version", + render: (_: unknown, item: DecodedVersion) => + `v${item.record.versionNumber}`, + sortable: true, + width: "80px", + }, + { + name: "Features", + render: (item: DecodedVersion) => `${item.features.length}`, + width: "80px", + }, + { + field: "record.featureViewType", + name: "Type", + render: (_: unknown, item: DecodedVersion) => + item.record.featureViewType || "—", + }, + { + field: "record.createdTimestamp", + name: "Created", + render: (_: unknown, item: DecodedVersion) => + item.record.createdTimestamp + ? toDate(item.record.createdTimestamp).toLocaleString() + : "—", + }, + { + field: "record.versionId", + name: "Version ID", + render: (_: unknown, item: DecodedVersion) => + item.record.versionId || "—", + }, + ]; + + const itemIdToExpandedRowMap: Record = {}; + decodedVersions.forEach((decoded) => { + const vn = decoded.record.versionNumber!; + if (expandedRows[vn]) { + itemIdToExpandedRowMap[String(vn)] = ; + } + }); + + return ( + String(item.record.versionNumber)} + itemIdToExpandedRowMap={itemIdToExpandedRowMap} + columns={[ + { + isExpander: true, + width: "40px", + render: (item: DecodedVersion) => { + const vn = item.record.versionNumber!; + return ( + + ); + }, + }, + ...columns, + ]} + /> + ); +}; + +export default FeatureViewVersionsTab; diff --git a/ui/src/pages/feature-views/Index.tsx b/ui/src/pages/feature-views/Index.tsx index b1c28895370..7bd81c34963 100644 --- a/ui/src/pages/feature-views/Index.tsx +++ b/ui/src/pages/feature-views/Index.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React, { useState } from "react"; import { useParams } from "react-router-dom"; import { @@ -9,11 +9,12 @@ import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem, + EuiButton, + EuiCallOut, } from "@elastic/eui"; import { FeatureViewIcon } from "../../graphics/FeatureViewIcon"; -import useLoadRegistry from "../../queries/useLoadRegistry"; import FeatureViewListingTable from "./FeatureViewListingTable"; import { filterInputInterface, @@ -22,26 +23,29 @@ import { } from "../../hooks/useSearchInputWithTags"; import { genericFVType, regularFVInterface } from "../../parsers/mergedFVTypes"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; import FeatureViewIndexEmptyState from "./FeatureViewIndexEmptyState"; import { useFeatureViewTagsAggregation } from "../../hooks/useTagsAggregation"; import TagSearch from "../../components/TagSearch"; import ExportButton from "../../components/ExportButton"; +import FeatureViewFormModal, { + FeatureViewFormData, +} from "../../components/FeatureViewFormModal"; +import { useApplyFeatureView } from "../../queries/mutations/useFeatureViewMutations"; +import useResourceQuery, { + featureViewListPath, + restFeatureViewsToMergedList, + entityListPath, + dataSourceListPath, +} from "../../queries/useResourceQuery"; const useLoadFeatureViews = () => { - const registryUrl = useContext(RegistryPathContext); const { projectName } = useParams(); - const registryQuery = useLoadRegistry(registryUrl, projectName); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.mergedFVList; - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: "feature-views-list", + project: projectName, + restPath: featureViewListPath(projectName), + restSelect: restFeatureViewsToMergedList, + }); }; const shouldIncludeFVsGivenTokenGroups = ( @@ -49,13 +53,12 @@ const shouldIncludeFVsGivenTokenGroups = ( tagTokenGroups: Record, ) => { return Object.entries(tagTokenGroups).every(([key, values]) => { - const entryTagValue = entry?.object?.spec!.tags - ? entry.object.spec.tags[key] - : undefined; + const tags = entry?.object?.spec?.tags; + const entryTagValue = tags ? (tags as any)[key] : undefined; if (entryTagValue) { return values.every((value) => { - return value.length > 0 ? entryTagValue.indexOf(value) >= 0 : true; // Don't filter if the string is empty + return value.length > 0 ? entryTagValue.indexOf(value) >= 0 : true; }); } else { return false; @@ -74,7 +77,7 @@ const filterFn = (data: genericFVType[], filterInput: filterInputInterface) => { filterInput.tagTokenGroups, ); } else { - return false; // ODFVs don't have tags yet + return false; } }); } @@ -90,9 +93,72 @@ const filterFn = (data: genericFVType[], filterInput: filterInputInterface) => { return filteredByTags; }; +const TTL_UNITS: Record = { + days: 86400, + hours: 3600, + minutes: 60, + seconds: 1, +}; + +const formDataToPayload = (formData: FeatureViewFormData, project: string) => ({ + name: formData.name, + project, + entities: formData.entities, + features: formData.features.map((f) => ({ + name: f.name, + value_type: parseInt(f.valueType, 10), + description: f.description, + })), + batch_source: formData.batchSource, + ttl_seconds: formData.ttlValue * (TTL_UNITS[formData.ttlUnit] || 1), + online: formData.online, + description: formData.description, + owner: formData.owner, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), +}); + const Index = () => { + const { projectName } = useParams(); const { isLoading, isSuccess, isError, data } = useLoadFeatureViews(); + const isAllProjects = projectName === "all"; + + const entitiesQuery = useResourceQuery({ + resourceType: "entities-list-fv-prereq", + project: projectName, + restPath: entityListPath(projectName), + restSelect: (d) => d.entities, + }); + const dataSourcesQuery = useResourceQuery({ + resourceType: "data-sources-list-fv-prereq", + project: projectName, + restPath: dataSourceListPath(projectName), + restSelect: (d) => d.dataSources, + }); + const tagAggregationQuery = useFeatureViewTagsAggregation(); + const [isModalOpen, setIsModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [errorMessage, setErrorMessage] = useState(null); + const [prereqWarning, setPrereqWarning] = useState(null); + const applyFeatureView = useApplyFeatureView(); + + const handleCreateClick = () => { + const missingDeps: string[] = []; + const entities = entitiesQuery.data || []; + const dataSources = dataSourcesQuery.data || []; + + if (entities.length === 0) missingDeps.push("entities"); + if (dataSources.length === 0) missingDeps.push("data sources"); + + if (missingDeps.length > 0) { + setPrereqWarning( + `Feature views require at least one entity and one data source. Missing: ${missingDeps.join(" and ")}. You can still proceed — the form will let you create them inline.`, + ); + } + setIsModalOpen(true); + }; useDocumentTitle(`Feature Views | Feast`); @@ -114,6 +180,27 @@ const Index = () => { ? filterFn(data, { tagTokenGroups, searchTokens }) : data; + const handleCreateSubmit = (formData: FeatureViewFormData) => { + const payload = formDataToPayload(formData, projectName || ""); + applyFeatureView.mutate(payload, { + onSuccess: () => { + setIsModalOpen(false); + setErrorMessage(null); + setPrereqWarning(null); + setSuccessMessage( + `Feature view "${formData.name}" created successfully.`, + ); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + // Error shown inside the modal via submitError prop + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setErrorMessage(message); + }, + }); + }; + return ( { iconType={FeatureViewIcon} pageTitle="Feature Views" rightSideItems={[ + ...(isAllProjects + ? [] + : [ + + Create Feature View + , + ]), , ]} /> + {prereqWarning && ( + <> + +

{prereqWarning}

+
+ + + )} + {successMessage && ( + <> + + + + )} + {errorMessage && ( + <> + + + + )} {isLoading && (

Loading @@ -171,6 +306,19 @@ const Index = () => { )} + + {isModalOpen && ( + { + setIsModalOpen(false); + setPrereqWarning(null); + setErrorMessage(null); + }} + onSubmit={handleCreateSubmit} + isSubmitting={applyFeatureView.isLoading} + submitError={errorMessage} + /> + )} ); }; diff --git a/ui/src/pages/feature-views/OnDemandFeatureViewInstance.tsx b/ui/src/pages/feature-views/OnDemandFeatureViewInstance.tsx index 5a4b48f6d6d..70824219aaa 100644 --- a/ui/src/pages/feature-views/OnDemandFeatureViewInstance.tsx +++ b/ui/src/pages/feature-views/OnDemandFeatureViewInstance.tsx @@ -1,11 +1,12 @@ import React from "react"; import { Route, Routes, useNavigate } from "react-router-dom"; import { useParams } from "react-router-dom"; -import { EuiPageTemplate } from "@elastic/eui"; +import { EuiBadge, EuiPageTemplate } from "@elastic/eui"; import { FeatureViewIcon } from "../../graphics/FeatureViewIcon"; -import { useMatchExact } from "../../hooks/useMatchSubpath"; +import { useMatchExact, useMatchSubpath } from "../../hooks/useMatchSubpath"; import OnDemandFeatureViewOverviewTab from "./OnDemandFeatureViewOverviewTab"; +import FeatureViewVersionsTab from "./FeatureViewVersionsTab"; import { useOnDemandFeatureViewCustomTabs, @@ -29,7 +30,17 @@ const OnDemandFeatureInstance = ({ data }: OnDemandFeatureInstanceProps) => { + {featureViewName} + {data?.meta?.currentVersionNumber != null && + data.meta.currentVersionNumber > 0 && ( + + v{data.meta.currentVersionNumber} + + )} + + } tabs={[ { label: "Overview", @@ -38,6 +49,13 @@ const OnDemandFeatureInstance = ({ data }: OnDemandFeatureInstanceProps) => { navigate(""); }, }, + { + label: "Versions", + isSelected: useMatchSubpath("versions"), + onClick: () => { + navigate("versions"); + }, + }, ...customNavigationTabs, ]} /> @@ -47,6 +65,12 @@ const OnDemandFeatureInstance = ({ data }: OnDemandFeatureInstanceProps) => { path="/" element={} /> + + } + /> {CustomTabRoutes} diff --git a/ui/src/pages/feature-views/RegularFeatureViewInstance.tsx b/ui/src/pages/feature-views/RegularFeatureViewInstance.tsx index 48d61e45f8f..a3c831b315f 100644 --- a/ui/src/pages/feature-views/RegularFeatureViewInstance.tsx +++ b/ui/src/pages/feature-views/RegularFeatureViewInstance.tsx @@ -1,12 +1,13 @@ import React, { useContext } from "react"; import { Route, Routes, useNavigate } from "react-router-dom"; -import { EuiPageTemplate } from "@elastic/eui"; +import { EuiBadge, EuiPageTemplate } from "@elastic/eui"; import { FeatureViewIcon } from "../../graphics/FeatureViewIcon"; import { useMatchExact, useMatchSubpath } from "../../hooks/useMatchSubpath"; import RegularFeatureViewOverviewTab from "./RegularFeatureViewOverviewTab"; import FeatureViewLineageTab from "./FeatureViewLineageTab"; +import FeatureViewVersionsTab from "./FeatureViewVersionsTab"; import { useRegularFeatureViewCustomTabs, @@ -57,6 +58,14 @@ const RegularFeatureInstance = ({ }); } + tabs.push({ + label: "Versions", + isSelected: useMatchSubpath("versions"), + onClick: () => { + navigate("versions"); + }, + }); + tabs.push(...customNavigationTabs); const TabRoutes = useRegularFeatureViewCustomTabRoutes(); @@ -66,7 +75,17 @@ const RegularFeatureInstance = ({ + {data?.spec?.name} + {data?.meta?.currentVersionNumber != null && + data.meta.currentVersionNumber > 0 && ( + + v{data.meta.currentVersionNumber} + + )} + + } tabs={tabs} /> @@ -84,6 +103,12 @@ const RegularFeatureInstance = ({ path="/lineage" element={} /> + + } + /> {TabRoutes} diff --git a/ui/src/pages/feature-views/RegularFeatureViewOverviewTab.tsx b/ui/src/pages/feature-views/RegularFeatureViewOverviewTab.tsx index e766e4fd0ab..59614dd5334 100644 --- a/ui/src/pages/feature-views/RegularFeatureViewOverviewTab.tsx +++ b/ui/src/pages/feature-views/RegularFeatureViewOverviewTab.tsx @@ -1,5 +1,7 @@ import { EuiBadge, + EuiButtonEmpty, + EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, @@ -8,20 +10,27 @@ import { EuiStat, EuiText, EuiTitle, + EuiToolTip, } from "@elastic/eui"; -import React from "react"; +import React, { useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import FeaturesListDisplay from "../../components/FeaturesListDisplay"; +import FeatureViewFormModal, { + FeatureViewFormData, +} from "../../components/FeatureViewFormModal"; import PermissionsDisplay from "../../components/PermissionsDisplay"; import TagsDisplay from "../../components/TagsDisplay"; import { encodeSearchQueryString } from "../../hooks/encodeSearchQueryString"; import { EntityRelation } from "../../parsers/parseEntityRelationships"; import { FEAST_FCO_TYPES } from "../../parsers/types"; import useLoadRelationshipData from "../../queries/useLoadRelationshipsData"; +import useLoadFeatureUsage from "../../queries/useLoadFeatureUsage"; +import { useApplyFeatureView } from "../../queries/mutations/useFeatureViewMutations"; import { getEntityPermissions } from "../../utils/permissionUtils"; import BatchSourcePropertiesView from "../data-sources/BatchSourcePropertiesView"; import ConsumingFeatureServicesList from "./ConsumingFeatureServicesList"; +import FeatureViewUsagePanel from "./FeatureViewUsagePanel"; import { feast } from "../../protos"; import { toDate } from "../../utils/timestamp"; @@ -39,6 +48,55 @@ interface RegularFeatureViewOverviewTabProps { permissions?: any[]; } +const buildEditFormData = ( + fv: feast.core.IFeatureView, +): FeatureViewFormData => { + const tags = fv.spec?.tags + ? Object.entries(fv.spec.tags).map(([key, value]) => ({ key, value })) + : []; + + const features = (fv.spec?.features || []).map((f) => ({ + name: f.name || "", + valueType: String(f.valueType ?? 0), + description: f.description || "", + })); + + let ttlValue = 0; + let ttlUnit = "seconds"; + if (fv.spec?.ttl?.seconds) { + const secs = + typeof fv.spec.ttl.seconds === "number" + ? fv.spec.ttl.seconds + : ((fv.spec.ttl.seconds as any).toNumber?.() ?? 0); + if (secs > 0 && secs % 86400 === 0) { + ttlValue = secs / 86400; + ttlUnit = "days"; + } else if (secs > 0 && secs % 3600 === 0) { + ttlValue = secs / 3600; + ttlUnit = "hours"; + } else if (secs > 0 && secs % 60 === 0) { + ttlValue = secs / 60; + ttlUnit = "minutes"; + } else { + ttlValue = secs; + ttlUnit = "seconds"; + } + } + + return { + name: fv.spec?.name || "", + description: fv.spec?.description || "", + owner: fv.spec?.owner || "", + entities: fv.spec?.entities || [], + features, + batchSource: fv.spec?.batchSource?.name || "", + ttlValue, + ttlUnit, + online: fv.spec?.online ?? true, + tags, + }; +}; + const RegularFeatureViewOverviewTab = ({ data, permissions, @@ -51,6 +109,7 @@ const RegularFeatureViewOverviewTab = ({ const fvName = featureViewName === undefined ? "" : featureViewName; const relationshipQuery = useLoadRelationshipData(); + const { data: usageData } = useLoadFeatureUsage(); const fsNames = relationshipQuery.data ? relationshipQuery.data.filter(whereFSconsumesThisFv(fvName)).map((fs) => { @@ -59,12 +118,125 @@ const RegularFeatureViewOverviewTab = ({ : []; const numOfFs = fsNames.length; + const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [successMessage, setSuccessMessage] = useState(null); + const [errorMessage, setErrorMessage] = useState(null); + const applyFeatureView = useApplyFeatureView(); + + const TTL_UNITS: Record = { + days: 86400, + hours: 3600, + minutes: 60, + seconds: 1, + }; + + const handleEditSubmit = (formData: FeatureViewFormData) => { + const payload = { + name: formData.name, + project: projectName || "", + entities: formData.entities, + features: formData.features.map((f) => ({ + name: f.name, + value_type: parseInt(f.valueType, 10), + description: f.description, + })), + batch_source: formData.batchSource, + ttl_seconds: formData.ttlValue * (TTL_UNITS[formData.ttlUnit] || 1), + online: formData.online, + description: formData.description, + owner: formData.owner, + tags: Object.fromEntries( + formData.tags.filter((t) => t.key.trim()).map((t) => [t.key, t.value]), + ), + }; + applyFeatureView.mutate(payload, { + onSuccess: () => { + setIsEditModalOpen(false); + setErrorMessage(null); + setSuccessMessage( + `Feature view "${formData.name}" updated successfully.`, + ); + setTimeout(() => setSuccessMessage(null), 5000); + }, + onError: (err: unknown) => { + // Error shown inside the modal via submitError prop + const message = + err instanceof Error ? err.message : "An unexpected error occurred."; + setErrorMessage(message); + }, + }); + }; + + const fvUsage = usageData?.feature_usage?.[fvName]; + const runCount = fvUsage?.run_count ?? 0; + const lastUsed = fvUsage?.last_used ?? null; + const lastUsedLabel = + lastUsed != null ? new Date(lastUsed).toLocaleDateString() : "N/A"; + return ( + {successMessage && ( + <> + + + + )} + {errorMessage && ( + <> + + + + )} + + + setIsEditModalOpen(true)} + > + Edit Feature View + + + + + {usageData?.mlflow_enabled && ( + <> + + + + + + + + + + )} @@ -128,6 +300,10 @@ const RegularFeatureViewOverviewTab = ({ )} + {usageData?.mlflow_enabled && ( + + )} +

Tags

@@ -197,6 +373,20 @@ const RegularFeatureViewOverviewTab = ({ })}
+ + {isEditModalOpen && data && ( + { + setIsEditModalOpen(false); + setErrorMessage(null); + }} + onSubmit={handleEditSubmit} + initialData={buildEditFormData(data)} + isEdit + isSubmitting={applyFeatureView.isLoading} + submitError={errorMessage} + /> + )} ); }; diff --git a/ui/src/pages/feature-views/StreamFeatureViewInstance.tsx b/ui/src/pages/feature-views/StreamFeatureViewInstance.tsx index 0e22a6c2e5d..c0b9627bca5 100644 --- a/ui/src/pages/feature-views/StreamFeatureViewInstance.tsx +++ b/ui/src/pages/feature-views/StreamFeatureViewInstance.tsx @@ -1,11 +1,12 @@ import React from "react"; import { Route, Routes, useNavigate } from "react-router-dom"; import { useParams } from "react-router-dom"; -import { EuiPageTemplate } from "@elastic/eui"; +import { EuiBadge, EuiPageTemplate } from "@elastic/eui"; import { FeatureViewIcon } from "../../graphics/FeatureViewIcon"; -import { useMatchExact } from "../../hooks/useMatchSubpath"; +import { useMatchExact, useMatchSubpath } from "../../hooks/useMatchSubpath"; import StreamFeatureViewOverviewTab from "./StreamFeatureViewOverviewTab"; +import FeatureViewVersionsTab from "./FeatureViewVersionsTab"; import { useStreamFeatureViewCustomTabs, @@ -30,7 +31,17 @@ const StreamFeatureInstance = ({ data }: StreamFeatureInstanceProps) => { restrictWidth paddingSize="l" iconType={FeatureViewIcon} - pageTitle={`${featureViewName}`} + pageTitle={ + <> + {featureViewName} + {data?.meta?.currentVersionNumber != null && + data.meta.currentVersionNumber > 0 && ( + + v{data.meta.currentVersionNumber} + + )} + + } tabs={[ { label: "Overview", @@ -39,6 +50,13 @@ const StreamFeatureInstance = ({ data }: StreamFeatureInstanceProps) => { navigate(""); }, }, + { + label: "Versions", + isSelected: useMatchSubpath("versions"), + onClick: () => { + navigate("versions"); + }, + }, ...customNavigationTabs, ]} /> @@ -48,6 +66,12 @@ const StreamFeatureInstance = ({ data }: StreamFeatureInstanceProps) => { path="/" element={} /> + + } + /> {CustomTabRoutes}
diff --git a/ui/src/pages/feature-views/components/FeatureViewProjectionDisplayPanel.tsx b/ui/src/pages/feature-views/components/FeatureViewProjectionDisplayPanel.tsx index 1e31df47d69..a80f8039e19 100644 --- a/ui/src/pages/feature-views/components/FeatureViewProjectionDisplayPanel.tsx +++ b/ui/src/pages/feature-views/components/FeatureViewProjectionDisplayPanel.tsx @@ -1,9 +1,9 @@ import React from "react"; import { + EuiBadge, EuiBasicTable, EuiPanel, EuiSpacer, - EuiText, EuiTitle, } from "@elastic/eui"; import { useParams } from "react-router-dom"; @@ -17,6 +17,8 @@ const FeatureViewProjectionDisplayPanel = ( featureViewProjection: RequestDataDisplayPanelProps, ) => { const { projectName } = useParams(); + const isLabelView = (featureViewProjection as any).viewType === "labelView"; + const viewPath = isLabelView ? "label-view" : "feature-view"; const columns = [ { @@ -27,20 +29,21 @@ const FeatureViewProjectionDisplayPanel = ( name: "Type", field: "valueType", render: (valueType: any) => { - return feast.types.ValueType.Enum[valueType]; + if (typeof valueType === "string") return valueType; + return feast.types.ValueType.Enum[valueType] || String(valueType || ""); }, }, ]; return ( - - Feature View - + + {isLabelView ? "label view" : "feature view"} + {featureViewProjection?.featureViewName} diff --git a/ui/src/pages/feature-views/useLoadFeatureView.ts b/ui/src/pages/feature-views/useLoadFeatureView.ts index 08e8646f60f..5f88aab0a7d 100644 --- a/ui/src/pages/feature-views/useLoadFeatureView.ts +++ b/ui/src/pages/feature-views/useLoadFeatureView.ts @@ -1,71 +1,56 @@ -import { useContext } from "react"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import useLoadRegistry from "../../queries/useLoadRegistry"; +import { useParams } from "react-router-dom"; +import useResourceQuery, { + featureViewDetailPath, + restFeatureViewDetailToGeneric, +} from "../../queries/useResourceQuery"; +import type { genericFVType } from "../../parsers/mergedFVTypes"; const useLoadFeatureView = (featureViewName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.mergedFVMap[featureViewName]; - - return { - ...registryQuery, - data, - }; + const { projectName } = useParams(); + + return useResourceQuery({ + resourceType: `feature-view:${featureViewName}`, + project: projectName, + restPath: featureViewDetailPath(featureViewName, projectName || ""), + restSelect: restFeatureViewDetailToGeneric, + enabled: !!featureViewName, + }); }; const useLoadRegularFeatureView = (featureViewName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.featureViews?.find((fv) => { - return fv?.spec?.name === featureViewName; - }); - - return { - ...registryQuery, - data, - }; + const { projectName } = useParams(); + + return useResourceQuery({ + resourceType: `regular-fv:${featureViewName}`, + project: projectName, + restPath: featureViewDetailPath(featureViewName, projectName || ""), + restSelect: (d) => (d?.type === "featureView" ? d : undefined), + enabled: !!featureViewName, + }); }; const useLoadOnDemandFeatureView = (featureViewName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.onDemandFeatureViews?.find((fv) => { - return fv?.spec?.name === featureViewName; - }); - - return { - ...registryQuery, - data, - }; + const { projectName } = useParams(); + + return useResourceQuery({ + resourceType: `odfv:${featureViewName}`, + project: projectName, + restPath: featureViewDetailPath(featureViewName, projectName || ""), + restSelect: (d) => (d?.type === "onDemandFeatureView" ? d : undefined), + enabled: !!featureViewName, + }); }; const useLoadStreamFeatureView = (featureViewName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.streamFeatureViews?.find((fv) => { - return fv.spec?.name === featureViewName; - }); - - return { - ...registryQuery, - data, - }; + const { projectName } = useParams(); + + return useResourceQuery({ + resourceType: `sfv:${featureViewName}`, + project: projectName, + restPath: featureViewDetailPath(featureViewName, projectName || ""), + restSelect: (d) => (d?.type === "streamFeatureView" ? d : undefined), + enabled: !!featureViewName, + }); }; export default useLoadFeatureView; diff --git a/ui/src/pages/features/FeatureInstance.tsx b/ui/src/pages/features/FeatureInstance.tsx index fe81c6e619f..aa73db7c8c1 100644 --- a/ui/src/pages/features/FeatureInstance.tsx +++ b/ui/src/pages/features/FeatureInstance.tsx @@ -3,8 +3,9 @@ import { Route, Routes, useNavigate, useParams } from "react-router-dom"; import { EuiPageTemplate } from "@elastic/eui"; import { FeatureIcon } from "../../graphics/FeatureIcon"; -import { useMatchExact } from "../../hooks/useMatchSubpath"; +import { useMatchExact, useMatchSubpath } from "../../hooks/useMatchSubpath"; import FeatureOverviewTab from "./FeatureOverviewTab"; +import FeatureMonitoringTab from "./FeatureMonitoringTab"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; import { useFeatureCustomTabs, @@ -34,12 +35,20 @@ const FeatureInstance = () => { navigate(""); }, }, + { + label: "Monitoring", + isSelected: useMatchSubpath("monitoring"), + onClick: () => { + navigate("monitoring"); + }, + }, ...customNavigationTabs, ]} /> } /> + } /> {CustomTabRoutes} diff --git a/ui/src/pages/features/FeatureListPage.tsx b/ui/src/pages/features/FeatureListPage.tsx index 36087f98bc0..550a2116bda 100644 --- a/ui/src/pages/features/FeatureListPage.tsx +++ b/ui/src/pages/features/FeatureListPage.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from "react"; +import React, { useState } from "react"; import { EuiBasicTable, EuiTableFieldDataColumnType, @@ -15,13 +15,18 @@ import { EuiFlexGroup, EuiFlexItem, EuiFormRow, + EuiBadge, } from "@elastic/eui"; import EuiCustomLink from "../../components/EuiCustomLink"; import ExportButton from "../../components/ExportButton"; import { useParams } from "react-router-dom"; -import useLoadRegistry from "../../queries/useLoadRegistry"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadFeatureModels, { + FeatureModelInfo, +} from "../../queries/useLoadFeatureModels"; import { FeatureIcon } from "../../graphics/FeatureIcon"; +import useResourceQuery, { + featuresListPath, +} from "../../queries/useResourceQuery"; import { FEAST_FCO_TYPES } from "../../parsers/types"; import { getEntityPermissions, @@ -35,6 +40,7 @@ interface Feature { type: string; project?: string; permissions?: any[]; + models?: FeatureModelInfo[]; } type FeatureColumn = @@ -43,11 +49,23 @@ type FeatureColumn = const FeatureListPage = () => { const { projectName } = useParams(); - const registryUrl = useContext(RegistryPathContext); - const { data, isLoading, isError } = useLoadRegistry( - registryUrl, - projectName, - ); + const { + data: features, + isLoading, + isError, + } = useResourceQuery({ + resourceType: "features-list", + project: projectName, + restPath: featuresListPath(projectName), + restSelect: (d) => d.features, + }); + const { data: permissions } = useResourceQuery({ + resourceType: "permissions", + project: projectName, + restPath: `/permissions?project=${encodeURIComponent(projectName || "")}`, + restSelect: (d) => d.permissions, + }); + const { data: featureModelsData } = useLoadFeatureModels(); const [searchText, setSearchText] = useState(""); const [selectedPermissionAction, setSelectedPermissionAction] = useState(""); @@ -57,27 +75,24 @@ const FeatureListPage = () => { const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(100); - const featuresWithPermissions: Feature[] = (data?.allFeatures || []).map( - (feature) => { - return { - ...feature, - permissions: getEntityPermissions( - selectedPermissionAction - ? filterPermissionsByAction( - data?.permissions, - selectedPermissionAction, - ) - : data?.permissions, - FEAST_FCO_TYPES.featureView, - feature.featureView, - ), - }; - }, - ); + const featuresWithPermissions: Feature[] = (features || []).map((feature) => { + const featureRef = `${feature.featureView}:${feature.name}`; + return { + ...feature, + models: featureModelsData?.feature_models?.[featureRef] || [], + permissions: getEntityPermissions( + selectedPermissionAction + ? filterPermissionsByAction(permissions, selectedPermissionAction) + : permissions, + FEAST_FCO_TYPES.featureView, + feature.featureView, + ), + }; + }); - const features: Feature[] = featuresWithPermissions; + const enrichedFeatures: Feature[] = featuresWithPermissions; - const filteredFeatures = features.filter((feature) => + const filteredFeatures = enrichedFeatures.filter((feature) => feature.name.toLowerCase().includes(searchText.toLowerCase()), ); @@ -100,7 +115,6 @@ const FeatureListPage = () => { field: "name", sortable: true, render: (name: string, feature: Feature) => { - // For "All Projects" view, link to the specific project const itemProject = feature.project || projectName; return ( { field: "featureView", sortable: true, render: (featureView: string, feature: Feature) => { - // For "All Projects" view, link to the specific project const itemProject = feature.project || projectName; return ( @@ -126,6 +139,47 @@ const FeatureListPage = () => { }, }, { name: "Type", field: "type", sortable: true }, + { + name: "Models", + field: "models", + sortable: false, + render: (models: FeatureModelInfo[]) => { + if (!models || models.length === 0) { + return ( + + -- + + ); + } + if (models.length === 1) { + return ( + + {models[0].model_name} v{models[0].version} + + ); + } + return ( + + {models.map((m) => ( +
+ {m.model_name} v{m.version} +
+ ))} + + } + > + {models.length} models +
+ ); + }, + }, { name: "Permissions", field: "permissions", diff --git a/ui/src/pages/features/FeatureMonitoringTab.tsx b/ui/src/pages/features/FeatureMonitoringTab.tsx new file mode 100644 index 00000000000..bc8e2c2cf9f --- /dev/null +++ b/ui/src/pages/features/FeatureMonitoringTab.tsx @@ -0,0 +1,113 @@ +import React from "react"; +import { useParams } from "react-router-dom"; +import { + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiSkeletonText, + EuiEmptyPrompt, + EuiButton, +} from "@elastic/eui"; +import { + useFeatureMetrics, + useBaselineMetrics, +} from "../../queries/useMonitoringApi"; +import type { + NumericHistogram, + CategoricalHistogram, +} from "../../queries/useMonitoringApi"; +import { + NumericHistogramChart, + CategoricalHistogramChart, +} from "../monitoring/components/HistogramChart"; +import StatsPanel from "../monitoring/components/StatsPanel"; + +const FeatureMonitoringTab = () => { + const { projectName, FeatureViewName, FeatureName } = useParams(); + + const { + data: metrics, + isLoading, + isError, + } = useFeatureMetrics({ + project: projectName || "", + feature_view_name: FeatureViewName, + feature_name: FeatureName, + }); + + const { data: baselineMetrics } = useBaselineMetrics( + projectName || "", + FeatureViewName, + FeatureName, + ); + + if (isLoading) { + return ; + } + + const latestMetric = (() => { + if (!metrics || metrics.length === 0) return null; + const withData = metrics.filter((m) => m.row_count > 0); + const candidates = withData.length > 0 ? withData : metrics; + return candidates.reduce((a, b) => (a.metric_date > b.metric_date ? a : b)); + })(); + + const baselineMetric = + baselineMetrics && baselineMetrics.length > 0 ? baselineMetrics[0] : null; + + if (isError || !latestMetric) { + return ( + No Monitoring Data} + body={ +

+ No monitoring metrics available for this feature. Run a monitoring + compute job to generate data quality metrics. +

+ } + actions={ + + Go to Monitoring + + } + /> + ); + } + + const isNumeric = latestMetric.feature_type === "numeric"; + + return ( + <> + + + {isNumeric && latestMetric.histogram && ( + + )} + {!isNumeric && latestMetric.histogram && ( + + )} + {!latestMetric.histogram && ( + No Histogram} + body={

Histogram data is not available.

} + /> + )} +
+ + + +
+ + + ); +}; + +export default FeatureMonitoringTab; diff --git a/ui/src/pages/features/FeatureOverviewTab.tsx b/ui/src/pages/features/FeatureOverviewTab.tsx index 6b613abc589..d895f52c585 100644 --- a/ui/src/pages/features/FeatureOverviewTab.tsx +++ b/ui/src/pages/features/FeatureOverviewTab.tsx @@ -1,4 +1,5 @@ import { + EuiBadge, EuiFlexGroup, EuiHorizontalRule, EuiLoadingSpinner, @@ -63,7 +64,9 @@ const FeatureOverviewTab = () => { Value Type - {feast.types.ValueType.Enum[featureData?.valueType!]} + {featureData?.valueType + ? feast.types.ValueType.Enum[featureData.valueType] + : featureData?.type || data?.type || "—"} Description @@ -71,13 +74,21 @@ const FeatureOverviewTab = () => { {featureData?.description} - FeatureView + + {data?.kind === "label" ? "Label View" : "Feature View"} + {FeatureViewName} + {data?.kind === "label" && ( + <> + {" "} + label view + + )}
diff --git a/ui/src/pages/features/useLoadFeature.ts b/ui/src/pages/features/useLoadFeature.ts index 54bf31e996f..be322a9c8aa 100644 --- a/ui/src/pages/features/useLoadFeature.ts +++ b/ui/src/pages/features/useLoadFeature.ts @@ -1,27 +1,32 @@ -import { useContext } from "react"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import useLoadRegistry from "../../queries/useLoadRegistry"; +import { useParams } from "react-router-dom"; +import useResourceQuery, { + featureDetailPath, +} from "../../queries/useResourceQuery"; const useLoadFeature = (featureViewName: string, featureName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); + const { projectName } = useParams(); - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.featureViews?.find((fv) => { - return fv?.spec?.name === featureViewName; - }); + const fvQuery = useResourceQuery({ + resourceType: `feature:${featureViewName}:${featureName}`, + project: projectName, + restPath: featureDetailPath( + featureViewName, + featureName, + projectName || "", + ), + restSelect: (d) => d, + enabled: !!featureViewName && !!featureName, + }); const featureData = - data === undefined + fvQuery.data === undefined ? undefined - : data?.spec?.features?.find((f) => { - return f.name === featureName; - }); + : fvQuery.data?.spec?.features?.find( + (f: any) => f.name === featureName, + ) || fvQuery.data; return { - ...registryQuery, + ...fvQuery, featureData, }; }; diff --git a/ui/src/pages/label-views/ActiveLearningTab.tsx b/ui/src/pages/label-views/ActiveLearningTab.tsx new file mode 100644 index 00000000000..e880c2aaa55 --- /dev/null +++ b/ui/src/pages/label-views/ActiveLearningTab.tsx @@ -0,0 +1,739 @@ +import React, { useContext, useState, useMemo, useCallback } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiForm, + EuiFormRow, + EuiFieldText, + EuiButton, + EuiSpacer, + EuiCallOut, + EuiText, + EuiLoadingSpinner, + EuiFlexGroup, + EuiFlexItem, + EuiStat, + EuiBadge, + EuiBasicTable, + EuiBasicTableColumn, + EuiCodeBlock, + EuiIcon, + EuiEmptyPrompt, + EuiFieldNumber, + EuiSuperSelect, + EuiFieldSearch, + EuiTablePagination, + EuiModal, + EuiModalHeader, + EuiModalHeaderTitle, + EuiModalBody, + EuiModalFooter, + EuiOverlayMask, + EuiGlobalToastList, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; +import useLoadRegistry from "../../queries/useLoadRegistry"; +import useAnnotationConfig from "./useAnnotationConfig"; + +interface CandidateData { + unlabeled_entities: Record[]; + total_labeled: number; + total_unlabeled: number; + entity_names: string[]; + feature_names: string[]; + label_view: string; + reference_feature_view: string | null; +} + +const PAGE_SIZE_OPTIONS = [10, 25, 50, 100]; + +const ActiveLearningTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading, data } = useLoadLabelView(name); + const { data: registryData } = useLoadRegistry(registryUrl); + const { data: annotationConfig } = useAnnotationConfig(name); + + const [refFV, setRefFV] = useState(""); + const [limit, setLimit] = useState(50); + const [candidates, setCandidates] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [selectedItems, setSelectedItems] = useState[]>([]); + const [labelValues, setLabelValues] = useState>({}); + const [submitting, setSubmitting] = useState(false); + const [submitSuccess, setSubmitSuccess] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(25); + const [toasts, setToasts] = useState< + Array<{ + id: string; + title: string; + color: "success" | "danger"; + iconType: string; + }> + >([]); + + const removeToast = useCallback((removedToast: { id: string }) => { + setToasts((prev) => prev.filter((t) => t.id !== removedToast.id)); + }, []); + + const spec = data?.object?.spec || data?.spec || {}; + const labelFields: { name: string; valueType?: string }[] = + spec.features || []; + const labelerField: string | null = + spec.labelerField || spec.labeler_field || null; + const configLabelValues = annotationConfig?.label_values || {}; + const configLabelWidgets = annotationConfig?.label_widgets || {}; + + const featureViewOptions = (registryData?.objects?.featureViews || []) + .filter((fv: any) => { + const fvName = fv.spec?.name || fv.name || ""; + return fvName !== name; + }) + .map((fv: any) => ({ + value: fv.spec?.name || fv.name || "", + inputDisplay: fv.spec?.name || fv.name || "Unknown", + dropdownDisplay: ( + + {fv.spec?.name || fv.name} + {fv.spec?.description && ( + +

{fv.spec.description}

+
+ )} +
+ ), + })); + + const fetchCandidates = async () => { + setLoading(true); + setError(null); + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const response = await fetch(`${baseUrl}/active-learning/candidates`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + feature_view: name, + reference_feature_view: refFV || undefined, + limit: limit, + }), + }); + const result = await response.json(); + if (!response.ok) { + const detail = result.detail; + setError( + typeof detail === "string" + ? detail + : Array.isArray(detail) + ? detail.map((d: any) => d.msg || JSON.stringify(d)).join("; ") + : "Failed to fetch candidates", + ); + } else { + setCandidates(result); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setLoading(false); + } + }; + + const entityColumns: EuiBasicTableColumn>[] = candidates + ? Object.keys(candidates.unlabeled_entities[0] || {}).map((key) => ({ + field: key, + name: key, + sortable: true, + })) + : []; + + const filteredCandidates = useMemo(() => { + if (!candidates) return []; + if (!searchQuery.trim()) return candidates.unlabeled_entities; + const query = searchQuery.toLowerCase(); + return candidates.unlabeled_entities.filter((row) => + Object.values(row).some( + (val) => val != null && String(val).toLowerCase().includes(query), + ), + ); + }, [candidates, searchQuery]); + + const paginatedCandidates = useMemo(() => { + const start = pageIndex * pageSize; + return filteredCandidates.slice(start, start + pageSize); + }, [filteredCandidates, pageIndex, pageSize]); + + const handleSubmitLabels = async () => { + if (selectedItems.length === 0) return; + setSubmitting(true); + setSubmitSuccess(null); + setError(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const pushSourceName = + spec.source?.pushSourceName || + spec.source?.name || + `${name}_push_source`; + + const rows = selectedItems.map((entity) => { + const row: Record = { ...entity, ...labelValues }; + row["event_timestamp"] = new Date().toISOString(); + return row; + }); + + const columnar: Record = {}; + if (rows.length > 0) { + for (const key of Object.keys(rows[0])) { + columnar[key] = rows.map((r) => r[key]); + } + } + + const response = await fetch(`${baseUrl}/push`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + push_source_name: pushSourceName, + df: columnar, + to: "online_and_offline", + }), + }); + + if (response.ok) { + const msg = `Successfully labeled ${selectedItems.length} record${selectedItems.length !== 1 ? "s" : ""}`; + setSubmitSuccess(msg); + setToasts((prev) => [ + ...prev, + { + id: String(Date.now()), + title: msg, + color: "success", + iconType: "check", + }, + ]); + setSelectedItems([]); + setLabelValues({}); + fetchCandidates(); + } else { + const errData = await response.json().catch(() => null); + const detail = errData?.detail; + setError( + typeof detail === "string" + ? detail + : Array.isArray(detail) + ? detail.map((d: any) => d.msg || JSON.stringify(d)).join("; ") + : `Label submission failed (${response.status})`, + ); + } + } catch (e: any) { + setError(e.message || "Network error during label submission"); + } finally { + setSubmitting(false); + } + }; + + if (isLoading) { + return ( +

+ Loading... +

+ ); + } + + const exportJSON = () => { + if (!candidates) return; + const blob = new Blob( + [JSON.stringify(candidates.unlabeled_entities, null, 2)], + { type: "application/json" }, + ); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `${name}_unlabeled_candidates.json`; + a.click(); + URL.revokeObjectURL(url); + }; + + const argillaPushCode = candidates + ? `import argilla as rg +import requests + +# Fetch unlabeled candidates from Feast +response = requests.post( + "${window.location.origin}/api/v1/active-learning/candidates", + json={ + "feature_view": "${name}", + ${refFV ? `"reference_feature_view": "${refFV}",` : ""} + "limit": ${limit}, + }, +) +candidates = response.json()["unlabeled_entities"] + +# Create Argilla records for annotation +records = [] +for entity in candidates: + records.append( + rg.Record( + fields={"text": f"Review entity: {entity}"}, + metadata=entity, + suggestions=[], # Add model predictions here for pre-labeling + ) + ) + +# Push to Argilla dataset for human annotation +dataset = rg.Dataset(name="${name}_annotation", settings=your_settings) +dataset.records.log(records) +print(f"Pushed {len(records)} candidates for annotation")` + : ""; + + return ( + + + + Find records that exist in your feature views but have NOT been + labeled yet. Label them directly here in the Feast UI, or export + candidates to your annotation tool (Argilla, Label Studio) for + targeted human review. + + + + + + + +

Find Unlabeled Records

+
+ + + + + {featureViewOptions.length > 0 ? ( + setRefFV(value)} + placeholder="Select a feature view..." + hasDividers + /> + ) : ( + setRefFV(e.target.value)} + /> + )} + + + + setLimit(parseInt(e.target.value) || 50)} + /> + + + + + + Find Unlabeled Records + + +
+ + {error && !isModalOpen && ( + + + + {error} + + + )} + + {candidates && ( + + + + + + + + + + + + + + + + + 0 + ? `${( + (candidates.total_labeled / + (candidates.total_labeled + + candidates.total_unlabeled)) * + 100 + ).toFixed(1)}%` + : "N/A" + } + description="Label Coverage" + titleColor="primary" + /> + + + + + + + {candidates.unlabeled_entities.length > 0 ? ( + + + + + +

+ Unlabeled Records{" "} + + {candidates.unlabeled_entities.length} + + {selectedItems.length > 0 && ( + <> + {" "} + + {selectedItems.length} selected + + + )} +

+
+
+ + + {selectedItems.length > 0 && ( + + setIsModalOpen(true)} + iconType="tag" + > + Label Selected ({selectedItems.length}) + + + )} + + + Export JSON + + + + +
+ + + Select records below, then click "Label Selected" to + assign labels. + + + { + setSearchQuery(e.target.value); + setPageIndex(0); + }} + isClearable + fullWidth + /> + + ) => + Object.values(item).join("_") + } + selection={{ + onSelectionChange: (items: Record[]) => + setSelectedItems(items), + selectable: () => true, + selectableMessage: () => "Select to label", + }} + /> + {filteredCandidates.length > pageSize && ( + <> + + setPageIndex(page)} + itemsPerPage={pageSize} + onChangeItemsPerPage={(size) => { + setPageSize(size); + setPageIndex(0); + }} + itemsPerPageOptions={PAGE_SIZE_OPTIONS} + /> + + )} +
+ + {submitSuccess && ( + + + + + )} + + {isModalOpen && ( + + setIsModalOpen(false)} + maxWidth={500} + > + + + Label {selectedItems.length}{" "} + Record + {selectedItems.length !== 1 ? "s" : ""} + + + + + Assign label values to all {selectedItems.length}{" "} + selected records. Labels will be pushed via{" "} + FeatureStore.push(). + + + + {labelFields + .filter((f) => f.name !== labelerField) + .map((field) => { + const widget = configLabelWidgets[field.name]; + const values = configLabelValues[field.name]; + let input; + + if ( + widget === "binary" && + values && + values.length === 2 + ) { + input = ( + ({ + value: v, + inputDisplay: + v === "1" + ? "Yes (1)" + : v === "0" + ? "No (0)" + : v, + })), + ]} + valueOfSelected={ + labelValues[field.name] || "" + } + onChange={(val) => + setLabelValues((prev) => ({ + ...prev, + [field.name]: val, + })) + } + /> + ); + } else if (values && values.length > 0) { + input = ( + ({ + value: v, + inputDisplay: v, + })), + ]} + valueOfSelected={ + labelValues[field.name] || "" + } + onChange={(val) => + setLabelValues((prev) => ({ + ...prev, + [field.name]: val, + })) + } + /> + ); + } else if (widget === "number") { + input = ( + + setLabelValues((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + /> + ); + } else { + input = ( + + setLabelValues((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + /> + ); + } + + return ( + + {input} + + ); + })} + {labelerField && ( + + + setLabelValues((prev) => ({ + ...prev, + [labelerField]: e.target.value, + })) + } + /> + + )} + + {error && ( + + + + {error} + + + )} + + + { + setIsModalOpen(false); + setLabelValues({}); + }} + > + Cancel + + { + await handleSubmitLabels(); + if (!error) { + setIsModalOpen(false); + } + }} + isLoading={submitting} + iconType="check" + > + Submit Labels + + + + + )} +
+ ) : ( + All records are labeled!} + body="No unlabeled records found in the reference feature view." + /> + )} + + + + + +

Push Candidates to Argilla

+
+ + + Use this script to push unlabeled candidates to Argilla for + annotation: + + + + {argillaPushCode} + +
+
+ )} + +
+ +
+
+ ); +}; + +export default ActiveLearningTab; diff --git a/ui/src/pages/label-views/AnnotateTab.tsx b/ui/src/pages/label-views/AnnotateTab.tsx new file mode 100644 index 00000000000..f378e2dfcb7 --- /dev/null +++ b/ui/src/pages/label-views/AnnotateTab.tsx @@ -0,0 +1,149 @@ +import React, { useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiButtonGroup, + EuiSpacer, + EuiPanel, + EuiText, + EuiLoadingSpinner, + EuiCallOut, + EuiBadge, + EuiFlexGroup, + EuiFlexItem, +} from "@elastic/eui"; +import ActiveLearningTab from "./ActiveLearningTab"; +import RagLabelingMethod from "./RagLabelingMethod"; +import ClassificationMethod from "./ClassificationMethod"; +import EntityFormMethod from "./EntityFormMethod"; +import useAnnotationConfig from "./useAnnotationConfig"; + +const PROFILE_DESCRIPTIONS: Record = { + "document-span": + "Load documents, highlight text spans, and label them for RAG retrieval or citation evaluation.", + "review-edit": + "Review and edit existing label records in a table view. Supports inline editing and batch push.", + "entity-form": + "Fill label fields per entity using a structured form. One record at a time.", + "active-learning": + "Surface unlabeled entities from a reference feature view and label them.", +}; + +const AnnotateTab = () => { + const { labelViewName } = useParams(); + const { + data: config, + isLoading, + isError, + } = useAnnotationConfig(labelViewName || ""); + + const detectedProfile = config?.profile || "table"; + + const availableMethods = React.useMemo(() => { + const methods: { id: string; label: string }[] = []; + + if (detectedProfile === "document-span") { + methods.push({ id: "document-span", label: "Document Span" }); + methods.push({ id: "review-edit", label: "Review & Edit" }); + return methods; + } + + if (detectedProfile === "entity-form") { + methods.push({ id: "entity-form", label: "Entity Form" }); + methods.push({ id: "review-edit", label: "Review & Edit" }); + methods.push({ id: "active-learning", label: "Active Learning" }); + return methods; + } + + if (detectedProfile === "active-learning") { + methods.push({ id: "active-learning", label: "Active Learning" }); + methods.push({ id: "entity-form", label: "Entity Form" }); + methods.push({ id: "review-edit", label: "Review & Edit" }); + return methods; + } + + methods.push({ id: "review-edit", label: "Review & Edit" }); + methods.push({ id: "active-learning", label: "Active Learning" }); + methods.push({ id: "entity-form", label: "Entity Form" }); + return methods; + }, [detectedProfile]); + + const [selectedMethod, setSelectedMethod] = useState(null); + const activeMethod = + selectedMethod || availableMethods[0]?.id || "review-edit"; + + if (isLoading) { + return ( + + + + + + Loading labeling configuration... + + + ); + } + + if (isError || !config) { + return ( + +

+ Falling back to Review & Edit view. Define{" "} + feast.io/labeling-method in your LabelView tags to + configure the labeling experience. +

+
+ ); + } + + return ( + + + + + + Labeling Method + + + + profile: {detectedProfile} + + + + setSelectedMethod(id)} + buttonSize="m" + isFullWidth={false} + /> + {PROFILE_DESCRIPTIONS[activeMethod] && ( + <> + + + {PROFILE_DESCRIPTIONS[activeMethod]} + + + )} + + + + + {activeMethod === "active-learning" && } + {activeMethod === "document-span" && ( + + )} + {activeMethod === "review-edit" && } + {activeMethod === "entity-form" && ( + + )} + + ); +}; + +export default AnnotateTab; diff --git a/ui/src/pages/label-views/BatchUploadTab.tsx b/ui/src/pages/label-views/BatchUploadTab.tsx new file mode 100644 index 00000000000..6f3930c5d92 --- /dev/null +++ b/ui/src/pages/label-views/BatchUploadTab.tsx @@ -0,0 +1,332 @@ +import React, { useContext, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiForm, + EuiFormRow, + EuiButton, + EuiSpacer, + EuiCallOut, + EuiText, + EuiLoadingSpinner, + EuiFlexGroup, + EuiFlexItem, + EuiBadge, + EuiSelect, + EuiFilePicker, + EuiBasicTable, + EuiBasicTableColumn, + EuiCodeBlock, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; + +const BatchUploadTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading, data } = useLoadLabelView(name); + + const [fileData, setFileData] = useState(null); + const [fileName, setFileName] = useState(""); + const [pushTarget, setPushTarget] = useState("online"); + const [uploading, setUploading] = useState(false); + const [result, setResult] = useState(null); + const [error, setError] = useState(null); + const [parseError, setParseError] = useState(null); + + if (isLoading) { + return ( +

+ Loading... +

+ ); + } + + const spec = data?.object?.spec || data?.spec || {}; + const pushSourceName = + spec.streamSource?.pushOptions?.pushSourceName || + spec.batchSource?.name?.replace("_batch", "_push_source") || + `${name}_push_source`; + + const features = data?.features || spec.features || []; + const entities = spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || []; + + const handleFileChange = (files: FileList | null) => { + if (!files || files.length === 0) { + setFileData(null); + setFileName(""); + setParseError(null); + return; + } + + const file = files[0]; + setFileName(file.name); + setParseError(null); + + const reader = new FileReader(); + reader.onload = (e) => { + try { + const text = e.target?.result as string; + if (file.name.endsWith(".json")) { + const parsed = JSON.parse(text); + const rows = Array.isArray(parsed) + ? parsed + : parsed.data || parsed.records || [parsed]; + setFileData(rows); + } else if (file.name.endsWith(".csv")) { + const lines = text.trim().split("\n"); + if (lines.length < 2) { + setParseError( + "CSV must have at least a header row and one data row", + ); + return; + } + const headers = lines[0] + .split(",") + .map((h) => h.trim().replace(/"/g, "")); + const rows = []; + for (let i = 1; i < lines.length; i++) { + const values = lines[i] + .split(",") + .map((v) => v.trim().replace(/"/g, "")); + const row: Record = {}; + headers.forEach((h, idx) => { + const val = values[idx] || ""; + const numVal = Number(val); + row[h] = val === "" ? null : isNaN(numVal) ? val : numVal; + }); + rows.push(row); + } + setFileData(rows); + } else { + setParseError("Unsupported file format. Use .csv or .json"); + } + } catch (e: any) { + setParseError(`Failed to parse file: ${e.message}`); + setFileData(null); + } + }; + reader.readAsText(file); + }; + + const handleUpload = async () => { + if (!fileData || fileData.length === 0) return; + + setUploading(true); + setError(null); + setResult(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + + const dataWithTimestamp = fileData.map((row) => ({ + ...row, + event_timestamp: row.event_timestamp || new Date().toISOString(), + })); + + const response = await fetch(`${baseUrl}/batch-push`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + push_source_name: pushSourceName, + data: dataWithTimestamp, + to: pushTarget, + }), + }); + + const res = await response.json(); + if (!response.ok) { + const detail = res.detail; + setError( + typeof detail === "string" + ? detail + : Array.isArray(detail) + ? detail.map((d: any) => d.msg || JSON.stringify(d)).join("; ") + : "Upload failed", + ); + } else { + setResult(res); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setUploading(false); + } + }; + + const previewColumns: EuiBasicTableColumn[] = fileData + ? Object.keys(fileData[0] || {}).map((col) => ({ + field: col, + name: col, + truncateText: true, + width: "120px", + })) + : []; + + const csvTemplate = [ + entities.join(",") + + "," + + features.map((f: any) => f.name || f).join(",") + + ",event_timestamp", + entities.map(() => "").join(",") + + "," + + features.map(() => "").join(",") + + ",2026-01-01T00:00:00Z", + ].join("\n"); + + return ( + + + + Upload a CSV or JSON file to push labels in bulk. Useful for + correcting labels, importing from external systems, or backfilling + historical labels. + + + + + + + +

Upload File

+
+ + + + + + + + {parseError && ( + + + + {parseError} + + + )} + + + setPushTarget(e.target.value)} + /> + + + + + + Push {fileData ? `${fileData.length} rows` : "Labels"} + + +
+ + {/* Preview */} + {fileData && fileData.length > 0 && ( + + + + + + +

+ Preview{" "} + {fileData.length} rows{" "} + {fileName} +

+
+
+
+ + + {fileData.length > 10 && ( + + Showing first 10 of {fileData.length} rows + + )} +
+
+ )} + + {error && ( + + + + {error} + + + )} + + {result && ( + + + + + Pushed {result.rows_pushed} rows to{" "} + {pushTarget} store. + + + + )} + + + + {/* Template */} + + +

CSV Template

+
+ + + Expected columns for this LabelView: + + + + {csvTemplate} + +
+
+ ); +}; + +export default BatchUploadTab; diff --git a/ui/src/pages/label-views/ClassificationMethod.tsx b/ui/src/pages/label-views/ClassificationMethod.tsx new file mode 100644 index 00000000000..9d4366f2e00 --- /dev/null +++ b/ui/src/pages/label-views/ClassificationMethod.tsx @@ -0,0 +1,465 @@ +import React, { + useState, + useContext, + useEffect, + useCallback, + useMemo, +} from "react"; +import { useParams } from "react-router-dom"; +import { + EuiCallOut, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiPanel, + EuiText, + EuiLoadingSpinner, + EuiBasicTable, + EuiBasicTableColumn, + EuiSelect, + EuiBadge, + EuiFieldSearch, + EuiTablePagination, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; +import useAnnotationConfig from "./useAnnotationConfig"; + +interface LabelRow { + _id: string; + [key: string]: any; +} + +const PAGE_SIZE_OPTIONS = [10, 25, 50]; + +const ClassificationMethod = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const { data } = useLoadLabelView(labelViewName || ""); + const { data: annotationConfig } = useAnnotationConfig(labelViewName || ""); + + const [rows, setRows] = useState([]); + const [originalRows, setOriginalRows] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const [isSaving, setIsSaving] = useState(false); + const [pushSuccess, setPushSuccess] = useState(null); + const [searchQuery, setSearchQuery] = useState(""); + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(25); + + const spec = data?.object?.spec || data?.spec || {}; + const labelFields: { name: string; valueType?: string }[] = useMemo( + () => spec.features || [], + [spec.features], + ); + const entities: string[] = useMemo( + () => + spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || [], + [spec.entityColumns, spec.entities], + ); + + const configuredValues = annotationConfig?.label_values || {}; + const fieldRoles = annotationConfig?.field_roles || {}; + const labelWidgets = annotationConfig?.label_widgets || {}; + + const fetchLabels = useCallback(async () => { + setIsLoading(true); + setError(null); + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const response = await fetch(`${baseUrl}/list-labels`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + feature_view: labelViewName || "", + limit: 200, + }), + }); + if (!response.ok) { + throw new Error(`Failed to fetch labels (${response.status})`); + } + const result = await response.json(); + const labelData: Record[] = result.labels || []; + const mapped = labelData.map((row, idx) => ({ + ...row, + _id: `row_${idx}_${Object.values(row).join("_")}`, + })); + setRows(mapped); + setOriginalRows(JSON.parse(JSON.stringify(mapped))); + } catch (e: any) { + setError(e.message || "Failed to load labels"); + } finally { + setIsLoading(false); + } + }, [labelViewName, registryUrl]); + + useEffect(() => { + if (labelViewName) { + fetchLabels(); + } + }, [labelViewName, fetchLabels]); + + const handleFieldChange = (rowId: string, field: string, value: string) => { + setRows((prev) => + prev.map((row) => (row._id === rowId ? { ...row, [field]: value } : row)), + ); + }; + + const getChangedRows = () => { + return rows.filter((row) => { + const original = originalRows.find((o) => o._id === row._id); + if (!original) return false; + return labelFields.some((f) => row[f.name] !== original[f.name]); + }); + }; + + const resetChanges = () => { + setRows(JSON.parse(JSON.stringify(originalRows))); + }; + + const saveToLabelView = async () => { + const changed = getChangedRows(); + if (changed.length === 0) return; + + setIsSaving(true); + setError(null); + setPushSuccess(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const pushSourceName = + spec.source?.pushSourceName || + spec.source?.name || + `${labelViewName}_push_source`; + + const pushRows = changed.map((row) => { + const pushRow: Record = {}; + entities.forEach((e) => { + pushRow[e] = row[e]; + }); + labelFields.forEach((f) => { + pushRow[f.name] = row[f.name]; + }); + pushRow["event_timestamp"] = new Date().toISOString(); + return pushRow; + }); + + const columnar: Record = {}; + if (pushRows.length > 0) { + for (const key of Object.keys(pushRows[0])) { + columnar[key] = pushRows.map((r) => r[key]); + } + } + + const response = await fetch(`${baseUrl}/push`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + push_source_name: pushSourceName, + df: columnar, + to: "online_and_offline", + }), + }); + + if (response.ok) { + setPushSuccess( + `Successfully pushed ${changed.length} updated labels to ${labelViewName}`, + ); + setOriginalRows(JSON.parse(JSON.stringify(rows))); + } else { + const errData = await response.json().catch(() => null); + setError(errData?.detail || `Push failed (${response.status})`); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setIsSaving(false); + } + }; + + const exportJSON = () => { + const exportData = rows.map((row) => { + const { _id, ...rest } = row; + return rest; + }); + const blob = new Blob([JSON.stringify(exportData, null, 2)], { + type: "application/json", + }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `${labelViewName}_labels.json`; + a.click(); + URL.revokeObjectURL(url); + }; + + const filteredRows = useMemo(() => { + if (!searchQuery.trim()) return rows; + const q = searchQuery.toLowerCase(); + return rows.filter((row) => + Object.entries(row) + .filter(([key]) => key !== "_id") + .some( + ([, val]) => val != null && String(val).toLowerCase().includes(q), + ), + ); + }, [rows, searchQuery]); + + const paginatedRows = useMemo(() => { + const start = pageIndex * pageSize; + return filteredRows.slice(start, start + pageSize); + }, [filteredRows, pageIndex, pageSize]); + + const uniqueValuesForField = useMemo(() => { + const result: Record = {}; + labelFields.forEach((field) => { + const values = new Set(); + rows.forEach((row) => { + if (row[field.name] != null && String(row[field.name]).trim() !== "") { + values.add(String(row[field.name])); + } + }); + result[field.name] = Array.from(values).sort(); + }); + return result; + }, [rows, labelFields]); + + const metadataFields = ["event_timestamp", "labeler"]; + + const entityColumns: EuiBasicTableColumn[] = entities.map( + (ent) => ({ + field: ent, + name: ent, + sortable: true, + truncateText: true, + }), + ); + + const labelColumns: EuiBasicTableColumn[] = labelFields + .filter((field) => !metadataFields.includes(field.name)) + .map((field) => { + const configVals = configuredValues[field.name]; + const role = fieldRoles[field.name]; + const widget = labelWidgets[field.name]; + + return { + field: field.name, + name: field.name, + render: (value: any, row: LabelRow) => { + if (widget === "binary" && configVals && configVals.length === 2) { + return ( + ({ + value: o, + text: o === "1" ? "Yes (1)" : o === "0" ? "No (0)" : o, + })), + ]} + value={value != null ? String(value) : ""} + onChange={(e) => + handleFieldChange(row._id, field.name, e.target.value) + } + /> + ); + } + const dropdownOptions = + configVals || uniqueValuesForField[field.name] || []; + if ( + (role === "label" || dropdownOptions.length > 0) && + dropdownOptions.length <= 30 + ) { + return ( + ({ + value: o, + text: o, + })), + ]} + value={value != null ? String(value) : ""} + onChange={(e) => + handleFieldChange(row._id, field.name, e.target.value) + } + /> + ); + } + return {value != null ? String(value) : ""}; + }, + }; + }); + + const metadataColumns: EuiBasicTableColumn[] = labelFields + .filter((field) => metadataFields.includes(field.name)) + .map((field) => ({ + field: field.name, + name: field.name, + sortable: true, + truncateText: true, + })); + + const columns = [...entityColumns, ...labelColumns, ...metadataColumns]; + + const changedCount = getChangedRows().length; + + if (isLoading) { + return ( + + + + + + Loading labels from {labelViewName}... + + + ); + } + + return ( + + +

+ Review and correct existing labels in the table below. Changes are + pushed to {labelViewName} via its PushSource and + governed by the configured conflict policy. +

+
+ + {error && ( + <> + + +

{error}

+
+ + )} + + {pushSuccess && ( + <> + + + + )} + + + + {rows.length === 0 ? ( + + +

+ No labels found. Use Entity Form or Active Learning to add labels + first, then review them here. +

+
+
+ ) : ( + <> + + + { + setSearchQuery(e.target.value); + setPageIndex(0); + }} + isClearable + /> + + + + {changedCount > 0 && ( + + {changedCount} changed + + )} + + + Export JSON + + + + + Reset + + + + + Save ({changedCount}) + + + + + + + + + + { + const original = originalRows.find((o) => o._id === row._id); + const isChanged = + original && + labelFields.some((f) => row[f.name] !== original[f.name]); + return isChanged + ? { style: { backgroundColor: "rgba(255, 200, 0, 0.05)" } } + : {}; + }} + /> + + + {filteredRows.length > pageSize && ( + <> + + setPageIndex(page)} + itemsPerPage={pageSize} + onChangeItemsPerPage={(size) => { + setPageSize(size); + setPageIndex(0); + }} + itemsPerPageOptions={PAGE_SIZE_OPTIONS} + /> + + )} + + )} +
+ ); +}; + +export default ClassificationMethod; diff --git a/ui/src/pages/label-views/EntityFormMethod.tsx b/ui/src/pages/label-views/EntityFormMethod.tsx new file mode 100644 index 00000000000..025f08b277c --- /dev/null +++ b/ui/src/pages/label-views/EntityFormMethod.tsx @@ -0,0 +1,484 @@ +import React, { useState, useContext, useEffect, useMemo } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiCallOut, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiPanel, + EuiTitle, + EuiText, + EuiFormRow, + EuiFieldText, + EuiFieldNumber, + EuiSelect, + EuiTextArea, + EuiButtonGroup, + EuiBadge, + EuiIcon, + EuiEmptyPrompt, + EuiForm, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; +import { AnnotationConfig } from "./useAnnotationConfig"; + +interface EntityFormMethodProps { + annotationConfig: AnnotationConfig; +} + +const EntityFormMethod = ({ annotationConfig }: EntityFormMethodProps) => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const { data } = useLoadLabelView(labelViewName || ""); + + const spec = data?.object?.spec || data?.spec || {}; + const entities: string[] = useMemo( + () => + spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || [], + [spec.entityColumns, spec.entities], + ); + const labelFields: { name: string; valueType?: string }[] = useMemo( + () => spec.features || [], + [spec.features], + ); + + const fieldRoles = annotationConfig.field_roles; + const labelValues = annotationConfig.label_values; + const labelWidgets = annotationConfig.label_widgets; + const labelerField = annotationConfig.labeler_field || "labeler"; + + const [entityValues, setEntityValues] = useState>({}); + const [fieldInputs, setFieldInputs] = useState>({}); + const [isSaving, setIsSaving] = useState(false); + const [error, setError] = useState(null); + const [pushSuccess, setPushSuccess] = useState(null); + const [labelCount, setLabelCount] = useState(0); + + const editableFields = useMemo( + () => + labelFields.filter( + (f) => f.name !== labelerField && f.name !== "event_timestamp", + ), + [labelFields, labelerField], + ); + + useEffect(() => { + const defaults: Record = {}; + editableFields.forEach((f) => { + const vals = labelValues[f.name]; + if (vals && vals.length > 0) { + defaults[f.name] = ""; + } else { + defaults[f.name] = ""; + } + }); + setFieldInputs(defaults); + }, [editableFields, labelValues]); + + const resetForm = () => { + const defaults: Record = {}; + editableFields.forEach((f) => { + defaults[f.name] = ""; + }); + setFieldInputs(defaults); + setError(null); + setPushSuccess(null); + }; + + const isFormValid = useMemo(() => { + const hasEntity = entities.every( + (e) => entityValues[e] && entityValues[e].trim() !== "", + ); + const hasAtLeastOneLabel = editableFields.some( + (f) => + fieldRoles[f.name] === "label" && + fieldInputs[f.name] && + fieldInputs[f.name].trim() !== "", + ); + return hasEntity && hasAtLeastOneLabel; + }, [entities, entityValues, editableFields, fieldInputs, fieldRoles]); + + const submitLabel = async () => { + if (!isFormValid) return; + + setIsSaving(true); + setError(null); + setPushSuccess(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const pushSourceName = + annotationConfig.push_source_name || + spec.source?.pushSourceName || + spec.source?.name || + `${labelViewName}_push_source`; + + const pushRow: Record = {}; + entities.forEach((e) => { + pushRow[e] = entityValues[e]; + }); + editableFields.forEach((f) => { + if (fieldInputs[f.name] && fieldInputs[f.name].trim() !== "") { + const widget = labelWidgets[f.name]; + if (widget === "number" || widget === "binary") { + pushRow[f.name] = Number(fieldInputs[f.name]); + } else { + pushRow[f.name] = fieldInputs[f.name]; + } + } + }); + pushRow[labelerField] = fieldInputs[labelerField] || "human_reviewer"; + pushRow["event_timestamp"] = new Date().toISOString(); + + const columnar: Record = {}; + for (const key of Object.keys(pushRow)) { + columnar[key] = [pushRow[key]]; + } + + const response = await fetch(`${baseUrl}/push`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + push_source_name: pushSourceName, + df: columnar, + to: "online_and_offline", + }), + }); + + if (response.ok) { + setLabelCount((c) => c + 1); + setPushSuccess( + `Label pushed for ${entities.map((e) => `${e}=${entityValues[e]}`).join(", ")}`, + ); + resetForm(); + } else { + const errData = await response.json().catch(() => null); + setError(errData?.detail || `Push failed (${response.status})`); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setIsSaving(false); + } + }; + + const renderFieldInput = (field: { name: string; valueType?: string }) => { + const widget = labelWidgets[field.name]; + const values = labelValues[field.name]; + const role = fieldRoles[field.name]; + const currentValue = fieldInputs[field.name] || ""; + + if (widget === "binary" && values && values.length === 2) { + const options = values.map((v) => ({ + id: v, + label: v === "1" ? "Yes" : v === "0" ? "No" : v, + })); + return ( + + setFieldInputs((prev) => ({ ...prev, [field.name]: id })) + } + buttonSize="m" + /> + ); + } + + if ( + widget === "enum" || + (values && values.length > 0 && values.length <= 30) + ) { + return ( + ({ value: v, text: v })), + ]} + value={currentValue} + onChange={(e) => + setFieldInputs((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + /> + ); + } + + if (widget === "number") { + return ( + + setFieldInputs((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + placeholder={`Enter ${field.name}`} + /> + ); + } + + if (widget === "text" || role === "metadata") { + return ( + + setFieldInputs((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + placeholder={`Enter ${field.name}`} + rows={2} + compressed + /> + ); + } + + return ( + + setFieldInputs((prev) => ({ + ...prev, + [field.name]: e.target.value, + })) + } + placeholder={`Enter ${field.name}`} + /> + ); + }; + + if (!labelViewName) { + return ( + No label view selected} + /> + ); + } + + return ( + + +

+ Fill in the entity identifier and label values below. Each submission + pushes one label record to {labelViewName}. +

+
+ + {error && ( + <> + + +

{error}

+
+ + )} + + {pushSuccess && ( + <> + + + + )} + + + + + + + + +

+ Entity +

+
+ + + {entities.map((entity) => ( + + + setEntityValues((prev) => ({ + ...prev, + [entity]: e.target.value, + })) + } + placeholder={`Enter ${entity} value`} + /> + + ))} + + + +

+ Labels +

+
+ + + {editableFields + .filter((f) => fieldRoles[f.name] === "label") + .map((field) => ( + + {renderFieldInput(field)} + + ))} + + {editableFields.filter( + (f) => + fieldRoles[f.name] !== "label" && + fieldRoles[f.name] !== undefined, + ).length > 0 && ( + <> + + +

+ Additional Fields +

+
+ + {editableFields + .filter( + (f) => + fieldRoles[f.name] !== "label" && + fieldRoles[f.name] !== undefined, + ) + .map((field) => ( + + {renderFieldInput(field)} + + ))} + + )} + + {editableFields.filter((f) => !fieldRoles[f.name]).length > 0 && ( + <> + + {editableFields + .filter((f) => !fieldRoles[f.name]) + .map((field) => ( + + {renderFieldInput(field)} + + ))} + + )} + + + + + + setFieldInputs((prev) => ({ + ...prev, + [labelerField]: e.target.value, + })) + } + placeholder="your_name or reviewer_id" + /> + + + + + + + + Submit Label + + + + + Clear + + + +
+
+
+ + + + +

Session

+
+ + +

+ Labels submitted:{" "} + {labelCount} +

+

+ Conflict policy:{" "} + + {spec.conflictPolicy || "LAST_WRITE_WINS"} + +

+

+ Labeler field: {labelerField} +

+
+ + +

Schema

+
+ + + {entities.map((e) => ( +

+ entity {e} +

+ ))} + {editableFields.map((f) => ( +

+ + {fieldRoles[f.name] || "field"} + {" "} + {f.name} +

+ ))} +
+
+
+
+
+ ); +}; + +export default EntityFormMethod; diff --git a/ui/src/pages/label-views/Index.tsx b/ui/src/pages/label-views/Index.tsx new file mode 100644 index 00000000000..7e519b48a40 --- /dev/null +++ b/ui/src/pages/label-views/Index.tsx @@ -0,0 +1,199 @@ +import React from "react"; +import { useParams } from "react-router-dom"; + +import { + EuiPageTemplate, + EuiLoadingSpinner, + EuiBasicTable, + EuiBasicTableColumn, + EuiBadge, + EuiEmptyPrompt, + EuiTitle, + EuiLink, +} from "@elastic/eui"; + +import { LabelViewIcon } from "../../graphics/LabelViewIcon"; +import { useDocumentTitle } from "../../hooks/useDocumentTitle"; +import useResourceQuery, { + labelViewListPath, + restLabelViewsFromResponse, +} from "../../queries/useResourceQuery"; + +const useLoadLabelViews = () => { + const { projectName } = useParams(); + return useResourceQuery({ + resourceType: "label-views-list", + project: projectName, + restPath: labelViewListPath(projectName), + restSelect: restLabelViewsFromResponse, + }); +}; + +interface LabelViewRow { + name: string; + entities: string[]; + conflictPolicy: string; + annotationProfile: string; + labelerField: string; + online: boolean; + description: string; +} + +const LabelViewsListingTable = ({ labelViews }: { labelViews: any[] }) => { + const { projectName } = useParams(); + + const rows: LabelViewRow[] = labelViews.map((lv: any) => { + const spec = lv.spec || {}; + const tags = spec.tags || {}; + return { + name: spec.name || "Unknown", + entities: spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || [], + conflictPolicy: spec.conflictPolicy || "LAST_WRITE_WINS", + annotationProfile: tags["feast.io/labeling-method"] || "table", + labelerField: spec.labelerField || "labeler", + online: spec.online !== false, + description: spec.description || "", + }; + }); + + const columns: EuiBasicTableColumn[] = [ + { + field: "name", + name: "Name", + sortable: true, + render: (name: string) => ( + {name} + ), + }, + { + field: "entities", + name: "Entities", + render: (entities: string[]) => + entities.length > 0 + ? entities.map((e, i) => ( + + {i > 0 && ", "} + {e} + + )) + : "-", + }, + { + field: "conflictPolicy", + name: "Conflict Policy", + render: (policy: string) => { + const color = + policy === "LAST_WRITE_WINS" + ? "default" + : policy === "MAJORITY_VOTE" + ? "primary" + : "accent"; + return {policy}; + }, + }, + { + field: "annotationProfile", + name: "Labeling Method", + render: (profile: string) => { + const color = + profile === "document-span" + ? "warning" + : profile === "entity-form" + ? "success" + : profile === "active-learning" + ? "accent" + : "hollow"; + return {profile}; + }, + }, + { + field: "labelerField", + name: "Labeler Field", + }, + { + field: "online", + name: "Online", + render: (online: boolean) => ( + + {online ? "Yes" : "No"} + + ), + }, + { + field: "description", + name: "Description", + render: (desc: string) => ( + + {desc || "-"} + + ), + }, + ]; + + return ( + + items={rows} + columns={columns} + tableLayout="auto" + /> + ); +}; + +const LabelViewIndexEmptyState = () => ( + +

No Label Views

+ + } + body={ +

+ Label views manage mutable labels and annotations for agent + interactions, safety monitoring, and RLHF pipelines. Define a LabelView + in your feature repository to get started. +

+ } + /> +); + +const Index = () => { + const { isLoading, isSuccess, isError, data } = useLoadLabelViews(); + + useDocumentTitle(`Label Views | Feast`); + + return ( + + + + {isLoading && ( +

+ Loading +

+ )} + {isError &&

We encountered an error while loading.

} + {isSuccess && (!data || data.length === 0) && ( + + )} + {isSuccess && data && data.length > 0 && ( + + )} +
+
+ ); +}; + +export default Index; diff --git a/ui/src/pages/label-views/IntegrationsTab.tsx b/ui/src/pages/label-views/IntegrationsTab.tsx new file mode 100644 index 00000000000..feca543bd10 --- /dev/null +++ b/ui/src/pages/label-views/IntegrationsTab.tsx @@ -0,0 +1,288 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiText, + EuiLoadingSpinner, + EuiCallOut, + EuiCodeBlock, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiBadge, + EuiIcon, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; + +const IntegrationsTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading, isSuccess, data } = useLoadLabelView(name); + + const [webhookConfig, setWebhookConfig] = useState(null); + const [configLoading, setConfigLoading] = useState(true); + + useEffect(() => { + if (isSuccess && data) { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + fetch(`${baseUrl}/webhook/config/${name}`) + .then((r) => r.json()) + .then((d) => { + setWebhookConfig(d); + setConfigLoading(false); + }) + .catch(() => setConfigLoading(false)); + } + }, [isSuccess, data, name, registryUrl]); + + if (isLoading || configLoading) { + return ( +

+ Loading integration config... +

+ ); + } + + if (!webhookConfig) { + return ( + + Could not fetch webhook configuration. + + ); + } + + const webhookPayload = JSON.stringify(webhookConfig.payload_example, null, 2); + const baseUrl = window.location.origin; + const webhookFullUrl = `${baseUrl}${webhookConfig.webhook_url}`; + const batchFullUrl = `${baseUrl}${webhookConfig.batch_url}`; + + const argillaPython = `import argilla as rg +import requests +from datetime import datetime, timezone + +# After annotation is complete, export and push to Feast LabelView +dataset = rg.load("your_dataset_name") +submitted = dataset.records(status="submitted").to_list(flatten=True) + +records = [] +for record in submitted: + records.append({ + ${webhookConfig.entity_fields.map((e: string) => `"${e}": record.metadata["${e}"],`).join("\n ")} + ${webhookConfig.label_fields.map((f: string) => `"${f}": record.responses["${f}"],`).join("\n ")} + ${webhookConfig.labeler_field ? `"${webhookConfig.labeler_field}": record.user_id,` : ""} + "event_timestamp": datetime.now(timezone.utc).isoformat(), + }) + +response = requests.post( + "${webhookFullUrl}", + json={ + "push_source_name": "${webhookConfig.push_source_name}", + "records": records, + }, +) +print(f"Pushed {len(records)} labels: {response.json()}")`; + + const labelStudioPython = `import requests +from datetime import datetime, timezone +from label_studio_sdk import Client + +ls = Client(url="http://localhost:8080", api_key="YOUR_KEY") +project = ls.get_project(PROJECT_ID) + +# Export completed annotations +tasks = project.get_labeled_tasks() + +records = [] +for task in tasks: + annotation = task["annotations"][0]["result"][0] + records.append({ + ${webhookConfig.entity_fields.map((e: string) => `"${e}": task["data"]["${e}"],`).join("\n ")} + ${webhookConfig.label_fields.map((f: string) => `"${f}": annotation["value"].get("${f}", ""),`).join("\n ")} + ${webhookConfig.labeler_field ? `"${webhookConfig.labeler_field}": str(task["annotations"][0]["completed_by"]),` : ""} + "event_timestamp": datetime.now(timezone.utc).isoformat(), + }) + +response = requests.post( + "${webhookFullUrl}", + json={ + "push_source_name": "${webhookConfig.push_source_name}", + "records": records, + }, +) +print(f"Pushed {len(records)} labels: {response.json()}")`; + + const curlExample = `curl -X POST "${webhookFullUrl}" \\ + -H "Content-Type: application/json" \\ + -d '${webhookPayload}'`; + + return ( + + + + Connect Argilla, Label Studio, or any annotation tool to push labels + into this LabelView via webhook or batch API. + + + + + + {/* Webhook Configuration */} + + + + + + + +

Webhook Endpoint

+
+
+ + POST + +
+ + + Real-time label ingestion from annotation tools. Automatically adds + timestamps if not provided. + + + + + URL: + + {webhookFullUrl} + + + + + + + Required fields: + + {webhookConfig.entity_fields.map((f: string) => ( + + {f} (entity) + + ))} + {webhookConfig.label_fields.map((f: string) => ( + + {f} (label) + + ))} + {webhookConfig.labeler_field && ( + + + {webhookConfig.labeler_field} (labeler) + + + )} + + + +

Example payload:

+
+ + {webhookPayload} + +
+ + + + {/* Batch Push */} + + + + + + + +

Batch Push Endpoint

+
+
+ + POST + +
+ + + Upload bulk labels from CSV/parquet exports. Same schema as webhook. + + + + {batchFullUrl} + +
+ + + + {/* cURL Example */} + + +

cURL Example

+
+ + + {curlExample} + +
+ + + + {/* Argilla Integration */} + + + + + + + +

Argilla Integration

+
+
+
+ + + Export annotated records from Argilla and push to this LabelView. + + + + {argillaPython} + +
+ + + + {/* Label Studio Integration */} + + + + + + + +

Label Studio Integration

+
+
+
+ + + Export completed annotations from Label Studio and ingest via webhook. + + + + {labelStudioPython} + +
+
+ ); +}; + +export default IntegrationsTab; diff --git a/ui/src/pages/label-views/LabelBrowseTab.tsx b/ui/src/pages/label-views/LabelBrowseTab.tsx new file mode 100644 index 00000000000..7ed1b51a8b1 --- /dev/null +++ b/ui/src/pages/label-views/LabelBrowseTab.tsx @@ -0,0 +1,385 @@ +import React, { useContext, useState, useEffect, useMemo } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiHorizontalRule, + EuiFieldSearch, + EuiButton, + EuiSpacer, + EuiCallOut, + EuiText, + EuiLoadingSpinner, + EuiBasicTable, + EuiBasicTableColumn, + EuiBadge, + EuiFlexGroup, + EuiFlexItem, + EuiTablePagination, + EuiEmptyPrompt, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; + +interface LabelRow { + [key: string]: any; +} + +const PAGE_SIZE_OPTIONS = [10, 25, 50, 100]; + +const LabelBrowseTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading, isSuccess, data } = useLoadLabelView(name); + + const [allLabels, setAllLabels] = useState(null); + const [allEntityNames, setAllEntityNames] = useState([]); + const [totalEntities, setTotalEntities] = useState(0); + const [loadingAll, setLoadingAll] = useState(false); + const [error, setError] = useState(null); + const [searchQuery, setSearchQuery] = useState(""); + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(25); + const initialLoadDone = React.useRef(false); + + useEffect(() => { + if (isSuccess && data && !initialLoadDone.current) { + initialLoadDone.current = true; + loadLabels(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isSuccess, data, name, registryUrl]); + + const loadLabels = async () => { + setLoadingAll(true); + setError(null); + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const response = await fetch(`${baseUrl}/list-labels`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ feature_view: name, limit: 1000 }), + }); + if (response.ok) { + const respData = await response.json(); + setAllLabels(respData.labels || []); + setAllEntityNames(respData.entity_names || []); + setTotalEntities(respData.total_entities || 0); + } else { + const errData = await response.json().catch(() => null); + setError( + errData?.detail || `Failed to load labels (${response.status})`, + ); + } + } catch (err: any) { + setError(err.message || "Network error."); + } finally { + setLoadingAll(false); + } + }; + + const spec = data?.spec || data?.object?.spec || {}; + const entities: string[] = spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || []; + const features: any[] = useMemo(() => spec.features || [], [spec.features]); + const conflictPolicy = + spec.conflictPolicy || spec.conflict_policy || "LAST_WRITE_WINS"; + const policyLabel = + typeof conflictPolicy === "number" + ? ["LAST_WRITE_WINS", "LABELER_PRIORITY", "MAJORITY_VOTE"][ + conflictPolicy + ] || "LAST_WRITE_WINS" + : String(conflictPolicy).replace("CONFLICT_POLICY_", ""); + const labelerField: string = + spec.labelerField || spec.labeler_field || "labeler"; + + const entityCols = allEntityNames.length > 0 ? allEntityNames : entities; + + const filteredLabels = useMemo(() => { + if (!allLabels) return []; + if (!searchQuery.trim()) return allLabels; + + const query = searchQuery.toLowerCase(); + return allLabels.filter((row) => + Object.values(row).some( + (val) => val != null && String(val).toLowerCase().includes(query), + ), + ); + }, [allLabels, searchQuery]); + + const paginatedLabels = useMemo(() => { + const start = pageIndex * pageSize; + return filteredLabels.slice(start, start + pageSize); + }, [filteredLabels, pageIndex, pageSize]); + + const columns: EuiBasicTableColumn[] = useMemo(() => { + const cols: EuiBasicTableColumn[] = []; + + for (const entity of entityCols) { + cols.push({ + field: entity, + name: entity, + sortable: true, + render: (value: any) => ( + + {value != null ? String(value) : "\u2014"} + + ), + }); + } + + for (const feature of features) { + cols.push({ + field: feature.name, + name: feature.name, + sortable: true, + render: (value: any) => { + if (value === null || value === undefined) { + return ( + + + + ); + } + return {String(value)}; + }, + }); + } + + cols.push({ + field: "_event_ts", + name: "Last Updated", + sortable: true, + render: (value: any) => + value ? new Date(value * 1000).toLocaleString() : "\u2014", + }); + + return cols; + }, [entityCols, features]); + + if (isLoading) { + return ( +

+ Loading schema... +

+ ); + } + + if (!isSuccess || !data) { + return

Unable to load label view schema.

; + } + + return ( + + + + + +

Schema

+
+ + ({ + name: e, + type: "ENTITY", + role: "entity", + })), + ...features.map((f: any) => ({ + name: f.name, + type: f.valueType || "STRING", + role: f.name === labelerField ? "labeler" : "label", + })), + ]} + columns={[ + { field: "name", name: "Field", width: "40%" }, + { field: "type", name: "Type", width: "30%" }, + { + field: "role", + name: "Role", + width: "30%", + render: (role: string) => ( + + {role} + + ), + }, + ]} + tableLayout="fixed" + compressed + /> +
+ + +

Properties

+
+ + + + + Conflict Policy + +
+ + {policyLabel} + +
+
+ + + Labeler Field + + + {labelerField} + + +
+
+
+
+ + + + + + + +

+ Label Records{" "} + {allLabels && ( + {totalEntities} total + )} + {searchQuery && + filteredLabels.length !== (allLabels || []).length && ( + <> + {" "} + + {filteredLabels.length} matching + + + )} +

+
+
+ + + Refresh + + +
+ + + + +

+ All label records in the online store, resolved by conflict policy. + Use the search bar to filter by any field value. +

+
+ + + + { + setSearchQuery(e.target.value); + setPageIndex(0); + }} + isClearable + fullWidth + /> + + + + {allLabels === null && loadingAll && ( + + + + + Loading label records... + + )} + + {allLabels !== null && allLabels.length === 0 && ( + No labels submitted yet} + body="No labels have been pushed to the online store for this label view." + /> + )} + + {allLabels !== null && + allLabels.length > 0 && + filteredLabels.length === 0 && ( + No matching records} + body={ +

+ No records match "{searchQuery}". + Try a different search term. +

+ } + /> + )} + + {filteredLabels.length > 0 && ( + <> + + items={paginatedLabels} + columns={columns} + tableLayout="auto" + /> + + setPageIndex(page)} + itemsPerPage={pageSize} + onChangeItemsPerPage={(size) => { + setPageSize(size); + setPageIndex(0); + }} + itemsPerPageOptions={PAGE_SIZE_OPTIONS} + /> + + )} +
+ + {error && ( + <> + + + {error} + + + )} +
+ ); +}; + +export default LabelBrowseTab; diff --git a/ui/src/pages/label-views/LabelViewInstance.tsx b/ui/src/pages/label-views/LabelViewInstance.tsx new file mode 100644 index 00000000000..8ef720ed278 --- /dev/null +++ b/ui/src/pages/label-views/LabelViewInstance.tsx @@ -0,0 +1,152 @@ +import React, { useState } from "react"; +import { Route, Routes, useNavigate, useParams } from "react-router-dom"; +import { + EuiPageTemplate, + EuiPopover, + EuiContextMenu, + EuiButton, +} from "@elastic/eui"; + +import { LabelViewIcon } from "../../graphics/LabelViewIcon"; +import { useMatchExact, useMatchSubpath } from "../../hooks/useMatchSubpath"; +import LabelBrowseTab from "./LabelBrowseTab"; +import QualityDashboardTab from "./QualityDashboardTab"; +import AnnotateTab from "./AnnotateTab"; +import TrainingExportTab from "./TrainingExportTab"; +import IntegrationsTab from "./IntegrationsTab"; +import BatchUploadTab from "./BatchUploadTab"; +import LabelViewLineageTab from "./LabelViewLineageTab"; +import FeatureViewVersionsTab from "../feature-views/FeatureViewVersionsTab"; +import { useDocumentTitle } from "../../hooks/useDocumentTitle"; + +const LabelViewInstance = () => { + const navigate = useNavigate(); + const { labelViewName } = useParams(); + const [isMoreOpen, setIsMoreOpen] = useState(false); + + useDocumentTitle(`${labelViewName} | Label View | Feast`); + + const moreMenuItems = [ + { + id: "more-panel", + items: [ + { + name: "Export", + icon: "exportAction", + onClick: () => { + setIsMoreOpen(false); + navigate("export"); + }, + }, + { + name: "Upload", + icon: "importAction", + onClick: () => { + setIsMoreOpen(false); + navigate("upload"); + }, + }, + { + name: "Versions", + icon: "copyClipboard", + onClick: () => { + setIsMoreOpen(false); + navigate("versions"); + }, + }, + { + name: "Lineage", + icon: "graphApp", + onClick: () => { + setIsMoreOpen(false); + navigate("lineage"); + }, + }, + { + name: "Integrations", + icon: "gear", + onClick: () => { + setIsMoreOpen(false); + navigate("integrations"); + }, + }, + ], + }, + ]; + + return ( + + setIsMoreOpen(!isMoreOpen)} + > + More + + } + isOpen={isMoreOpen} + closePopover={() => setIsMoreOpen(false)} + panelPaddingSize="none" + anchorPosition="downRight" + > + + , + ]} + tabs={[ + { + label: "Labels", + isSelected: useMatchExact(""), + onClick: () => { + navigate(""); + }, + }, + { + label: "Quality", + isSelected: useMatchSubpath("quality"), + onClick: () => { + navigate("quality"); + }, + }, + { + label: "Label Data", + isSelected: useMatchSubpath("annotate"), + onClick: () => { + navigate("annotate"); + }, + }, + ]} + /> + + + } /> + } /> + } /> + } /> + } /> + + } + /> + } /> + } /> + + + + ); +}; + +export default LabelViewInstance; diff --git a/ui/src/pages/label-views/LabelViewLineageTab.tsx b/ui/src/pages/label-views/LabelViewLineageTab.tsx new file mode 100644 index 00000000000..0da3d92dab8 --- /dev/null +++ b/ui/src/pages/label-views/LabelViewLineageTab.tsx @@ -0,0 +1,93 @@ +import React, { useContext, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiEmptyPrompt, + EuiLoadingSpinner, + EuiSpacer, + EuiSelect, + EuiFormRow, + EuiFlexGroup, + EuiFlexItem, +} from "@elastic/eui"; +import useLoadRegistry from "../../queries/useLoadRegistry"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import RegistryVisualization from "../../components/RegistryVisualization"; +import { FEAST_FCO_TYPES } from "../../parsers/types"; +import { filterPermissionsByAction } from "../../utils/permissionUtils"; + +const LabelViewLineageTab = () => { + const registryUrl = useContext(RegistryPathContext); + const { labelViewName, projectName } = useParams(); + const { + isLoading, + isSuccess, + isError, + data: registryData, + } = useLoadRegistry(registryUrl, projectName); + const [selectedPermissionAction, setSelectedPermissionAction] = useState(""); + + const filterNode = { + type: FEAST_FCO_TYPES.labelView, + name: labelViewName || "", + }; + + return ( + <> + {isLoading && ( +
+ +
+ )} + {isError && ( + Error loading lineage} + body={

Could not load lineage data for this label view.

} + /> + )} + {isSuccess && registryData && ( + <> + + + + setSelectedPermissionAction(e.target.value)} + aria-label="Filter by permissions" + /> + + + + + + + )} + + ); +}; + +export default LabelViewLineageTab; diff --git a/ui/src/pages/label-views/LabelViewOverviewTab.tsx b/ui/src/pages/label-views/LabelViewOverviewTab.tsx new file mode 100644 index 00000000000..bbe65071c39 --- /dev/null +++ b/ui/src/pages/label-views/LabelViewOverviewTab.tsx @@ -0,0 +1,340 @@ +import React from "react"; +import { useParams } from "react-router-dom"; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiTitle, + EuiHorizontalRule, + EuiDescriptionList, + EuiDescriptionListTitle, + EuiDescriptionListDescription, + EuiText, + EuiSpacer, + EuiBadge, + EuiLoadingSpinner, + EuiBasicTable, + EuiBasicTableColumn, + EuiCallOut, + EuiLink, + EuiCode, +} from "@elastic/eui"; + +import useLoadLabelView from "./useLoadLabelView"; +import useAnnotationConfig from "./useAnnotationConfig"; + +const CONFLICT_POLICY_MAP: Record = { + "0": "LAST_WRITE_WINS", + "1": "LABELER_PRIORITY", + "2": "MAJORITY_VOTE", + LAST_WRITE_WINS: "LAST_WRITE_WINS", + LABELER_PRIORITY: "LABELER_PRIORITY", + MAJORITY_VOTE: "MAJORITY_VOTE", +}; + +interface SchemaField { + name: string; + valueType: string; +} + +const PROFILE_COLORS: Record = { + "document-span": "primary", + table: "default", + "entity-form": "accent", + "active-learning": "success", +}; + +interface FieldRoleRow { + field: string; + role: string; + values?: string; + widget?: string; +} + +const LabelViewOverviewTab = () => { + const { labelViewName, projectName } = useParams(); + const name = labelViewName || ""; + const { isLoading, isSuccess, isError, data } = useLoadLabelView(name); + const { data: annotationConfig } = useAnnotationConfig(name); + + if (isLoading) { + return ( +

+ Loading +

+ ); + } + if (isError) { + return

Error loading label view: {name}

; + } + if (!isSuccess || !data) { + return

No label view found with name: {name}

; + } + + const spec = data.spec || {}; + const meta = data.meta || {}; + const conflictPolicy = + CONFLICT_POLICY_MAP[spec.conflictPolicy] || + spec.conflictPolicy || + "LAST_WRITE_WINS"; + const labelerField = spec.labelerField || "labeler"; + const entities: string[] = spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || []; + const features: any[] = spec.features || []; + + const schemaColumns: EuiBasicTableColumn[] = [ + { field: "name", name: "Field Name", sortable: true }, + { field: "valueType", name: "Value Type" }, + ]; + + const schemaRows: SchemaField[] = features.map((f: any) => ({ + name: f.name || "Unknown", + valueType: f.valueType != null ? String(f.valueType) : "Unknown", + })); + + return ( + + +

+ conflict_policy is enforced for offline store reads + (training data, Browse, Quality). The offline store always retains + full write history. The online store uses last-write-wins for serving. +

+
+ + + + + +

Properties

+
+ + + Conflict Policy + + + {conflictPolicy} + + + + Labeler Field + + {labelerField} + + + Entities + + {entities.length > 0 + ? entities.map((ent: string, i: number) => ( + + {i > 0 && ", "} + + {ent} + + + )) + : "-"} + + + {spec.description && ( + <> + Description + + {spec.description} + + + )} + +
+ + + +

Metadata

+
+ + + Created + + {meta.createdTimestamp + ? new Date( + typeof meta.createdTimestamp === "string" + ? meta.createdTimestamp + : Number(meta.createdTimestamp.seconds) * 1000, + ).toLocaleDateString("en-CA") + : "N/A"} + + + Last Updated + + {meta.lastUpdatedTimestamp + ? new Date( + typeof meta.lastUpdatedTimestamp === "string" + ? meta.lastUpdatedTimestamp + : Number(meta.lastUpdatedTimestamp.seconds) * 1000, + ).toLocaleDateString("en-CA") + : "N/A"} + + +
+ {annotationConfig && ( + <> + + + +

Labeling Method

+
+ + + Profile + + + {annotationConfig.profile} + + + + Push Source + + + {annotationConfig.push_source_name || "N/A"} + + + + + {Object.keys(annotationConfig.field_roles).length > 0 && ( + <> + + + Field Roles + + + + items={Object.entries(annotationConfig.field_roles).map( + ([field, role]) => ({ + field, + role, + values: + annotationConfig.label_values[field]?.join(", "), + widget: annotationConfig.label_widgets[field], + }), + )} + columns={[ + { field: "field", name: "Field", width: "30%" }, + { + field: "role", + name: "Role", + width: "25%", + render: (role: string) => ( + + {role} + + ), + }, + { + field: "values", + name: "Values", + render: (v: string) => v || "\u2014", + }, + { + field: "widget", + name: "Widget", + render: (w: string) => w || "\u2014", + }, + ]} + tableLayout="auto" + compressed + /> + + )} +
+ + )} +
+ + + +

Labels

+
+ + {schemaRows.length > 0 ? ( + + items={schemaRows} + columns={[ + { + field: "name", + name: "Label Name", + sortable: true, + render: (labelName: string) => ( + + {labelName} + + ), + }, + { field: "valueType", name: "Value Type" }, + ]} + tableLayout="auto" + /> + ) : ( + No labels defined. + )} +
+ + {spec.source && ( + + +

Data Source

+
+ + + Source Type + + {spec.source.type || "PushSource"} + + {spec.source.name && ( + <> + + Source Name + + + + {spec.source.name} + + + + )} + +
+ )} +
+
+
+ ); +}; + +export default LabelViewOverviewTab; diff --git a/ui/src/pages/label-views/QualityDashboardTab.tsx b/ui/src/pages/label-views/QualityDashboardTab.tsx new file mode 100644 index 00000000000..7d0a8a0f3f4 --- /dev/null +++ b/ui/src/pages/label-views/QualityDashboardTab.tsx @@ -0,0 +1,406 @@ +import React, { useContext, useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiHorizontalRule, + EuiText, + EuiLoadingSpinner, + EuiCallOut, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiStat, + EuiBadge, + EuiBasicTable, + EuiBasicTableColumn, + EuiProgress, + EuiButton, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; + +interface QualityData { + total_entities: number; + feature_names: string[]; + distributions: Record>; + coverage_pct: Record; + null_counts: Record; + labeler_stats: Record; + staleness_seconds: number | null; + oldest_label_ts: string | null; + newest_label_ts: string | null; + labeler_field: string | null; +} + +const formatStaleness = (seconds: number | null): string => { + if (seconds === null) return "N/A"; + if (seconds < 60) return `${Math.round(seconds)}s ago`; + if (seconds < 3600) return `${Math.round(seconds / 60)}m ago`; + if (seconds < 86400) return `${Math.round(seconds / 3600)}h ago`; + return `${Math.round(seconds / 86400)}d ago`; +}; + +const getStalenessColor = (seconds: number | null): string => { + if (seconds === null) return "subdued"; + if (seconds < 3600) return "success"; + if (seconds < 86400) return "warning"; + return "danger"; +}; + +const DistributionBar = ({ + distribution, + label, +}: { + distribution: Record; + label: string; +}) => { + const entries = Object.entries(distribution).sort((a, b) => b[1] - a[1]); + const total = entries.reduce((acc, [, count]) => acc + count, 0); + const colors = [ + "#0569EA", + "#00BFB3", + "#F5A623", + "#BD271E", + "#6092C0", + "#D36086", + "#9170B8", + "#CA8EAE", + ]; + + if (entries.length === 0) { + return ( + + No data + + ); + } + + return ( +
+ + {label} ({total} values, {entries.length} unique) + + +
+ {entries.slice(0, 8).map(([val, count], idx) => ( +
+ ))} +
+ + + {entries.slice(0, 6).map(([val, count], idx) => ( + + + {val.length > 12 ? val.slice(0, 12) + "\u2026" : val}: {count} + + + ))} + {entries.length > 6 && ( + + +{entries.length - 6} more + + )} + +
+ ); +}; + +const QualityDashboardTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading: lvLoading, isSuccess } = useLoadLabelView(name); + + const [quality, setQuality] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const fetchQuality = async () => { + setLoading(true); + setError(null); + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const response = await fetch(`${baseUrl}/label-quality`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ feature_view: name, limit: 500 }), + }); + const result = await response.json(); + if (!response.ok) { + const detail = result.detail; + setError( + typeof detail === "string" + ? detail + : Array.isArray(detail) + ? detail.map((d: any) => d.msg || JSON.stringify(d)).join("; ") + : "Failed to load quality metrics", + ); + } else { + setQuality(result); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (isSuccess) { + fetchQuality(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isSuccess, name]); + + if (lvLoading) { + return ( +

+ Loading... +

+ ); + } + + if (loading) { + return ( + + + + + + Computing label quality metrics... + + + ); + } + + if (error) { + return ( + + {error} + + ); + } + + if (!quality) return null; + + const labelerColumns: EuiBasicTableColumn<{ name: string; count: number }>[] = + [ + { field: "name", name: "Labeler", sortable: true }, + { + field: "count", + name: "Labels Submitted", + sortable: true, + render: (count: number) => {count}, + }, + { + field: "count", + name: "Share", + render: (count: number) => { + const total = Object.values(quality.labeler_stats).reduce( + (a, b) => a + b, + 0, + ); + return `${((count / total) * 100).toFixed(1)}%`; + }, + }, + ]; + + const labelerData = Object.entries(quality.labeler_stats) + .map(([name, count]) => ({ name, count })) + .sort((a, b) => b.count - a.count); + + return ( + + {/* Time Range + Refresh at top */} + + + + + + + Oldest label:{" "} + {quality.oldest_label_ts + ? new Date(quality.oldest_label_ts).toLocaleString() + : "N/A"} + + + + + Newest label:{" "} + {quality.newest_label_ts + ? new Date(quality.newest_label_ts).toLocaleString() + : "N/A"} + + + + + + + Refresh Metrics + + + + + + + + {/* Summary Stats */} + + + + + + + + + + + + + + + + + + + + + + + + + + {/* Coverage */} + + +

Field Coverage

+
+ + Percentage of records with non-null values for each label field + + + {quality.feature_names.map((fn) => ( + + + + + {fn} + + + + 80 + ? "success" + : (quality.coverage_pct[fn] || 0) > 50 + ? "warning" + : "danger" + } + label={`${(quality.coverage_pct[fn] || 0).toFixed(1)}%`} + /> + + + + {quality.null_counts[fn] || 0} nulls + + + + + + ))} +
+ + + + {/* Distributions */} + + +

Value Distributions

+
+ + Distribution of label values across all records + + + {quality.feature_names.map((fn) => ( + + + + + + ))} +
+ + + + {/* Per-Labeler Stats */} + {labelerData.length > 0 && ( + + + + +

Per-Labeler Statistics

+
+
+ {quality.labeler_field && ( + + + Tracked via: {quality.labeler_field} + + + )} +
+ + +
+ )} +
+ ); +}; + +export default QualityDashboardTab; diff --git a/ui/src/pages/label-views/RagLabelingMethod.tsx b/ui/src/pages/label-views/RagLabelingMethod.tsx new file mode 100644 index 00000000000..84ad696a149 --- /dev/null +++ b/ui/src/pages/label-views/RagLabelingMethod.tsx @@ -0,0 +1,899 @@ +import React, { useState, useContext, useMemo } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiCallOut, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFieldText, + EuiButton, + EuiPanel, + EuiTitle, + EuiText, + EuiLoadingSpinner, + EuiButtonGroup, + EuiCode, + EuiTextArea, + EuiModal, + EuiModalHeader, + EuiModalHeaderTitle, + EuiModalBody, + EuiModalFooter, + EuiOverlayMask, + EuiForm, + EuiIcon, + EuiBasicTable, + EuiBasicTableColumn, + EuiBadge, + EuiDescriptionList, + EuiDescriptionListTitle, + EuiDescriptionListDescription, +} from "@elastic/eui"; +import { useTheme } from "../../contexts/ThemeContext"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import type { AnnotationConfig } from "./useAnnotationConfig"; + +interface TextSelection { + text: string; + start: number; + end: number; +} + +interface DocumentLabel { + text: string; + start: number; + end: number; + label: string; + timestamp: number; +} + +interface RagLabelingMethodProps { + annotationConfig: AnnotationConfig; +} + +const RagLabelingMethod = ({ annotationConfig }: RagLabelingMethodProps) => { + const { labelViewName } = useParams(); + const { colorMode } = useTheme(); + const registryUrl = useContext(RegistryPathContext); + + const fieldRoles = annotationConfig.field_roles; + const labelValues = annotationConfig.label_values; + const labelWidgets = annotationConfig.label_widgets; + + const contentRefField = useMemo( + () => + Object.entries(fieldRoles).find( + ([, role]) => role === "content_ref", + )?.[0] || null, + [fieldRoles], + ); + const contentField = useMemo( + () => + Object.entries(fieldRoles).find(([, role]) => role === "content")?.[0] || + null, + [fieldRoles], + ); + const spanStartField = useMemo( + () => + Object.entries(fieldRoles).find( + ([, role]) => role === "span_start", + )?.[0] || null, + [fieldRoles], + ); + const spanEndField = useMemo( + () => + Object.entries(fieldRoles).find(([, role]) => role === "span_end")?.[0] || + null, + [fieldRoles], + ); + + const labelFieldEntries = useMemo( + () => Object.entries(fieldRoles).filter(([, role]) => role === "label"), + [fieldRoles], + ); + const primaryLabelField = labelFieldEntries[0]?.[0] || null; + const secondaryLabelFields = labelFieldEntries.slice(1).map(([name]) => name); + + const primaryLabelOptions = useMemo(() => { + if (!primaryLabelField) + return [ + { id: "relevant", label: "Relevant" }, + { id: "irrelevant", label: "Irrelevant" }, + ]; + const values = labelValues[primaryLabelField]; + if (values && values.length > 0) { + return values.map((v) => ({ + id: v, + label: v.charAt(0).toUpperCase() + v.slice(1), + })); + } + return [ + { id: "relevant", label: "Relevant" }, + { id: "irrelevant", label: "Irrelevant" }, + ]; + }, [primaryLabelField, labelValues]); + + const [filePath, setFilePath] = useState(""); + const [selectedText, setSelectedText] = useState(null); + const [labelingMode, setLabelingMode] = useState( + primaryLabelOptions[0]?.id || "relevant", + ); + const [labels, setLabels] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [documentContent, setDocumentContent] = useState(null); + const [error, setError] = useState(null); + const [groundTruthLabel, setGroundTruthLabel] = useState(""); + const [isSaving, setIsSaving] = useState(false); + const [pushSuccess, setPushSuccess] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); + const [extraFieldValues, setExtraFieldValues] = useState< + Record + >({}); + + const loadDocument = async () => { + if (!filePath) return; + setIsLoading(true); + setError(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const response = await fetch( + `${baseUrl}/document-content?path=${encodeURIComponent(filePath)}`, + ); + if (response.ok) { + const result = await response.json(); + setDocumentContent(result.content); + } else { + setDocumentContent( + `This is a sample document for testing RAG labeling in Feast UI. + +The document contains multiple paragraphs that can be used to test text highlighting and labeling. + +This paragraph discusses machine learning and artificial intelligence concepts. It covers topics like neural networks, deep learning, and natural language processing. Users should be able to select and label relevant portions of this text for RAG retrieval systems. + +Another section focuses on data engineering and ETL pipelines. This content explains how to process large datasets and build scalable data infrastructure. + +The final paragraph contains information about feature stores and real-time machine learning systems.`, + ); + } + } catch { + setDocumentContent( + `This is a sample document for testing RAG labeling in Feast UI. + +The document contains multiple paragraphs that can be used to test text highlighting and labeling. + +This paragraph discusses machine learning and artificial intelligence concepts. It covers topics like neural networks, deep learning, and natural language processing. + +Another section focuses on data engineering and ETL pipelines. This content explains how to process large datasets and build scalable data infrastructure. + +The final paragraph contains information about feature stores and real-time machine learning systems.`, + ); + } finally { + setIsLoading(false); + } + }; + + const handleTextSelection = () => { + const selection = window.getSelection(); + if (selection && selection.toString().trim() && documentContent) { + const selectedTextContent = selection.toString().trim(); + const range = selection.getRangeAt(0); + const rangeText = range.toString(); + if (rangeText) { + const startIndex = documentContent.indexOf(rangeText); + if (startIndex !== -1) { + setSelectedText({ + text: selectedTextContent, + start: startIndex, + end: startIndex + rangeText.length, + }); + } + } + } + }; + + const handleLabelSelection = () => { + if (selectedText) { + const newLabel: DocumentLabel = { + text: selectedText.text, + start: selectedText.start, + end: selectedText.end, + label: labelingMode, + timestamp: Date.now(), + }; + setLabels([...labels, newLabel]); + setSelectedText(null); + const selection = window.getSelection(); + if (selection) selection.removeAllRanges(); + } + }; + + const handleRemoveLabel = (index: number) => { + setLabels(labels.filter((_: DocumentLabel, i: number) => i !== index)); + }; + + const generateChunkId = (docName: string, start: number, end: number) => { + const raw = `${docName}:${start}:${end}`; + let hash = 0; + for (let i = 0; i < raw.length; i++) { + const char = raw.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash |= 0; + } + return `chunk_${Math.abs(hash).toString(36)}`; + }; + + const openSubmitModal = () => { + const defaults: Record = {}; + if (annotationConfig.labeler_field) { + defaults[annotationConfig.labeler_field] = "rag_labeling_ui"; + } + setExtraFieldValues(defaults); + setIsModalOpen(true); + }; + + const buildPushRows = () => { + const docName = filePath || "document"; + const entityField = annotationConfig.entities[0] || "entity_id"; + const labelerField = annotationConfig.labeler_field; + + return labels.map((label) => { + const row: Record = {}; + + row[entityField] = generateChunkId(docName, label.start, label.end); + + if (annotationConfig.entities.length > 1) { + for (let i = 1; i < annotationConfig.entities.length; i++) { + const ent = annotationConfig.entities[i]; + if (extraFieldValues[ent]) { + row[ent] = extraFieldValues[ent]; + } + } + } + + if (contentRefField) row[contentRefField] = filePath; + if (contentField) row[contentField] = label.text; + if (spanStartField) row[spanStartField] = label.start; + if (spanEndField) row[spanEndField] = label.end; + if (primaryLabelField) row[primaryLabelField] = label.label; + + for (const secField of secondaryLabelFields) { + const widget = labelWidgets[secField]; + if (widget === "text" && groundTruthLabel) { + row[secField] = groundTruthLabel; + } else if (extraFieldValues[secField]) { + row[secField] = extraFieldValues[secField]; + } + } + + if (labelerField) { + row[labelerField] = extraFieldValues[labelerField] || "rag_labeling_ui"; + } + + row["event_timestamp"] = new Date().toISOString(); + return row; + }); + }; + + const saveToLabelView = async () => { + if (labels.length === 0) return; + setIsSaving(true); + setError(null); + setPushSuccess(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const pushSourceName = + annotationConfig.push_source_name || `${labelViewName}_push_source`; + const rows = buildPushRows(); + + const columnar: Record = {}; + if (rows.length > 0) { + for (const key of Object.keys(rows[0])) { + columnar[key] = rows.map((r) => r[key]); + } + } + + const response = await fetch(`${baseUrl}/push`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + push_source_name: pushSourceName, + df: columnar, + to: "online_and_offline", + }), + }); + + if (response.ok) { + setPushSuccess( + `Pushed ${labels.length} span labels to ${labelViewName}`, + ); + setLabels([]); + setIsModalOpen(false); + } else { + const errData = await response.json().catch(() => null); + setError( + typeof errData?.detail === "string" + ? errData.detail + : `Push failed (${response.status})`, + ); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setIsSaving(false); + } + }; + + const exportJSON = () => { + const rows = buildPushRows(); + const saveData = { + labelView: labelViewName, + profile: annotationConfig.profile, + filePath, + groundTruthLabel, + rows, + timestamp: new Date().toISOString(), + }; + const blob = new Blob([JSON.stringify(saveData, null, 2)], { + type: "application/json", + }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `${labelViewName}_rag_labels.json`; + a.click(); + URL.revokeObjectURL(url); + }; + + const renderDocumentWithHighlights = ( + content: string, + ): (string | React.ReactElement)[] => { + const allHighlights = [...labels]; + if (selectedText) { + allHighlights.push({ + text: selectedText.text, + start: selectedText.start, + end: selectedText.end, + label: "temp-selection", + timestamp: 0, + }); + } + if (allHighlights.length === 0) return [content]; + + const sortedHighlights = [...allHighlights].sort( + (a, b) => a.start - b.start, + ); + const result: (string | React.ReactElement)[] = []; + let lastIndex = 0; + + const positiveValues = new Set( + primaryLabelOptions.length > 0 + ? [primaryLabelOptions[0].id] + : ["relevant"], + ); + + sortedHighlights.forEach((highlight, index) => { + result.push(content.slice(lastIndex, highlight.start)); + let highlightColor: string; + let borderColor: string; + + if (highlight.label === "temp-selection") { + highlightColor = colorMode === "dark" ? "#1a4d66" : "#add8e6"; + borderColor = colorMode === "dark" ? "#2d6b8a" : "#87ceeb"; + } else if (!positiveValues.has(highlight.label)) { + highlightColor = colorMode === "dark" ? "#4d1a1a" : "#f8d7da"; + borderColor = colorMode === "dark" ? "#6b2d2d" : "#f5c6cb"; + } else { + highlightColor = colorMode === "dark" ? "#1a4d1a" : "#d4edda"; + borderColor = colorMode === "dark" ? "#2d6b2d" : "#c3e6cb"; + } + + result.push( + + {highlight.text} + , + ); + lastIndex = highlight.end; + }); + + result.push(content.slice(lastIndex)); + return result; + }; + + const chunkColumns: EuiBasicTableColumn[] = [ + { + field: "label", + name: primaryLabelField || "Label", + width: "120px", + render: (value: string) => { + const isPositive = + primaryLabelOptions.length > 0 && value === primaryLabelOptions[0].id; + return ( + {value} + ); + }, + }, + { + field: "text", + name: "Span Text", + truncateText: true, + render: (value: string) => + value.substring(0, 100) + (value.length > 100 ? "..." : ""), + }, + { + name: "Offsets", + width: "100px", + render: (item: DocumentLabel) => ( + + {item.start}–{item.end} + + ), + }, + ]; + + const unmappedFeatures = annotationConfig.features.filter((f) => { + if (f === annotationConfig.labeler_field) return false; + if (fieldRoles[f]) return false; + return true; + }); + + return ( + + +

+ Load a document, highlight text spans, and label them. Span positions + and labels are auto-mapped to your schema fields and pushed to{" "} + {labelViewName} via its PushSource. +

+
+ + + + + +

Field Mapping

+
+ + + {contentRefField && ( + <> + Document path + + {contentRefField} + + + )} + {contentField && ( + <> + Span text + + {contentField} + + + )} + {spanStartField && spanEndField && ( + <> + Offsets + + {spanStartField},{" "} + {spanEndField} + + + )} + {primaryLabelField && ( + <> + Primary label + + {primaryLabelField} + {" → "} + {primaryLabelOptions.map((o) => o.id).join(", ")} + + + )} + {secondaryLabelFields.map((f) => ( + + {f} + + {labelWidgets[f] || "text"} + + + ))} + +
+ + + + + + + setFilePath(e.target.value)} + /> + + + + + + Load Document + + + + + + {isLoading && ( + <> + + + + + + + Loading document... + + + + )} + + {error && ( + <> + + +

{error}

+
+ + )} + + {pushSuccess && ( + <> + + + + )} + + {documentContent && ( + <> + + + + + + setLabelingMode(id)} + buttonSize="s" + /> + + + + + + Label Selected Text + + + + + + {selectedText && ( + <> + + + {selectedText.text.substring(0, 120)} + + + )} + + + + + +

Document Content

+
+ + +
+ {renderDocumentWithHighlights(documentContent)} +
+
+
+ + {secondaryLabelFields.length > 0 && ( + <> + + {secondaryLabelFields.map((f) => { + const widget = labelWidgets[f] || "text"; + if (widget === "text") { + return ( + + { + if (f === secondaryLabelFields[0]) { + setGroundTruthLabel(e.target.value); + } else { + setExtraFieldValues((prev) => ({ + ...prev, + [f]: e.target.value, + })); + } + }} + rows={3} + /> + + ); + } + return null; + })} + + )} + + + + + + + Export JSON + + + + + Save to LabelView ({labels.length}) + + + + + {labels.length > 0 && ( + <> + + + +

Labeled Spans ({labels.length})

+
+ + {labels.map((label, index) => ( + + + + {label.label} + + + + + {label.start}–{label.end} + + + + + "{label.text.substring(0, 80)} + {label.text.length > 80 ? "..." : ""}" + + + + handleRemoveLabel(index)} + > + Remove + + + + ))} +
+ + )} + + )} + + {isModalOpen && ( + + setIsModalOpen(false)} maxWidth={600}> + + + Push {labels.length} Span + {labels.length !== 1 ? "s" : ""} to {labelViewName} + + + + +

+ Each span will be pushed as a row. Entity key ( + {annotationConfig.entities[0] || "entity_id"} + ) is auto-generated from document path + span offsets. Fields + are mapped from the annotation profile. +

+
+ + + + +

Spans to push:

+
+ + +
+ + + +

Additional Fields

+
+ + + + + setExtraFieldValues((prev) => ({ + ...prev, + [annotationConfig.labeler_field]: e.target.value, + })) + } + /> + + + {annotationConfig.entities.length > 1 && + annotationConfig.entities.slice(1).map((ent) => ( + + + setExtraFieldValues((prev) => ({ + ...prev, + [ent]: e.target.value, + })) + } + /> + + ))} + + {unmappedFeatures.map((f) => ( + + + setExtraFieldValues((prev) => ({ + ...prev, + [f]: e.target.value, + })) + } + /> + + ))} + + + {error && ( + <> + + + {error} + + + )} +
+ + { + setIsModalOpen(false); + setError(null); + }} + > + Cancel + + + Push Labels + + +
+
+ )} +
+ ); +}; + +export default RagLabelingMethod; diff --git a/ui/src/pages/label-views/TrainingExportTab.tsx b/ui/src/pages/label-views/TrainingExportTab.tsx new file mode 100644 index 00000000000..7a19741c182 --- /dev/null +++ b/ui/src/pages/label-views/TrainingExportTab.tsx @@ -0,0 +1,421 @@ +import React, { useContext, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + EuiPanel, + EuiTitle, + EuiForm, + EuiFormRow, + EuiFieldText, + EuiButton, + EuiSpacer, + EuiCallOut, + EuiText, + EuiLoadingSpinner, + EuiFlexGroup, + EuiFlexItem, + EuiBasicTable, + EuiBasicTableColumn, + EuiBadge, + EuiDatePicker, + EuiSuperSelect, +} from "@elastic/eui"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import useLoadLabelView from "./useLoadLabelView"; +import useLoadRegistry from "../../queries/useLoadRegistry"; +import moment from "moment"; + +const TrainingExportTab = () => { + const { labelViewName } = useParams(); + const registryUrl = useContext(RegistryPathContext); + const name = labelViewName || ""; + const { isLoading, data } = useLoadLabelView(name); + const { data: registryData } = useLoadRegistry(registryUrl); + + const [featureService, setFeatureService] = useState(""); + const [entityColumn, setEntityColumn] = useState(""); + const [entityValues, setEntityValues] = useState(""); + const [startDate, setStartDate] = useState( + moment().subtract(30, "days"), + ); + const [endDate, setEndDate] = useState(moment()); + const [exporting, setExporting] = useState(false); + const [exportResult, setExportResult] = useState(null); + const [error, setError] = useState(null); + + if (isLoading) { + return ( +

+ Loading... +

+ ); + } + + const spec = data?.object?.spec || data?.spec || {}; + const entities: string[] = spec.entityColumns?.length + ? spec.entityColumns.map((ec: { name: string }) => ec.name) + : spec.entities || []; + + const allFeatureServices = registryData?.objects?.featureServices || []; + const relevantFeatureServices = allFeatureServices.filter((fs: any) => { + const projections = [ + ...(fs.spec?.features || []), + ...(fs.spec?.featureViewProjections || []), + ]; + return projections.some( + (proj: any) => + proj.featureViewName === name || + proj.name === name || + proj.featureViewProjection?.featureViewName === name, + ); + }); + const servicesToShow = + relevantFeatureServices.length > 0 + ? relevantFeatureServices + : allFeatureServices; + + const featureServiceOptions = servicesToShow.map((fs: any) => ({ + value: fs.spec?.name || fs.name || "", + inputDisplay: fs.spec?.name || fs.name || "Unknown", + dropdownDisplay: ( + + {fs.spec?.name || fs.name} + {fs.spec?.description && ( + +

{fs.spec.description}

+
+ )} +
+ ), + })); + + const entityColumnOptions = entities.map((e: string) => ({ + value: e, + inputDisplay: e, + })); + + const handleExport = async () => { + setExporting(true); + setError(null); + setExportResult(null); + + try { + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + const entityKey = + entityColumn || (entities.length > 0 ? entities[0] : "entity_id"); + const values = entityValues + .split(",") + .map((v: string) => v.trim()) + .filter((v: string) => v.length > 0); + + if (values.length === 0) { + setError("Please provide at least one entity value"); + setExporting(false); + return; + } + + const serviceName = featureService || `${name}_service`; + const entityDf: Record = { + [entityKey]: values, + }; + + const response = await fetch(`${baseUrl}/training-dataset/export`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + feature_service: serviceName, + entity_df: entityDf, + start_date: startDate?.toISOString() || null, + end_date: endDate?.toISOString() || null, + }), + }); + + const result = await response.json(); + if (!response.ok) { + const detail = result.detail; + setError( + typeof detail === "string" + ? detail + : Array.isArray(detail) + ? detail.map((d: any) => d.msg || JSON.stringify(d)).join("; ") + : "Export failed", + ); + } else { + setExportResult(result); + } + } catch (e: any) { + setError(e.message || "Network error"); + } finally { + setExporting(false); + } + }; + + const downloadCSV = () => { + if (!exportResult?.data) return; + const cols = exportResult.columns; + const csvRows = [cols.join(",")]; + for (const row of exportResult.data) { + csvRows.push( + cols + .map((c: string) => { + const val = row[c]; + if (val === null || val === undefined) return ""; + const str = String(val); + return str.includes(",") ? `"${str}"` : str; + }) + .join(","), + ); + } + const blob = new Blob([csvRows.join("\n")], { type: "text/csv" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `${exportResult.feature_service}_training_data.csv`; + a.click(); + URL.revokeObjectURL(url); + }; + + const downloadJSON = () => { + if (!exportResult?.data) return; + const blob = new Blob([JSON.stringify(exportResult.data, null, 2)], { + type: "application/json", + }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `${exportResult.feature_service}_training_data.json`; + a.click(); + URL.revokeObjectURL(url); + }; + + const columns: EuiBasicTableColumn[] = exportResult + ? exportResult.columns.map((col: string) => ({ + field: col, + name: col, + truncateText: true, + render: (val: any) => + val === null || val === undefined ? ( + null + ) : ( + String(val) + ), + })) + : []; + + return ( + + + + Create a point-in-time correct training dataset by joining features + with labels via get_historical_features. Export as CSV or + JSON for model training. + + + + + + + +

Export Configuration

+
+ + + + + setFeatureService(value)} + placeholder="Select a feature service..." + hasDividers + /> + + + + {entityColumnOptions.length > 0 ? ( + setEntityColumn(value)} + /> + ) : ( + setEntityColumn(e.target.value)} + /> + )} + + + + setEntityValues(e.target.value)} + /> + + + + + + + + + + + + + + + + + + + Generate Training Dataset + + +
+ + {error && ( + + + + {error} + + + )} + + {exportResult && ( + + + + + + +

+ Training Dataset{" "} + + {exportResult.row_count} rows + +

+
+
+ + + + + Download CSV + + + + + Download JSON + + + + +
+ + + Feature service: {exportResult.feature_service} | + Columns: {exportResult.columns.length} | Point-in-time correct + + + + {exportResult.data.length > 50 && ( + + Showing first 50 of {exportResult.data.length} rows. Download + for full dataset. + + )} +
+
+ )} + + + + + +

SDK Equivalent

+
+ + + This UI action is equivalent to the following Python SDK call: + + +
+          {`from feast import FeatureStore
+import pandas as pd
+
+store = FeatureStore(".")
+entity_df = pd.DataFrame({
+    "${entityColumn || entities[0] || "entity_id"}": [${
+      entityValues
+        ? entityValues
+            .split(",")
+            .map((v) => `"${v.trim()}"`)
+            .join(", ")
+        : '"user_1", "user_2"'
+    }],
+    "event_timestamp": pd.Timestamp("${endDate?.toISOString() || "now"}"),
+})
+
+training_df = store.get_historical_features(
+    entity_df=entity_df,
+    features=store.get_feature_service("${featureService || "your_service"}"),
+).to_df()
+
+training_df.to_parquet("training_data.parquet")`}
+        
+
+
+ ); +}; + +export default TrainingExportTab; diff --git a/ui/src/pages/label-views/useAnnotationConfig.ts b/ui/src/pages/label-views/useAnnotationConfig.ts new file mode 100644 index 00000000000..558fd3067e8 --- /dev/null +++ b/ui/src/pages/label-views/useAnnotationConfig.ts @@ -0,0 +1,41 @@ +import { useContext } from "react"; +import { useQuery } from "react-query"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; + +export interface AnnotationConfig { + label_view: string; + profile: string; + field_roles: Record; + label_values: Record; + label_widgets: Record; + entities: string[]; + features: string[]; + labeler_field: string; + push_source_name: string | null; +} + +const useAnnotationConfig = (labelViewName: string) => { + const registryUrl = useContext(RegistryPathContext); + const baseUrl = registryUrl?.replace(/\/$/, "") || "/api/v1"; + + return useQuery( + ["annotation-config", labelViewName, registryUrl], + async () => { + const response = await fetch( + `${baseUrl}/annotation-config/${encodeURIComponent(labelViewName)}`, + ); + if (!response.ok) { + throw new Error( + `Failed to load annotation config (${response.status})`, + ); + } + return response.json(); + }, + { + enabled: !!labelViewName && !!registryUrl, + staleTime: 60_000, + }, + ); +}; + +export default useAnnotationConfig; diff --git a/ui/src/pages/label-views/useLoadLabelView.ts b/ui/src/pages/label-views/useLoadLabelView.ts new file mode 100644 index 00000000000..8ddb44cd22c --- /dev/null +++ b/ui/src/pages/label-views/useLoadLabelView.ts @@ -0,0 +1,18 @@ +import { useParams } from "react-router-dom"; +import useResourceQuery, { + labelViewDetailPath, +} from "../../queries/useResourceQuery"; + +const useLoadLabelView = (labelViewName: string) => { + const { projectName } = useParams(); + + return useResourceQuery({ + resourceType: `label-view:${labelViewName}`, + project: projectName, + restPath: labelViewDetailPath(labelViewName, projectName || ""), + restSelect: (d) => d, + enabled: !!labelViewName, + }); +}; + +export default useLoadLabelView; diff --git a/ui/src/pages/monitoring/FeatureMetricsDetail.tsx b/ui/src/pages/monitoring/FeatureMetricsDetail.tsx new file mode 100644 index 00000000000..51f690ffa55 --- /dev/null +++ b/ui/src/pages/monitoring/FeatureMetricsDetail.tsx @@ -0,0 +1,259 @@ +import React, { useState, useMemo } from "react"; +import { useParams, useNavigate } from "react-router-dom"; +import { + EuiPageTemplate, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiSkeletonText, + EuiEmptyPrompt, + EuiButton, + EuiBreadcrumbs, + EuiSuperSelect, + EuiFormRow, +} from "@elastic/eui"; +import { FeatureIcon } from "../../graphics/FeatureIcon"; +import { + useFeatureMetrics, + useBaselineMetrics, +} from "../../queries/useMonitoringApi"; +import type { + NumericHistogram, + CategoricalHistogram, +} from "../../queries/useMonitoringApi"; +import { + NumericHistogramChart, + CategoricalHistogramChart, +} from "./components/HistogramChart"; +import StatsPanel from "./components/StatsPanel"; +import TimeSeriesAnalysis from "./components/TimeSeriesAnalysis"; +import { useDocumentTitle } from "../../hooks/useDocumentTitle"; + +const BASELINE_KEY = "__baseline__"; + +const GRANULARITY_LABELS: Record = { + daily: "Daily", + weekly: "Weekly", + biweekly: "Biweekly", + monthly: "Monthly", + quarterly: "Quarterly", + [BASELINE_KEY]: "Baseline", +}; + +const FeatureMetricsDetail = () => { + const { projectName, featureViewName, featureName } = useParams(); + const navigate = useNavigate(); + const [selectedGranularity, setSelectedGranularity] = useState(""); + + useDocumentTitle(`${featureName} Monitoring | ${featureViewName} | Feast`); + + const { + data: metrics, + isLoading, + isError, + } = useFeatureMetrics({ + project: projectName || "", + feature_view_name: featureViewName, + feature_name: featureName, + }); + + const { data: baselineMetrics } = useBaselineMetrics( + projectName || "", + featureViewName, + featureName, + ); + + const baselineMetric = + baselineMetrics && baselineMetrics.length > 0 ? baselineMetrics[0] : null; + + const availableGranularities = useMemo(() => { + const granularities = new Set(); + if (metrics) { + for (const m of metrics) { + if (m.row_count > 0) granularities.add(m.granularity); + } + } + return Array.from(granularities).sort(); + }, [metrics]); + + const granularityOptions = useMemo(() => { + const options = availableGranularities.map((g) => ({ + value: g, + inputDisplay: GRANULARITY_LABELS[g] || g, + dropdownDisplay: GRANULARITY_LABELS[g] || g, + })); + if (baselineMetric) { + options.push({ + value: BASELINE_KEY, + inputDisplay: "Baseline", + dropdownDisplay: "Baseline (all data)", + }); + } + return options; + }, [availableGranularities, baselineMetric]); + + const effectiveGranularity = + selectedGranularity || availableGranularities[0] || ""; + + const activeMetric = useMemo(() => { + if (effectiveGranularity === BASELINE_KEY && baselineMetric) { + return baselineMetric; + } + if (!metrics || metrics.length === 0) return null; + const matching = metrics.filter( + (m) => m.granularity === effectiveGranularity && m.row_count > 0, + ); + if (matching.length === 0) { + const withData = metrics.filter((m) => m.row_count > 0); + const candidates = withData.length > 0 ? withData : metrics; + return candidates.reduce((a, b) => + a.metric_date > b.metric_date ? a : b, + ); + } + return matching.reduce((a, b) => (a.metric_date > b.metric_date ? a : b)); + }, [metrics, effectiveGranularity, baselineMetric]); + + const breadcrumbs = [ + { + text: "Monitoring", + onClick: () => navigate(`/p/${projectName}/monitoring`), + }, + { + text: featureViewName || "", + }, + { + text: featureName || "", + }, + ]; + + if (isLoading) { + return ( + + + + + + ); + } + + if (isError || !activeMetric) { + return ( + + + + + No Metrics Available} + body={ +

+ No monitoring metrics found for feature{" "} + {featureName} in feature view{" "} + {featureViewName}. Run a monitoring compute job + first. +

+ } + actions={ + navigate(`/p/${projectName}/monitoring`)} + > + Back to Monitoring + + } + /> +
+
+ ); + } + + const isNumeric = activeMetric.feature_type === "numeric"; + + return ( + + navigate(`/p/${projectName}/monitoring`)} + > + Back to Monitoring + , + ]} + /> + + + + + {granularityOptions.length > 0 && ( + <> + + + + setSelectedGranularity(val)} + compressed + /> + + + + + + )} + + + + {isNumeric && activeMetric.histogram && ( + + )} + {!isNumeric && activeMetric.histogram && ( + + )} + {!activeMetric.histogram && ( + No Histogram Data} + body={

Histogram data is not available for this metric.

} + /> + )} +
+ + + + +
+ + {metrics && metrics.length > 1 && ( + <> + + + + )} +
+
+ ); +}; + +export default FeatureMetricsDetail; diff --git a/ui/src/pages/monitoring/FeatureMetricsTable.tsx b/ui/src/pages/monitoring/FeatureMetricsTable.tsx new file mode 100644 index 00000000000..5b998c98aee --- /dev/null +++ b/ui/src/pages/monitoring/FeatureMetricsTable.tsx @@ -0,0 +1,426 @@ +import React, { useState, useMemo, useEffect } from "react"; +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiBadge, + EuiButtonIcon, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiHealth, + EuiLink, + EuiPopover, + EuiProgress, + EuiTitle, + EuiToolTip, + Criteria, +} from "@elastic/eui"; +import type { + FeatureMetric, + NumericHistogram, + CategoricalHistogram, +} from "../../queries/useMonitoringApi"; + +const healthColor = (nullRate: number): string => { + if (nullRate >= 0.5) return "danger"; + if (nullRate >= 0.1) return "warning"; + return "success"; +}; + +const healthLabel = (nullRate: number): string => { + if (nullRate >= 0.5) return "High null rate"; + if (nullRate >= 0.1) return "Moderate null rate"; + return "Healthy"; +}; + +const formatNum = (val: number | null, decimals = 2): string => { + if (val === null || val === undefined) return "—"; + if (Number.isInteger(val)) return val.toLocaleString(); + return val.toFixed(decimals); +}; + +const formatFreshness = (computedAt: string | null): string => { + if (!computedAt) return "—"; + const diff = Date.now() - new Date(computedAt).getTime(); + const mins = Math.floor(diff / 60_000); + if (mins < 1) return "just now"; + if (mins < 60) return `${mins}m ago`; + const hrs = Math.floor(mins / 60); + if (hrs < 24) return `${hrs}h ago`; + const days = Math.floor(hrs / 24); + if (days < 30) return `${days}d ago`; + return `${Math.floor(days / 30)}mo ago`; +}; + +const freshnessColor = (computedAt: string | null): string => { + if (!computedAt) return "subdued"; + const hrs = (Date.now() - new Date(computedAt).getTime()) / 3_600_000; + if (hrs < 24) return "success"; + if (hrs < 72) return "warning"; + return "danger"; +}; + +const MiniHistogram = ({ metric }: { metric: FeatureMetric }) => { + if (!metric.histogram) return ; + + const width = 120; + const height = 28; + + if (metric.feature_type === "numeric") { + const hist = metric.histogram as NumericHistogram; + const maxCount = Math.max(...hist.counts, 1); + const barW = Math.max(Math.floor(width / hist.counts.length) - 1, 2); + + return ( + + + {hist.counts.map((count, i) => { + const h = (count / maxCount) * (height - 2); + return ( + + ); + })} + + + ); + } + + const hist = metric.histogram as CategoricalHistogram; + const maxCount = Math.max(...hist.values.map((v) => v.count), 1); + const barW = Math.max( + Math.floor(width / Math.min(hist.values.length, 10)) - 1, + 6, + ); + + return ( + + + {hist.values.slice(0, 10).map((v, i) => { + const h = (v.count / maxCount) * (height - 2); + return ( + + ); + })} + + + ); +}; + +interface FeatureMetricsTableProps { + metrics: FeatureMetric[]; + isLoading: boolean; + onFeatureClick: (fvName: string, featureName: string) => void; +} + +const PAGE_SIZE_OPTIONS = [10, 20, 50]; + +const FeatureMetricsTable = ({ + metrics, + isLoading, + onFeatureClick, +}: FeatureMetricsTableProps) => { + const [sortField, setSortField] = + useState("feature_view_name"); + const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc"); + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(20); + + useEffect(() => { + setPageIndex(0); + }, [metrics]); + + const latestMetrics = useMemo(() => { + const byKey = new Map(); + for (const m of metrics) { + const key = `${m.feature_view_name}::${m.feature_name}`; + const existing = byKey.get(key); + if (!existing) { + byKey.set(key, m); + } else { + const preferNew = + m.row_count > 0 && existing.row_count === 0 + ? true + : existing.row_count > 0 && m.row_count === 0 + ? false + : m.metric_date > existing.metric_date; + if (preferNew) byKey.set(key, m); + } + } + return Array.from(byKey.values()); + }, [metrics]); + + const sortedItems = useMemo(() => { + return [...latestMetrics].sort((a, b) => { + const aVal = a[sortField]; + const bVal = b[sortField]; + if (aVal == null && bVal == null) return 0; + if (aVal == null) return 1; + if (bVal == null) return -1; + if (aVal < bVal) return sortDirection === "asc" ? -1 : 1; + if (aVal > bVal) return sortDirection === "asc" ? 1 : -1; + return 0; + }); + }, [latestMetrics, sortField, sortDirection]); + + const pageOfItems = useMemo(() => { + const start = pageIndex * pageSize; + return sortedItems.slice(start, start + pageSize); + }, [sortedItems, pageIndex, pageSize]); + + const pagination = useMemo( + () => ({ + pageIndex, + pageSize, + totalItemCount: sortedItems.length, + pageSizeOptions: PAGE_SIZE_OPTIONS, + }), + [pageIndex, pageSize, sortedItems.length], + ); + + const onTableChange = ({ sort, page }: Criteria) => { + if (sort) { + setSortField(sort.field as keyof FeatureMetric); + setSortDirection(sort.direction); + } + if (page) { + setPageIndex(page.index); + setPageSize(page.size); + } + }; + + const [isLegendOpen, setIsLegendOpen] = useState(false); + + const columnLegend = [ + { + title: "Feature", + description: + "Name of the individual feature. Click to view full distribution and detailed statistics.", + }, + { + title: "Feature View", + description: + "The feature view this feature belongs to — a logical grouping of related features sharing the same data source.", + }, + { + title: "Type", + description: + "Data type: numeric (continuous/discrete numbers) or categorical (strings/labels).", + }, + { + title: "Distribution", + description: + "Compact histogram showing the value distribution. Blue bars = numeric, orange bars = categorical.", + }, + { + title: "Rows", + description: + "Total number of rows (data points) observed for this feature in the computed time window.", + }, + { + title: "Null Rate", + description: + "Percentage of rows with missing (null) values. Shown as a progress bar colored by severity.", + }, + { + title: "Health", + description: + "Data quality indicator based on null rate: Healthy (< 10%), Moderate (10–49%), High (>= 50%).", + }, + { + title: "Mean", + description: + "Arithmetic mean of the feature values. Only shown for numeric features.", + }, + { + title: "Std Dev", + description: + "Standard deviation — measures how spread out the values are from the mean. Only for numeric features.", + }, + { + title: "Freshness", + description: + "Recency of the underlying data. Green (< 24h old), Yellow (24–72h), Red (> 72h). Hover for the data date.", + }, + { + title: "Source", + description: + "Data source type used for metric computation (e.g. batch, stream).", + }, + ]; + + const columns: EuiBasicTableColumn[] = [ + { + field: "feature_name", + name: "Feature", + sortable: true, + render: (name: string, item: FeatureMetric) => ( + onFeatureClick(item.feature_view_name, name)}> + {name} + + ), + }, + { + field: "feature_view_name", + name: "Feature View", + sortable: true, + }, + { + field: "feature_type", + name: "Type", + sortable: true, + width: "100px", + render: (type: string) => ( + + {type} + + ), + }, + { + name: "Distribution", + width: "140px", + render: (item: FeatureMetric) => , + }, + { + field: "row_count", + name: "Rows", + sortable: true, + width: "90px", + render: (val: number) => formatNum(val, 0), + }, + { + field: "null_rate", + name: "Null Rate", + sortable: true, + width: "150px", + render: (val: number) => ( +
+ + {(val * 100).toFixed(1)}% +
+ ), + }, + { + field: "null_rate", + name: "Health", + width: "130px", + render: (val: number) => ( + {healthLabel(val)} + ), + }, + { + field: "mean", + name: "Mean", + sortable: true, + width: "100px", + render: (val: number | null) => formatNum(val), + }, + { + field: "stddev", + name: "Std Dev", + sortable: true, + width: "100px", + render: (val: number | null) => formatNum(val), + }, + { + field: "metric_date", + name: "Freshness", + sortable: true, + width: "110px", + render: (val: string) => ( + + + {formatFreshness(val)} + + + ), + }, + { + field: "data_source_type", + name: "Source", + width: "80px", + render: (val: string) => {val}, + }, + ]; + + return ( + <> + + + setIsLegendOpen(!isLegendOpen)} + /> + } + isOpen={isLegendOpen} + closePopover={() => setIsLegendOpen(false)} + anchorPosition="downRight" + panelPaddingSize="m" + panelStyle={{ maxWidth: 420 }} + > + +

Column Legend

+
+ +
+
+
+ ({ + "data-test-subj": `row-${item.feature_name}`, + })} + noItemsMessage={ + isLoading + ? "Loading metrics..." + : "No metrics found. Run a monitoring compute job to generate metrics." + } + /> + + ); +}; + +export default FeatureMetricsTable; diff --git a/ui/src/pages/monitoring/FeatureServiceMetricsPanel.tsx b/ui/src/pages/monitoring/FeatureServiceMetricsPanel.tsx new file mode 100644 index 00000000000..536c5d56c6c --- /dev/null +++ b/ui/src/pages/monitoring/FeatureServiceMetricsPanel.tsx @@ -0,0 +1,225 @@ +import React, { useState, useMemo } from "react"; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiStat, + EuiBasicTable, + EuiBasicTableColumn, + EuiProgress, + EuiBadge, + EuiSkeletonText, + Criteria, +} from "@elastic/eui"; +import type { FeatureServiceMetric } from "../../queries/useMonitoringApi"; + +const healthColor = (nullRate: number): string => { + if (nullRate >= 0.5) return "danger"; + if (nullRate >= 0.1) return "warning"; + return "success"; +}; + +interface FeatureServiceMetricsPanelProps { + metrics: FeatureServiceMetric[]; + isLoading: boolean; +} + +const FeatureServiceMetricsPanel = ({ + metrics, + isLoading, +}: FeatureServiceMetricsPanelProps) => { + if (isLoading) { + return ( + + +

Feature Service Metrics

+
+ + +
+ ); + } + + const latestByFS = new Map(); + for (const m of metrics) { + const existing = latestByFS.get(m.feature_service_name); + if (!existing || m.metric_date > existing.metric_date) { + latestByFS.set(m.feature_service_name, m); + } + } + const latestMetrics = Array.from(latestByFS.values()); + + const totalViews = latestMetrics.reduce( + (sum, m) => sum + (m.total_feature_views || 0), + 0, + ); + const totalFeatures = latestMetrics.reduce( + (sum, m) => sum + (m.total_features || 0), + 0, + ); + const avgNullRate = + latestMetrics.length > 0 + ? latestMetrics.reduce((sum, m) => sum + (m.avg_null_rate || 0), 0) / + latestMetrics.length + : 0; + + const columns: EuiBasicTableColumn[] = [ + { + field: "feature_service_name", + name: "Feature Service", + sortable: true, + }, + { + field: "total_feature_views", + name: "Feature Views", + sortable: true, + width: "110px", + }, + { + field: "total_features", + name: "Features", + sortable: true, + width: "80px", + }, + { + field: "avg_null_rate", + name: "Avg Null Rate", + sortable: true, + render: (val: number) => ( +
+ + {((val || 0) * 100).toFixed(1)}% +
+ ), + }, + { + field: "max_null_rate", + name: "Max Null Rate", + sortable: true, + width: "110px", + render: (val: number) => `${((val || 0) * 100).toFixed(1)}%`, + }, + { + field: "metric_date", + name: "Date", + sortable: true, + width: "110px", + }, + { + field: "data_source_type", + name: "Source", + width: "80px", + render: (val: string) => {val}, + }, + ]; + + return ( + + +

Feature Service Metrics

+
+

+ Aggregated data quality metrics across feature services. +

+ + + + + + + + + + + + + + + + + + + + {latestMetrics.length > 0 && ( + + )} +
+ ); +}; + +const SortableFSTable = ({ + items, + columns, +}: { + items: FeatureServiceMetric[]; + columns: EuiBasicTableColumn[]; +}) => { + const [sortField, setSortField] = useState("feature_service_name"); + const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc"); + + const sortedItems = useMemo(() => { + return [...items].sort((a, b) => { + const aVal = (a as any)[sortField]; + const bVal = (b as any)[sortField]; + if (aVal == null && bVal == null) return 0; + if (aVal == null) return 1; + if (bVal == null) return -1; + if (aVal < bVal) return sortDirection === "asc" ? -1 : 1; + if (aVal > bVal) return sortDirection === "asc" ? 1 : -1; + return 0; + }); + }, [items, sortField, sortDirection]); + + const onTableChange = ({ sort }: Criteria) => { + if (sort) { + setSortField(sort.field as string); + setSortDirection(sort.direction); + } + }; + + return ( + + ); +}; + +export default FeatureServiceMetricsPanel; diff --git a/ui/src/pages/monitoring/FeatureViewMetricsPanel.tsx b/ui/src/pages/monitoring/FeatureViewMetricsPanel.tsx new file mode 100644 index 00000000000..a0dcc78a8ab --- /dev/null +++ b/ui/src/pages/monitoring/FeatureViewMetricsPanel.tsx @@ -0,0 +1,241 @@ +import React, { useState, useMemo } from "react"; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiStat, + EuiBasicTable, + EuiBasicTableColumn, + EuiProgress, + EuiBadge, + EuiSkeletonText, + Criteria, +} from "@elastic/eui"; +import type { FeatureViewMetric } from "../../queries/useMonitoringApi"; + +const healthColor = (nullRate: number): string => { + if (nullRate >= 0.5) return "danger"; + if (nullRate >= 0.1) return "warning"; + return "success"; +}; + +interface FeatureViewMetricsPanelProps { + metrics: FeatureViewMetric[]; + isLoading: boolean; + title: string; + description?: string; +} + +const FeatureViewMetricsPanel = ({ + metrics, + isLoading, + title, + description, +}: FeatureViewMetricsPanelProps) => { + if (isLoading) { + return ( + + +

{title}

+
+ + +
+ ); + } + + const latestByFV = new Map(); + for (const m of metrics) { + const existing = latestByFV.get(m.feature_view_name); + if (!existing || m.metric_date > existing.metric_date) { + latestByFV.set(m.feature_view_name, m); + } + } + const latestMetrics = Array.from(latestByFV.values()); + + const totalRows = latestMetrics.reduce( + (sum, m) => sum + (m.total_row_count || 0), + 0, + ); + const totalFeatures = latestMetrics.reduce( + (sum, m) => sum + (m.total_features || 0), + 0, + ); + const avgNullRate = + latestMetrics.length > 0 + ? latestMetrics.reduce((sum, m) => sum + (m.avg_null_rate || 0), 0) / + latestMetrics.length + : 0; + const healthyViews = latestMetrics.filter( + (m) => m.avg_null_rate < 0.1, + ).length; + + const columns: EuiBasicTableColumn[] = [ + { + field: "feature_view_name", + name: "Feature View", + sortable: true, + }, + { + field: "total_row_count", + name: "Total Rows", + sortable: true, + render: (val: number) => (val || 0).toLocaleString(), + }, + { + field: "total_features", + name: "Features", + sortable: true, + width: "80px", + }, + { + field: "features_with_nulls", + name: "With Nulls", + sortable: true, + width: "90px", + }, + { + field: "avg_null_rate", + name: "Avg Null Rate", + sortable: true, + render: (val: number) => ( +
+ + {((val || 0) * 100).toFixed(1)}% +
+ ), + }, + { + field: "max_null_rate", + name: "Max Null Rate", + sortable: true, + width: "110px", + render: (val: number) => `${((val || 0) * 100).toFixed(1)}%`, + }, + { + field: "metric_date", + name: "Date", + sortable: true, + width: "110px", + }, + { + field: "data_source_type", + name: "Source", + width: "80px", + render: (val: string) => {val}, + }, + ]; + + return ( + + +

{title}

+
+ {description && ( +

+ {description} +

+ )} + + + + + + + + + + + + + + + + + + + + {latestMetrics.length > 0 && ( + + )} +
+ ); +}; + +const SortableTable = ({ + items, + columns, +}: { + items: FeatureViewMetric[]; + columns: EuiBasicTableColumn[]; +}) => { + const [sortField, setSortField] = useState("feature_view_name"); + const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc"); + + const sortedItems = useMemo(() => { + return [...items].sort((a, b) => { + const aVal = (a as any)[sortField]; + const bVal = (b as any)[sortField]; + if (aVal == null && bVal == null) return 0; + if (aVal == null) return 1; + if (bVal == null) return -1; + if (aVal < bVal) return sortDirection === "asc" ? -1 : 1; + if (aVal > bVal) return sortDirection === "asc" ? 1 : -1; + return 0; + }); + }, [items, sortField, sortDirection]); + + const onTableChange = ({ sort }: Criteria) => { + if (sort) { + setSortField(sort.field as string); + setSortDirection(sort.direction); + } + }; + + return ( + + ); +}; + +export default FeatureViewMetricsPanel; diff --git a/ui/src/pages/monitoring/Index.tsx b/ui/src/pages/monitoring/Index.tsx new file mode 100644 index 00000000000..848d6ee9ae8 --- /dev/null +++ b/ui/src/pages/monitoring/Index.tsx @@ -0,0 +1,283 @@ +import React, { useState, useContext, useMemo } from "react"; +import { useParams, useNavigate } from "react-router-dom"; +import { + EuiPageTemplate, + EuiSpacer, + EuiTabbedContent, + EuiTabbedContentTab, + EuiEmptyPrompt, + EuiButton, + EuiCallOut, +} from "@elastic/eui"; + +import { useDocumentTitle } from "../../hooks/useDocumentTitle"; +import useLoadRegistry from "../../queries/useLoadRegistry"; +import RegistryPathContext from "../../contexts/RegistryPathContext"; +import { + useFeatureMetrics, + useFeatureViewMetrics, + useFeatureServiceMetrics, + useComputeMetrics, +} from "../../queries/useMonitoringApi"; +import FeatureMetricsTable from "./FeatureMetricsTable"; +import FeatureViewMetricsPanel from "./FeatureViewMetricsPanel"; +import FeatureServiceMetricsPanel from "./FeatureServiceMetricsPanel"; +import MetricsFilters from "./components/MetricsFilters"; + +const MonitoringIndex = () => { + useDocumentTitle("Monitoring | Feast"); + + const { projectName } = useParams(); + const navigate = useNavigate(); + const registryUrl = useContext(RegistryPathContext); + const { data: registryData } = useLoadRegistry(registryUrl, projectName); + + const [selectedFV, setSelectedFV] = useState(""); + const [granularity, setGranularity] = useState("baseline"); + const [dataSourceType, setDataSourceType] = useState(""); + const [startDate, setStartDate] = useState(""); + const [endDate, setEndDate] = useState(""); + + const isBaseline = granularity === "baseline"; + + const handleGranularityChange = (g: string) => { + setGranularity(g); + if (g === "baseline") { + setStartDate(""); + setEndDate(""); + } + }; + + const filters = useMemo( + () => ({ + project: projectName || "", + feature_view_name: selectedFV || undefined, + granularity: isBaseline ? undefined : granularity || undefined, + data_source_type: dataSourceType || undefined, + start_date: isBaseline ? undefined : startDate || undefined, + end_date: isBaseline ? undefined : endDate || undefined, + is_baseline: isBaseline || undefined, + }), + [ + projectName, + selectedFV, + granularity, + isBaseline, + dataSourceType, + startDate, + endDate, + ], + ); + + const featureQuery = useFeatureMetrics(filters); + const fvQuery = useFeatureViewMetrics(filters); + const fsQuery = useFeatureServiceMetrics({ + project: projectName || "", + granularity: isBaseline ? undefined : granularity || undefined, + data_source_type: dataSourceType || undefined, + start_date: startDate || undefined, + end_date: endDate || undefined, + is_baseline: isBaseline || undefined, + }); + const computeMutation = useComputeMetrics(); + + const featureViews = useMemo(() => { + if (!registryData?.mergedFVList) return []; + return registryData.mergedFVList.map((fv: any) => fv.name as string); + }, [registryData]); + + const handleFeatureClick = (fvName: string, featureName: string) => { + navigate(`/p/${projectName}/monitoring/feature/${fvName}/${featureName}`); + }; + + const uniqueFeatureCount = useMemo(() => { + if (!featureQuery.data) return 0; + const seen = new Set(); + for (const m of featureQuery.data) { + seen.add(`${m.feature_view_name}::${m.feature_name}`); + } + return seen.size; + }, [featureQuery.data]); + + const handleRefresh = () => { + featureQuery.refetch(); + fvQuery.refetch(); + fsQuery.refetch(); + }; + + const handleCompute = () => { + computeMutation.mutate({ + project: projectName || "", + feature_view_name: selectedFV || undefined, + }); + }; + + const hasError = featureQuery.isError && fvQuery.isError && fsQuery.isError; + const hasData = + (featureQuery.data && featureQuery.data.length > 0) || + (fvQuery.data && fvQuery.data.length > 0); + + const tabs: EuiTabbedContentTab[] = [ + { + id: "features", + name: `Features${uniqueFeatureCount > 0 ? ` (${uniqueFeatureCount})` : ""}`, + content: ( + <> + + + + ), + }, + { + id: "feature-views", + name: "Feature Views", + content: ( + <> + + + + ), + }, + { + id: "feature-services", + name: "Feature Services", + content: ( + <> + + + + ), + }, + ]; + + return ( + + + Compute Metrics + , + ]} + /> + + {hasError && ( + <> + +

+ Could not connect to the monitoring API. Make sure the Feast + registry server is running with monitoring enabled. +

+
+ + + )} + + + + + + {!hasData && !featureQuery.isLoading && !hasError && ( + No Metrics Yet} + body={ +

+ No monitoring data has been computed for this project. Click + "Compute Metrics" to run data quality analysis on your + feature views, or use the CLI:{" "} + feast monitor run --data-source batch +

+ } + actions={ + + Compute Metrics + + } + /> + )} + + {(hasData || featureQuery.isLoading) && ( + + )} + + {computeMutation.isSuccess && ( + <> + + +

+ Data quality metrics have been computed. The table above has + been refreshed. +

+
+ + )} + + {computeMutation.isError && ( + <> + + +

{(computeMutation.error as Error)?.message}

+
+ + )} +
+
+ ); +}; + +export default MonitoringIndex; diff --git a/ui/src/pages/monitoring/components/HistogramChart.tsx b/ui/src/pages/monitoring/components/HistogramChart.tsx new file mode 100644 index 00000000000..a716b025021 --- /dev/null +++ b/ui/src/pages/monitoring/components/HistogramChart.tsx @@ -0,0 +1,435 @@ +import React, { useState } from "react"; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiText, + EuiModal, + EuiModalHeader, + EuiModalHeaderTitle, + EuiModalBody, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiToolTip, +} from "@elastic/eui"; +import type { + NumericHistogram, + CategoricalHistogram, +} from "../../../queries/useMonitoringApi"; + +const BAR_COLOR = "#006BB4"; +const BAR_COLOR_BASELINE = "#BD271E55"; + +interface ChartDimensions { + chartHeight: number; + axisHeight: number; + leftPad: number; + barGap: number; + minBarWidth: number; + targetBarsWidth: number; + fontSize: number; + xTickCount: number; +} + +const COMPACT: ChartDimensions = { + chartHeight: 160, + axisHeight: 28, + leftPad: 54, + barGap: 2, + minBarWidth: 6, + targetBarsWidth: 460, + fontSize: 10, + xTickCount: 2, +}; + +const EXPANDED: ChartDimensions = { + chartHeight: 400, + axisHeight: 48, + leftPad: 72, + barGap: 3, + minBarWidth: 12, + targetBarsWidth: 800, + fontSize: 12, + xTickCount: 6, +}; + +const formatNumber = (val: number, compact: boolean): string => { + if (val === 0) return "0"; + const abs = Math.abs(val); + if (compact && abs >= 1_000_000) return (val / 1_000_000).toFixed(1) + "M"; + if (compact && abs >= 1_000) return (val / 1_000).toFixed(1) + "K"; + if (abs >= 1) + return val.toLocaleString(undefined, { maximumFractionDigits: 1 }); + if (abs >= 0.01) return val.toFixed(2); + return val.toExponential(1); +}; + +const renderNumericSvg = ( + histogram: NumericHistogram, + baseline: NumericHistogram | null | undefined, + dim: ChartDimensions, +) => { + const maxCount = Math.max( + ...histogram.counts, + ...(baseline ? baseline.counts : []), + 1, + ); + const numBars = histogram.counts.length; + const barWidth = Math.max( + Math.floor(dim.targetBarsWidth / numBars) - dim.barGap, + dim.minBarWidth, + ); + const barsWidth = (barWidth + dim.barGap) * numBars; + const svgWidth = dim.leftPad + barsWidth + 24; + const isCompact = dim === COMPACT; + + const yTickFractions = [0, 0.25, 0.5, 0.75, 1]; + const yTicks = yTickFractions.map((f) => ({ + label: formatNumber(Math.round(maxCount * f), isCompact), + y: dim.chartHeight - f * dim.chartHeight, + })); + + const xTickStep = Math.max(1, Math.floor(numBars / dim.xTickCount)); + const xTicks: { label: string; x: number }[] = []; + for (let i = 0; i < numBars; i += xTickStep) { + xTicks.push({ + label: formatNumber(histogram.bins[i], isCompact), + x: dim.leftPad + i * (barWidth + dim.barGap) + barWidth / 2, + }); + } + if (numBars > 0) { + const lastBin = histogram.bins[histogram.bins.length - 1]; + xTicks.push({ + label: formatNumber(lastBin, isCompact), + x: dim.leftPad + (numBars - 1) * (barWidth + dim.barGap) + barWidth / 2, + }); + } + + return ( + + {yTicks.map((t, i) => ( + + + + {t.label} + + + ))} + {histogram.counts.map((count, i) => { + const height = (count / maxCount) * dim.chartHeight; + const x = dim.leftPad + i * (barWidth + dim.barGap); + const binStart = histogram.bins[i]; + const binEnd = + i < histogram.bins.length - 1 + ? histogram.bins[i + 1] + : binStart + histogram.bin_width; + const baselineHeight = + baseline && baseline.counts[i] + ? (baseline.counts[i] / maxCount) * dim.chartHeight + : 0; + + return ( + + {baselineHeight > 0 && ( + + )} + + {`${formatNumber(binStart, false)} – ${formatNumber(binEnd, false)}: ${count.toLocaleString()}`} + + + ); + })} + + {xTicks.map((t, i) => ( + + {t.label} + + ))} + + ); +}; + +const NumericHistogramChart = ({ + histogram, + baseline, + title, +}: { + histogram: NumericHistogram; + baseline?: NumericHistogram | null; + title?: string; +}) => { + const [expanded, setExpanded] = useState(false); + + return ( + <> + + + + {title && ( + +

{title}

+
+ )} +
+ + + setExpanded(true)} + /> + + +
+ {title && } +
+ {renderNumericSvg(histogram, baseline, COMPACT)} +
+ {baseline && ( + + + Baseline + + )} +
+ + {expanded && ( + setExpanded(false)} maxWidth={960}> + + {title || "Histogram"} + + +
+ {renderNumericSvg(histogram, baseline, EXPANDED)} +
+ {baseline && ( + <> + + + + Baseline + + + )} +
+
+ )} + + ); +}; + +const LABEL_WIDTH = 60; +const BAR_MAX_WIDTH = 320; +const COUNT_PAD = 80; + +const LABEL_WIDTH_EXP = 120; +const BAR_MAX_WIDTH_EXP = 560; +const COUNT_PAD_EXP = 100; + +const renderCategoricalSvg = ( + histogram: CategoricalHistogram, + isExpanded: boolean, +) => { + const labelW = isExpanded ? LABEL_WIDTH_EXP : LABEL_WIDTH; + const barMax = isExpanded ? BAR_MAX_WIDTH_EXP : BAR_MAX_WIDTH; + const countPad = isExpanded ? COUNT_PAD_EXP : COUNT_PAD; + const totalW = labelW + barMax + countPad; + const truncLen = isExpanded ? 20 : 8; + const fontSize = isExpanded ? 13 : 12; + const barHeight = isExpanded ? 30 : 24; + const rowHeight = barHeight + 6; + + const maxCount = Math.max(...histogram.values.map((v) => v.count), 1); + const chartHeight = histogram.values.length * rowHeight; + + return ( + + {histogram.values.map((v, i) => { + const width = (v.count / maxCount) * barMax; + const y = i * rowHeight; + return ( + + + {v.value.length > truncLen + ? v.value.slice(0, truncLen) + "…" + : v.value} + + + {`${v.value}: ${v.count.toLocaleString()}`} + + + {v.count.toLocaleString()} + + + ); + })} + + ); +}; + +const CategoricalHistogramChart = ({ + histogram, + title, +}: { + histogram: CategoricalHistogram; + title?: string; +}) => { + const [expanded, setExpanded] = useState(false); + + return ( + <> + + + + {title && ( + +

{title}

+
+ )} +
+ + + setExpanded(true)} + /> + + +
+ {title && } +
+ {renderCategoricalSvg(histogram, false)} +
+ + {histogram.unique_count} unique values + {histogram.other_count > 0 && + ` (${histogram.other_count.toLocaleString()} in other categories)`} + +
+ + {expanded && ( + setExpanded(false)} maxWidth={960}> + + + {title || "Category Distribution"} + + + +
+ {renderCategoricalSvg(histogram, true)} +
+ + + {histogram.unique_count} unique values + {histogram.other_count > 0 && + ` (${histogram.other_count.toLocaleString()} in other categories)`} + +
+
+ )} + + ); +}; + +export { NumericHistogramChart, CategoricalHistogramChart }; diff --git a/ui/src/pages/monitoring/components/MetricsFilters.tsx b/ui/src/pages/monitoring/components/MetricsFilters.tsx new file mode 100644 index 00000000000..977044d495a --- /dev/null +++ b/ui/src/pages/monitoring/components/MetricsFilters.tsx @@ -0,0 +1,138 @@ +import React from "react"; +import { + EuiFlexGroup, + EuiFlexItem, + EuiSelect, + EuiFieldText, + EuiFormRow, + EuiButton, +} from "@elastic/eui"; + +interface MetricsFiltersProps { + featureViews: string[]; + selectedFeatureView: string; + onFeatureViewChange: (fv: string) => void; + granularity: string; + onGranularityChange: (g: string) => void; + dataSourceType: string; + onDataSourceTypeChange: (ds: string) => void; + startDate: string; + onStartDateChange: (d: string) => void; + endDate: string; + onEndDateChange: (d: string) => void; + onRefresh: () => void; + isLoading?: boolean; + datesDisabled?: boolean; +} + +const GRANULARITY_OPTIONS = [ + { value: "baseline", text: "Baseline" }, + { value: "daily", text: "Daily" }, + { value: "weekly", text: "Weekly" }, + { value: "biweekly", text: "Biweekly" }, + { value: "monthly", text: "Monthly" }, + { value: "quarterly", text: "Quarterly" }, +]; + +const DATA_SOURCE_OPTIONS = [ + { value: "", text: "All Sources" }, + { value: "batch", text: "Batch" }, + { value: "log", text: "Log" }, +]; + +const MetricsFilters = ({ + featureViews, + selectedFeatureView, + onFeatureViewChange, + granularity, + onGranularityChange, + dataSourceType, + onDataSourceTypeChange, + startDate, + onStartDateChange, + endDate, + onEndDateChange, + onRefresh, + isLoading, + datesDisabled, +}: MetricsFiltersProps) => { + const fvOptions = [ + { value: "", text: "All Feature Views" }, + ...featureViews.map((fv) => ({ value: fv, text: fv })), + ]; + + return ( + + + + onFeatureViewChange(e.target.value)} + compressed + /> + + + + + onGranularityChange(e.target.value)} + compressed + /> + + + + + onDataSourceTypeChange(e.target.value)} + compressed + /> + + + + + onStartDateChange(e.target.value)} + compressed + disabled={datesDisabled} + /> + + + + + onEndDateChange(e.target.value)} + compressed + disabled={datesDisabled} + /> + + + + + Refresh + + + + ); +}; + +export default MetricsFilters; diff --git a/ui/src/pages/monitoring/components/StatsPanel.tsx b/ui/src/pages/monitoring/components/StatsPanel.tsx new file mode 100644 index 00000000000..070b99373e7 --- /dev/null +++ b/ui/src/pages/monitoring/components/StatsPanel.tsx @@ -0,0 +1,130 @@ +import React from "react"; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiDescriptionList, + EuiDescriptionListTitle, + EuiDescriptionListDescription, + EuiFlexGroup, + EuiFlexItem, + EuiBadge, +} from "@elastic/eui"; +import type { FeatureMetric } from "../../../queries/useMonitoringApi"; + +const formatNumber = (val: number | null, decimals = 4): string => { + if (val === null || val === undefined) return "—"; + if (Number.isInteger(val)) return val.toLocaleString(); + return val.toFixed(decimals); +}; + +const formatPercent = (val: number | null): string => { + if (val === null || val === undefined) return "—"; + return `${(val * 100).toFixed(2)}%`; +}; + +const StatsPanel = ({ + metric, + baseline, +}: { + metric: FeatureMetric; + baseline?: FeatureMetric | null; +}) => { + const isNumeric = metric.feature_type === "numeric"; + + return ( + + + + +

Statistics

+
+
+ + + {metric.feature_type} + + +
+ + + Row Count + + {formatNumber(metric.row_count, 0)} + {baseline && ( + + (baseline: {formatNumber(baseline.row_count, 0)}) + + )} + + + Null Rate + + 0.1 ? "#BD271E" : "inherit", + fontWeight: metric.null_rate > 0.1 ? 600 : 400, + }} + > + {formatPercent(metric.null_rate)} + + {baseline && ( + + (baseline: {formatPercent(baseline.null_rate)}) + + )} + + + {isNumeric && ( + <> + Mean + + {formatNumber(metric.mean)} + {baseline && ( + + (baseline: {formatNumber(baseline.mean)}) + + )} + + + Std Dev + + {formatNumber(metric.stddev)} + + + Min / Max + + {formatNumber(metric.min_val)} / {formatNumber(metric.max_val)} + + + Percentiles + + P50: {formatNumber(metric.p50)} | P75: {formatNumber(metric.p75)}{" "} + | P90: {formatNumber(metric.p90)} | P95:{" "} + {formatNumber(metric.p95)} | P99: {formatNumber(metric.p99)} + + + )} + + Data Source + + {metric.data_source_type} + + + Granularity + + {metric.granularity} + + + Computed At + + {metric.computed_at + ? new Date(metric.computed_at).toLocaleString() + : "—"} + + +
+ ); +}; + +export default StatsPanel; diff --git a/ui/src/pages/monitoring/components/TimeSeriesAnalysis.tsx b/ui/src/pages/monitoring/components/TimeSeriesAnalysis.tsx new file mode 100644 index 00000000000..23acd0be434 --- /dev/null +++ b/ui/src/pages/monitoring/components/TimeSeriesAnalysis.tsx @@ -0,0 +1,651 @@ +import React, { useState, useMemo } from "react"; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiSuperSelect, +} from "@elastic/eui"; +import type { + FeatureMetric, + CategoricalHistogram, +} from "../../../queries/useMonitoringApi"; + +const COLORS = [ + "#006BB4", + "#54B399", + "#E7664C", + "#9170B8", + "#D36086", + "#6092C0", + "#D6BF57", + "#B9A888", +]; + +const RANGE_OPTIONS = [ + { value: "24h", inputDisplay: "Last 24 hours" }, + { value: "7d", inputDisplay: "Last 7 days" }, + { value: "30d", inputDisplay: "Last 30 days" }, + { value: "90d", inputDisplay: "Last 90 days" }, + { value: "all", inputDisplay: "All time" }, +]; + +const rangeToMs: Record = { + "24h": 24 * 3600_000, + "7d": 7 * 86400_000, + "30d": 30 * 86400_000, + "90d": 90 * 86400_000, + all: Infinity, +}; + +interface ChartDims { + width: number; + height: number; + padLeft: number; + padRight: number; + padTop: number; + padBottom: number; +} + +const DIMS: ChartDims = { + width: 860, + height: 220, + padLeft: 60, + padRight: 20, + padTop: 10, + padBottom: 30, +}; + +const formatDate = (d: string): string => { + const dt = new Date(d); + const mm = String(dt.getMonth() + 1).padStart(2, "0"); + const dd = String(dt.getDate()).padStart(2, "0"); + const hh = String(dt.getHours()).padStart(2, "0"); + const mi = String(dt.getMinutes()).padStart(2, "0"); + return `${mm}-${dd} ${hh}:${mi}`; +}; + +const formatAxisVal = (v: number): string => { + if (v === 0) return "0"; + const abs = Math.abs(v); + if (abs >= 1_000_000) return (v / 1_000_000).toFixed(1) + "M"; + if (abs >= 1_000) return (v / 1_000).toFixed(1) + "K"; + if (abs >= 1) return v.toFixed(1); + return (v * 100).toFixed(1) + "%"; +}; + +const niceYTicks = (min: number, max: number, count = 5): number[] => { + if (max === min) return [min]; + const step = (max - min) / (count - 1); + return Array.from({ length: count }, (_, i) => min + step * i); +}; + +interface LineSeriesData { + label: string; + color: string; + dashArray?: string; + points: { x: number; y: number; date: string; value: number }[]; +} + +const renderMultiLineChart = ( + series: LineSeriesData[], + dims: ChartDims, + yLabel: string, + yFormatter: (v: number) => string = formatAxisVal, +) => { + const allPoints = series.flatMap((s) => s.points); + if (allPoints.length === 0) return null; + + const xMin = Math.min(...allPoints.map((p) => p.x)); + const xMax = Math.max(...allPoints.map((p) => p.x)); + const yMin = Math.min(...allPoints.map((p) => p.value), 0); + const yMax = Math.max(...allPoints.map((p) => p.value), 0.01); + + const plotW = dims.width - dims.padLeft - dims.padRight; + const plotH = dims.height - dims.padTop - dims.padBottom; + + const scaleX = (x: number) => + xMax === xMin + ? dims.padLeft + plotW / 2 + : dims.padLeft + ((x - xMin) / (xMax - xMin)) * plotW; + const scaleY = (v: number) => + dims.padTop + plotH - ((v - yMin) / (yMax - yMin || 1)) * plotH; + + const yTicks = niceYTicks(yMin, yMax); + const xDates = allPoints + .map((p) => ({ x: p.x, date: p.date })) + .filter((v, i, arr) => arr.findIndex((a) => a.date === v.date) === i) + .sort((a, b) => a.x - b.x); + + const maxXLabels = Math.floor(plotW / 80); + const xStep = Math.max(1, Math.ceil(xDates.length / maxXLabels)); + const xLabels = xDates.filter((_, i) => i % xStep === 0); + + return ( + + {/* Y axis grid + labels */} + {yTicks.map((v, i) => { + const y = scaleY(v); + return ( + + + + {yFormatter(v)} + + + ); + })} + + {/* Y axis label */} + + {yLabel} + + + {/* X axis labels */} + {xLabels.map((xl, i) => ( + + {formatDate(xl.date)} + + ))} + + {/* Lines */} + {series.map((s, si) => { + if (s.points.length === 0) return null; + const sorted = [...s.points].sort((a, b) => a.x - b.x); + const pathD = sorted + .map( + (p, i) => + `${i === 0 ? "M" : "L"} ${scaleX(p.x)} ${scaleY(p.value)}`, + ) + .join(" "); + return ( + + + {sorted.map((p, i) => ( + + ))} + + ); + })} + + ); +}; + +const renderAreaChart = ( + points: { x: number; value: number; date: string }[], + dims: ChartDims, + yLabel: string, + lineColor: string, + fillColor: string, +) => { + if (points.length === 0) return null; + + const sorted = [...points].sort((a, b) => a.x - b.x); + const xMin = Math.min(...sorted.map((p) => p.x)); + const xMax = Math.max(...sorted.map((p) => p.x)); + const yMin = 0; + const yMax = Math.max(...sorted.map((p) => p.value), 0.01); + + const plotW = dims.width - dims.padLeft - dims.padRight; + const plotH = dims.height - dims.padTop - dims.padBottom; + + const scaleX = (x: number) => + xMax === xMin + ? dims.padLeft + plotW / 2 + : dims.padLeft + ((x - xMin) / (xMax - xMin)) * plotW; + const scaleY = (v: number) => + dims.padTop + plotH - ((v - yMin) / (yMax - yMin || 1)) * plotH; + + const yTicks = niceYTicks(yMin, yMax); + const baseline = scaleY(0); + + const areaPath = + `M ${scaleX(sorted[0].x)} ${baseline} ` + + sorted.map((p) => `L ${scaleX(p.x)} ${scaleY(p.value)}`).join(" ") + + ` L ${scaleX(sorted[sorted.length - 1].x)} ${baseline} Z`; + + const linePath = sorted + .map((p, i) => `${i === 0 ? "M" : "L"} ${scaleX(p.x)} ${scaleY(p.value)}`) + .join(" "); + + const maxXLabels = Math.floor(plotW / 80); + const xStep = Math.max(1, Math.ceil(sorted.length / maxXLabels)); + const xLabels = sorted.filter((_, i) => i % xStep === 0); + + return ( + + {yTicks.map((v, i) => { + const y = scaleY(v); + return ( + + + + {(v * 100).toFixed(0)}% + + + ); + })} + + + {yLabel} + + + {xLabels.map((xl, i) => ( + + {formatDate(xl.date)} + + ))} + + + + + ); +}; + +const Legend = ({ + items, +}: { + items: { label: string; color: string; dashed?: boolean }[]; +}) => ( +
+ {items.map((item, i) => ( +
+ {item.dashed ? ( + + + + ) : ( +
+ )} + {item.label} +
+ ))} +
+); + +interface TimeSeriesAnalysisProps { + metrics: FeatureMetric[]; + featureType: string; +} + +const TimeSeriesAnalysis = ({ + metrics, + featureType, +}: TimeSeriesAnalysisProps) => { + const [range, setRange] = useState("all"); + + const filteredMetrics = useMemo(() => { + if (range === "all") return metrics; + const cutoff = Date.now() - rangeToMs[range]; + return metrics.filter((m) => new Date(m.metric_date).getTime() >= cutoff); + }, [metrics, range]); + + const sorted = useMemo( + () => + [...filteredMetrics] + .filter((m) => m.row_count > 0) + .sort((a, b) => a.metric_date.localeCompare(b.metric_date)), + [filteredMetrics], + ); + + const toX = (m: FeatureMetric) => new Date(m.metric_date).getTime(); + const isNumeric = featureType === "numeric"; + const hasData = sorted.length >= 1; + + return ( + + + + +

Time-Series Analysis

+
+

+ Historical trends for central aggregates and quality signals. +

+
+ + + +
+ + + + {!hasData ? ( +

+ No data points available for the selected time range. Try a wider + range. +

+ ) : isNumeric ? ( + + ) : ( + + )} +
+ ); +}; + +const NumericTimeSeries = ({ + metrics, + toX, +}: { + metrics: FeatureMetric[]; + toX: (m: FeatureMetric) => number; +}) => { + const driftSeries: LineSeriesData[] = useMemo(() => { + const build = ( + label: string, + color: string, + accessor: (m: FeatureMetric) => number | null, + dashArray?: string, + ): LineSeriesData => ({ + label, + color, + dashArray, + points: metrics + .filter((m) => accessor(m) !== null) + .map((m) => ({ + x: toX(m), + y: 0, + value: accessor(m)!, + date: m.metric_date, + })), + }); + return [ + build("Mean", COLORS[0], (m) => m.mean, "6,3"), + build("P50", COLORS[1], (m) => m.p50), + build("P95", COLORS[2], (m) => m.p95), + ]; + }, [metrics, toX]); + + const nullPoints = useMemo( + () => + metrics.map((m) => ({ + x: toX(m), + value: m.null_rate, + date: m.metric_date, + })), + [metrics, toX], + ); + + return ( + <> +

+ Aggregate Metrics Drift (Mean/P50/P95) +

+
+ {renderMultiLineChart(driftSeries, DIMS, "Metric Value")} +
+ + + + +

+ Null Rate Evolution (%) +

+
+ {renderAreaChart( + nullPoints, + { ...DIMS, height: 160 }, + "Percentage (%)", + "#BD271E", + "rgba(189, 39, 30, 0.15)", + )} +
+ + ); +}; + +const CategoricalTimeSeries = ({ + metrics, + toX, +}: { + metrics: FeatureMetric[]; + toX: (m: FeatureMetric) => number; +}) => { + const { cardinalitySeries, shareSeries, topCategories } = useMemo(() => { + const catCounts = new Map(); + for (const m of metrics) { + const hist = m.histogram as CategoricalHistogram | null; + if (!hist) continue; + for (const v of hist.values) { + catCounts.set(v.value, (catCounts.get(v.value) || 0) + v.count); + } + } + const topCats = Array.from(catCounts.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, 5) + .map(([v]) => v); + + const cardSeries: LineSeriesData[] = [ + { + label: "Cardinality", + color: COLORS[0], + points: metrics + .filter((m) => m.histogram) + .map((m) => ({ + x: toX(m), + y: 0, + value: (m.histogram as CategoricalHistogram).unique_count || 0, + date: m.metric_date, + })), + }, + ...topCats.map((cat, i) => ({ + label: cat, + color: COLORS[(i + 1) % COLORS.length], + points: metrics + .filter((m) => m.histogram) + .map((m) => { + const hist = m.histogram as CategoricalHistogram; + const entry = hist.values.find((v) => v.value === cat); + return { + x: toX(m), + y: 0, + value: entry?.count || 0, + date: m.metric_date, + }; + }), + })), + ]; + + const shrSeries: LineSeriesData[] = topCats.map((cat, i) => ({ + label: cat, + color: COLORS[(i + 1) % COLORS.length], + points: metrics + .filter((m) => m.histogram && m.row_count > 0) + .map((m) => { + const hist = m.histogram as CategoricalHistogram; + const entry = hist.values.find((v) => v.value === cat); + return { + x: toX(m), + y: 0, + value: ((entry?.count || 0) / m.row_count) * 100, + date: m.metric_date, + }; + }), + })); + + return { + cardinalitySeries: cardSeries, + shareSeries: shrSeries, + topCategories: topCats, + }; + }, [metrics, toX]); + + const nullPoints = useMemo( + () => + metrics.map((m) => ({ + x: toX(m), + value: m.null_rate, + date: m.metric_date, + })), + [metrics, toX], + ); + + const shareYFormatter = (v: number) => `${v.toFixed(0)}%`; + + return ( + <> +

+ Cardinality over time +

+
+ {renderMultiLineChart(cardinalitySeries, DIMS, "Count")} +
+ ({ + label: s.label, + color: s.color, + }))} + /> + + + +

+ Top category share over time (%) +

+
+ {renderMultiLineChart( + shareSeries, + DIMS, + "Percentage (%)", + shareYFormatter, + )} +
+ ({ + label: cat, + color: COLORS[(i + 1) % COLORS.length], + }))} + /> + + + +

+ Null Rate Evolution (%) +

+
+ {renderAreaChart( + nullPoints, + { ...DIMS, height: 160 }, + "Percentage (%)", + "#BD271E", + "rgba(189, 39, 30, 0.15)", + )} +
+ + ); +}; + +export default TimeSeriesAnalysis; diff --git a/ui/src/pages/saved-data-sets/DatasetOverviewTab.tsx b/ui/src/pages/saved-data-sets/DatasetOverviewTab.tsx index 9ee7dd1aa42..d9a0ab43af9 100644 --- a/ui/src/pages/saved-data-sets/DatasetOverviewTab.tsx +++ b/ui/src/pages/saved-data-sets/DatasetOverviewTab.tsx @@ -69,7 +69,7 @@ const EntityOverviewTab = () => { { + data?.spec?.joinKeys!.map((joinKey: any) => { return { name: joinKey }; })! } diff --git a/ui/src/pages/saved-data-sets/Index.tsx b/ui/src/pages/saved-data-sets/Index.tsx index c6cc81f4146..f78ee572ae6 100644 --- a/ui/src/pages/saved-data-sets/Index.tsx +++ b/ui/src/pages/saved-data-sets/Index.tsx @@ -1,28 +1,25 @@ -import React, { useContext } from "react"; +import React from "react"; +import { useParams } from "react-router-dom"; import { EuiPageTemplate, EuiLoadingSpinner } from "@elastic/eui"; import { DatasetIcon } from "../../graphics/DatasetIcon"; -import useLoadRegistry from "../../queries/useLoadRegistry"; import { useDocumentTitle } from "../../hooks/useDocumentTitle"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; import DatasetsListingTable from "./DatasetsListingTable"; import DatasetsIndexEmptyState from "./DatasetsIndexEmptyState"; +import useResourceQuery, { + savedDatasetListPath, +} from "../../queries/useResourceQuery"; const useLoadSavedDataSets = () => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); - - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.savedDatasets; - - return { - ...registryQuery, - data, - }; + const { projectName } = useParams(); + return useResourceQuery({ + resourceType: "saved-datasets-list", + project: projectName, + restPath: savedDatasetListPath(projectName), + restSelect: (d) => d.savedDatasets, + }); }; const Index = () => { diff --git a/ui/src/pages/saved-data-sets/useLoadDataset.ts b/ui/src/pages/saved-data-sets/useLoadDataset.ts index 40f8a8ebd48..c560f7f9eb6 100644 --- a/ui/src/pages/saved-data-sets/useLoadDataset.ts +++ b/ui/src/pages/saved-data-sets/useLoadDataset.ts @@ -1,22 +1,18 @@ -import { useContext } from "react"; -import RegistryPathContext from "../../contexts/RegistryPathContext"; -import useLoadRegistry from "../../queries/useLoadRegistry"; +import { useParams } from "react-router-dom"; +import useResourceQuery, { + savedDatasetDetailPath, +} from "../../queries/useResourceQuery"; -const useLoadEntity = (entityName: string) => { - const registryUrl = useContext(RegistryPathContext); - const registryQuery = useLoadRegistry(registryUrl); +const useLoadDataset = (datasetName: string) => { + const { projectName } = useParams(); - const data = - registryQuery.data === undefined - ? undefined - : registryQuery.data.objects.savedDatasets?.find( - (fv) => fv.spec?.name === entityName, - ); - - return { - ...registryQuery, - data, - }; + return useResourceQuery({ + resourceType: `saved-dataset:${datasetName}`, + project: projectName, + restPath: savedDatasetDetailPath(datasetName, projectName || ""), + restSelect: (d) => d, + enabled: !!datasetName, + }); }; -export default useLoadEntity; +export default useLoadDataset; diff --git a/ui/src/parsers/mergedFVTypes.ts b/ui/src/parsers/mergedFVTypes.ts index 1c6b759be1e..0c65dea54f6 100644 --- a/ui/src/parsers/mergedFVTypes.ts +++ b/ui/src/parsers/mergedFVTypes.ts @@ -4,6 +4,7 @@ enum FEAST_FV_TYPES { regular = "regular", ondemand = "ondemand", stream = "stream", + label = "label", } interface regularFVInterface { @@ -27,7 +28,18 @@ interface SFVInterface { object: feast.core.IStreamFeatureView; } -type genericFVType = regularFVInterface | ODFVInterface | SFVInterface; +interface LabelViewInterface { + name: string; + type: FEAST_FV_TYPES.label; + features: feast.core.IFeatureSpecV2[]; + object: any; +} + +type genericFVType = + | regularFVInterface + | ODFVInterface + | SFVInterface + | LabelViewInterface; const mergedFVTypes = (objects: feast.core.Registry) => { const mergedFVMap: Record = {}; @@ -75,4 +87,10 @@ const mergedFVTypes = (objects: feast.core.Registry) => { export default mergedFVTypes; export { FEAST_FV_TYPES }; -export type { genericFVType, regularFVInterface, ODFVInterface, SFVInterface }; +export type { + genericFVType, + regularFVInterface, + ODFVInterface, + SFVInterface, + LabelViewInterface, +}; diff --git a/ui/src/parsers/parseEntityRelationships.ts b/ui/src/parsers/parseEntityRelationships.ts index 579374e30ff..b1a014044a0 100644 --- a/ui/src/parsers/parseEntityRelationships.ts +++ b/ui/src/parsers/parseEntityRelationships.ts @@ -14,12 +14,21 @@ interface EntityRelation { const parseEntityRelationships = (objects: feast.core.Registry) => { const links: EntityRelation[] = []; + const labelViewNames = new Set( + ((objects as any).labelViews || []).map((lv: any) => lv.spec?.name), + ); + objects.featureServices?.forEach((fs) => { - fs.spec?.features!.forEach((feature) => { + fs.spec?.features!.forEach((feature: any) => { + const viewName = feature?.featureViewName!; + const isLabelView = + feature?.viewType === "labelView" || labelViewNames.has(viewName); links.push({ source: { - type: FEAST_FCO_TYPES["featureView"], - name: feature?.featureViewName!, + type: isLabelView + ? FEAST_FCO_TYPES["labelView"] + : FEAST_FCO_TYPES["featureView"], + name: viewName, }, target: { type: FEAST_FCO_TYPES["featureService"], @@ -134,6 +143,58 @@ const parseEntityRelationships = (objects: feast.core.Registry) => { }); }); + (objects as any).labelViews?.forEach((lv: any) => { + lv.spec?.entities?.forEach((ent: string) => { + links.push({ + source: { + type: FEAST_FCO_TYPES["entity"], + name: ent, + }, + target: { + type: FEAST_FCO_TYPES["labelView"], + name: lv.spec?.name!, + }, + }); + }); + + if (lv.spec?.source?.name) { + links.push({ + source: { + type: FEAST_FCO_TYPES["dataSource"], + name: lv.spec.source.name, + }, + target: { + type: FEAST_FCO_TYPES["labelView"], + name: lv.spec?.name!, + }, + }); + } + if (lv.spec?.source?.batchSource?.name) { + links.push({ + source: { + type: FEAST_FCO_TYPES["dataSource"], + name: lv.spec.source.batchSource.name, + }, + target: { + type: FEAST_FCO_TYPES["labelView"], + name: lv.spec?.name!, + }, + }); + } + if (lv.spec?.batchSource?.name) { + links.push({ + source: { + type: FEAST_FCO_TYPES["dataSource"], + name: lv.spec.batchSource.name, + }, + target: { + type: FEAST_FCO_TYPES["labelView"], + name: lv.spec?.name!, + }, + }); + } + }); + return links; }; diff --git a/ui/src/parsers/types.ts b/ui/src/parsers/types.ts index 1e515f23f34..ee0020bc8e5 100644 --- a/ui/src/parsers/types.ts +++ b/ui/src/parsers/types.ts @@ -3,6 +3,9 @@ enum FEAST_FCO_TYPES { entity = "entity", featureView = "featureView", featureService = "featureService", + labelView = "labelView", + mlflowRun = "mlflowRun", + mlflowModel = "mlflowModel", } export { FEAST_FCO_TYPES }; diff --git a/ui/src/queries/mutations/useDataSourceMutations.ts b/ui/src/queries/mutations/useDataSourceMutations.ts new file mode 100644 index 00000000000..737ced0dbfd --- /dev/null +++ b/ui/src/queries/mutations/useDataSourceMutations.ts @@ -0,0 +1,99 @@ +import { useMutation, useQueryClient } from "react-query"; + +interface ApplyDataSourcePayload { + name: string; + project: string; + type?: number; + timestamp_field?: string; + created_timestamp_column?: string; + description?: string; + tags?: Record; + owner?: string; + file_options?: { uri: string }; + bigquery_options?: { table: string; query: string }; + snowflake_options?: { table: string; database: string; schema_: string }; + redshift_options?: { table: string; database: string; schema_: string }; + kafka_options?: { kafka_bootstrap_servers: string; topic: string }; + spark_options?: { table: string; path: string }; +} + +interface DeleteDataSourcePayload { + name: string; + project: string; +} + +interface MutationResult { + name: string; + project: string; + status: string; +} + +const API_BASE = "/api/v1"; + +const applyDataSource = async ( + payload: ApplyDataSourcePayload, +): Promise => { + const response = await fetch(`${API_BASE}/data_sources`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to apply data source: ${response.status}`, + ); + } + + return response.json(); +}; + +const deleteDataSource = async ( + payload: DeleteDataSourcePayload, +): Promise => { + const response = await fetch( + `${API_BASE}/data_sources/${encodeURIComponent(payload.name)}?project=${encodeURIComponent(payload.project)}`, + { method: "DELETE" }, + ); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to delete data source: ${response.status}`, + ); + } + + return response.json(); +}; + +const useApplyDataSource = () => { + const queryClient = useQueryClient(); + + return useMutation(applyDataSource, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["data-sources-rest"]); + queryClient.invalidateQueries(["data-source-rest"]); + }, + }); +}; + +const useDeleteDataSource = () => { + const queryClient = useQueryClient(); + + return useMutation(deleteDataSource, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["data-sources-rest"]); + queryClient.invalidateQueries(["data-source-rest"]); + }, + }); +}; + +export { useApplyDataSource, useDeleteDataSource }; +export type { ApplyDataSourcePayload, DeleteDataSourcePayload }; diff --git a/ui/src/queries/mutations/useEntityMutations.ts b/ui/src/queries/mutations/useEntityMutations.ts new file mode 100644 index 00000000000..659c367558e --- /dev/null +++ b/ui/src/queries/mutations/useEntityMutations.ts @@ -0,0 +1,92 @@ +import { useMutation, useQueryClient } from "react-query"; + +interface ApplyEntityPayload { + name: string; + project: string; + join_key?: string; + value_type?: number; + description?: string; + tags?: Record; + owner?: string; +} + +interface DeleteEntityPayload { + name: string; + project: string; +} + +interface MutationResult { + name: string; + project: string; + status: string; +} + +const API_BASE = "/api/v1"; + +const applyEntity = async ( + payload: ApplyEntityPayload, +): Promise => { + const response = await fetch(`${API_BASE}/entities`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to apply entity: ${response.status}`, + ); + } + + return response.json(); +}; + +const deleteEntity = async ( + payload: DeleteEntityPayload, +): Promise => { + const response = await fetch( + `${API_BASE}/entities/${encodeURIComponent(payload.name)}?project=${encodeURIComponent(payload.project)}`, + { method: "DELETE" }, + ); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to delete entity: ${response.status}`, + ); + } + + return response.json(); +}; + +const useApplyEntity = () => { + const queryClient = useQueryClient(); + + return useMutation(applyEntity, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["entities-rest"]); + queryClient.invalidateQueries(["entity-rest"]); + }, + }); +}; + +const useDeleteEntity = () => { + const queryClient = useQueryClient(); + + return useMutation(deleteEntity, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["entities-rest"]); + queryClient.invalidateQueries(["entity-rest"]); + }, + }); +}; + +export { useApplyEntity, useDeleteEntity }; +export type { ApplyEntityPayload, DeleteEntityPayload }; diff --git a/ui/src/queries/mutations/useFeatureViewMutations.ts b/ui/src/queries/mutations/useFeatureViewMutations.ts new file mode 100644 index 00000000000..6ca31208093 --- /dev/null +++ b/ui/src/queries/mutations/useFeatureViewMutations.ts @@ -0,0 +1,101 @@ +import { useMutation, useQueryClient } from "react-query"; + +interface FeaturePayload { + name: string; + value_type: number; + description?: string; +} + +interface ApplyFeatureViewPayload { + name: string; + project: string; + entities?: string[]; + features?: FeaturePayload[]; + batch_source?: string; + ttl_seconds?: number; + online?: boolean; + description?: string; + tags?: Record; + owner?: string; +} + +interface DeleteFeatureViewPayload { + name: string; + project: string; +} + +interface MutationResult { + name: string; + project: string; + status: string; +} + +const API_BASE = "/api/v1"; + +const applyFeatureView = async ( + payload: ApplyFeatureViewPayload, +): Promise => { + const response = await fetch(`${API_BASE}/feature_views`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to apply feature view: ${response.status}`, + ); + } + + return response.json(); +}; + +const deleteFeatureView = async ( + payload: DeleteFeatureViewPayload, +): Promise => { + const response = await fetch( + `${API_BASE}/feature_views/${encodeURIComponent(payload.name)}?project=${encodeURIComponent(payload.project)}`, + { method: "DELETE" }, + ); + + if (!response.ok) { + const error = await response + .json() + .catch(() => ({ detail: response.statusText })); + throw new Error( + error.detail || `Failed to delete feature view: ${response.status}`, + ); + } + + return response.json(); +}; + +const useApplyFeatureView = () => { + const queryClient = useQueryClient(); + + return useMutation(applyFeatureView, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["feature-views-rest"]); + queryClient.invalidateQueries(["feature-view-rest"]); + }, + }); +}; + +const useDeleteFeatureView = () => { + const queryClient = useQueryClient(); + + return useMutation(deleteFeatureView, { + onSuccess: () => { + queryClient.invalidateQueries(["rest"]); + queryClient.invalidateQueries(["feature-views-rest"]); + queryClient.invalidateQueries(["feature-view-rest"]); + }, + }); +}; + +export { useApplyFeatureView, useDeleteFeatureView }; +export type { ApplyFeatureViewPayload, DeleteFeatureViewPayload }; diff --git a/ui/src/queries/restApi.ts b/ui/src/queries/restApi.ts new file mode 100644 index 00000000000..f3734962a00 --- /dev/null +++ b/ui/src/queries/restApi.ts @@ -0,0 +1,19 @@ +const API_BASE = "/api/v1"; + +export async function fetchApi( + path: string, + params?: Record, +): Promise { + const url = new URL(`${API_BASE}${path}`, window.location.origin); + if (params) { + Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); + } + const res = await fetch(url.toString(), { + headers: { "Content-Type": "application/json" }, + }); + if (!res.ok) { + const body = await res.json().catch(() => ({ detail: res.statusText })); + throw new Error(body.detail || `API error: ${res.status}`); + } + return res.json(); +} diff --git a/ui/src/queries/restApiClient.ts b/ui/src/queries/restApiClient.ts new file mode 100644 index 00000000000..4cf2cb64bdd --- /dev/null +++ b/ui/src/queries/restApiClient.ts @@ -0,0 +1,40 @@ +import type { FetchOptions } from "../contexts/DataModeContext"; + +class RestApiError extends Error { + status: number; + constructor(message: string, status: number) { + super(message); + this.name = "RestApiError"; + this.status = status; + } +} + +const restFetch = async ( + baseUrl: string, + path: string, + fetchOptions?: FetchOptions, +): Promise => { + const url = `${baseUrl}${path}`; + const headers: Record = { + Accept: "application/json", + ...fetchOptions?.headers, + }; + + const res = await fetch(url, { + method: "GET", + headers, + credentials: fetchOptions?.credentials, + }); + + if (!res.ok) { + throw new RestApiError( + `REST API error: ${res.status} ${res.statusText}`, + res.status, + ); + } + + return res.json(); +}; + +export default restFetch; +export { RestApiError }; diff --git a/ui/src/queries/useLoadDataSourcesREST.ts b/ui/src/queries/useLoadDataSourcesREST.ts new file mode 100644 index 00000000000..5d3890cc503 --- /dev/null +++ b/ui/src/queries/useLoadDataSourcesREST.ts @@ -0,0 +1,41 @@ +import { useQuery } from "react-query"; +import { fetchApi } from "./restApi"; + +interface DataSourceListResponse { + dataSources: any[]; + pagination: Record; + relationships?: Record; +} + +const useLoadDataSourcesREST = (project: string) => { + return useQuery( + ["data-sources-rest", project], + () => + fetchApi("/data_sources", { + project, + allow_cache: "false", + }), + { + enabled: !!project, + staleTime: 30000, + }, + ); +}; + +const useLoadDataSourceREST = (name: string, project: string) => { + return useQuery( + ["data-source-rest", name, project], + () => + fetchApi(`/data_sources/${encodeURIComponent(name)}`, { + project, + include_relationships: "true", + allow_cache: "false", + }), + { + enabled: !!name && !!project, + staleTime: 30000, + }, + ); +}; + +export { useLoadDataSourcesREST, useLoadDataSourceREST }; diff --git a/ui/src/queries/useLoadEntitiesREST.ts b/ui/src/queries/useLoadEntitiesREST.ts new file mode 100644 index 00000000000..7127de656ee --- /dev/null +++ b/ui/src/queries/useLoadEntitiesREST.ts @@ -0,0 +1,41 @@ +import { useQuery } from "react-query"; +import { fetchApi } from "./restApi"; + +interface EntityListResponse { + entities: any[]; + pagination: Record; + relationships?: Record; +} + +const useLoadEntitiesREST = (project: string) => { + return useQuery( + ["entities-rest", project], + () => + fetchApi("/entities", { + project, + allow_cache: "false", + }), + { + enabled: !!project, + staleTime: 30000, + }, + ); +}; + +const useLoadEntityREST = (name: string, project: string) => { + return useQuery( + ["entity-rest", name, project], + () => + fetchApi(`/entities/${encodeURIComponent(name)}`, { + project, + include_relationships: "true", + allow_cache: "false", + }), + { + enabled: !!name && !!project, + staleTime: 30000, + }, + ); +}; + +export { useLoadEntitiesREST, useLoadEntityREST }; diff --git a/ui/src/queries/useLoadFeatureModels.ts b/ui/src/queries/useLoadFeatureModels.ts new file mode 100644 index 00000000000..dc6f97843d0 --- /dev/null +++ b/ui/src/queries/useLoadFeatureModels.ts @@ -0,0 +1,37 @@ +import { useQuery } from "react-query"; + +export interface FeatureModelInfo { + model_name: string; + version: string; + stage: string; + mlflow_url: string; +} + +interface FeatureModelsResponse { + feature_models: Record; + error?: string; +} + +const useLoadFeatureModels = () => { + return useQuery( + "feature-models", + () => { + return fetch("/api/mlflow-feature-models") + .then((res) => { + if (!res.ok) { + return { feature_models: {} }; + } + return res.json(); + }) + .catch(() => { + return { feature_models: {} }; + }); + }, + { + staleTime: 60000, + retry: false, + }, + ); +}; + +export default useLoadFeatureModels; diff --git a/ui/src/queries/useLoadFeatureUsage.ts b/ui/src/queries/useLoadFeatureUsage.ts new file mode 100644 index 00000000000..c797abe88ce --- /dev/null +++ b/ui/src/queries/useLoadFeatureUsage.ts @@ -0,0 +1,35 @@ +import { useQuery } from "react-query"; + +interface FeatureUsageEntry { + run_count: number; + last_used: number | null; + models: string[]; +} + +interface FeatureUsageResponse { + feature_usage: Record; + mlflow_enabled?: boolean; + error?: string; +} + +const fetchFeatureUsage = async (): Promise => { + const response = await fetch("/api/mlflow-feature-usage"); + if (!response.ok) { + throw new Error(`Failed to fetch feature usage: ${response.statusText}`); + } + return response.json(); +}; + +const useLoadFeatureUsage = () => { + return useQuery( + "mlflowFeatureUsage", + fetchFeatureUsage, + { + staleTime: 5 * 60 * 1000, + refetchOnWindowFocus: false, + }, + ); +}; + +export default useLoadFeatureUsage; +export type { FeatureUsageEntry, FeatureUsageResponse }; diff --git a/ui/src/queries/useLoadFeatureViewsREST.ts b/ui/src/queries/useLoadFeatureViewsREST.ts new file mode 100644 index 00000000000..0b67b960e11 --- /dev/null +++ b/ui/src/queries/useLoadFeatureViewsREST.ts @@ -0,0 +1,41 @@ +import { useQuery } from "react-query"; +import { fetchApi } from "./restApi"; + +interface FeatureViewListResponse { + featureViews: any[]; + pagination: Record; + relationships?: Record; +} + +const useLoadFeatureViewsREST = (project: string) => { + return useQuery( + ["feature-views-rest", project], + () => + fetchApi("/feature_views", { + project, + allow_cache: "false", + }), + { + enabled: !!project, + staleTime: 30000, + }, + ); +}; + +const useLoadFeatureViewREST = (name: string, project: string) => { + return useQuery( + ["feature-view-rest", name, project], + () => + fetchApi(`/feature_views/${encodeURIComponent(name)}`, { + project, + include_relationships: "true", + allow_cache: "false", + }), + { + enabled: !!name && !!project, + staleTime: 30000, + }, + ); +}; + +export { useLoadFeatureViewsREST, useLoadFeatureViewREST }; diff --git a/ui/src/queries/useLoadMlflowRuns.ts b/ui/src/queries/useLoadMlflowRuns.ts new file mode 100644 index 00000000000..041fd41137d --- /dev/null +++ b/ui/src/queries/useLoadMlflowRuns.ts @@ -0,0 +1,52 @@ +import { useQuery } from "react-query"; + +export interface RegisteredModelInfo { + model_name: string; + version: string; + stage: string; + mlflow_url: string; +} + +export interface MlflowRunData { + run_id: string; + run_name: string; + status: string; + start_time: number; + feature_service: string | null; + feature_views: string[]; + feature_refs: string[]; + retrieval_type: string | null; + entity_count: string | null; + mlflow_url: string; + registered_models: RegisteredModelInfo[]; +} + +interface MlflowRunsResponse { + runs: MlflowRunData[]; + mlflow_uri: string | null; + error?: string; +} + +const useLoadMlflowRuns = () => { + return useQuery( + "mlflow-runs", + () => { + return fetch("/api/mlflow-runs") + .then((res) => { + if (!res.ok) { + return { runs: [], mlflow_uri: null }; + } + return res.json(); + }) + .catch(() => { + return { runs: [], mlflow_uri: null }; + }); + }, + { + staleTime: 30000, + retry: false, + }, + ); +}; + +export default useLoadMlflowRuns; diff --git a/ui/src/queries/useLoadRegistry.ts b/ui/src/queries/useLoadRegistry.ts index e3f5ac87a1d..477f9be3db8 100644 --- a/ui/src/queries/useLoadRegistry.ts +++ b/ui/src/queries/useLoadRegistry.ts @@ -4,18 +4,20 @@ import parseEntityRelationships, { EntityRelation, } from "../parsers/parseEntityRelationships"; import parseIndirectRelationships from "../parsers/parseIndirectRelationships"; -import { feast } from "../protos"; +import { useDataMode } from "../contexts/DataModeContext"; +import restFetch from "./restApiClient"; +import type { FetchOptions } from "../contexts/DataModeContext"; interface FeatureStoreAllData { project: string; description?: string; - objects: feast.core.Registry; + objects: any; relationships: EntityRelation[]; mergedFVMap: Record; mergedFVList: genericFVType[]; indirectRelationships: EntityRelation[]; allFeatures: Feature[]; - permissions?: any[]; // Add permissions field + permissions?: any[]; } interface Feature { @@ -25,251 +27,195 @@ interface Feature { project?: string; } -const useLoadRegistry = (url: string, projectName?: string) => { - return useQuery( - `registry:${url}:${projectName || "all"}`, - () => { - return fetch(url, { - headers: { - "Content-Type": "application/json", - }, - }) - .then((res) => { - const contentType = res.headers.get("content-type"); - if (contentType && contentType.includes("application/json")) { - return res.json(); - } else { - return res.arrayBuffer(); - } - }) - .then((data) => { - let objects; - - if (data instanceof ArrayBuffer) { - objects = feast.core.Registry.decode(new Uint8Array(data)); - } else { - objects = data; - } - // const objects = FeastRegistrySchema.parse(json); - - if (!objects.featureViews) { - objects.featureViews = []; - } - - // Filter objects by project if projectName is provided - // Skip filtering if projectName is "all" (All Projects view) - // Only filter if we detect that the registry contains multiple projects - if (projectName && projectName !== "all") { - // Check if the registry actually has multiple projects - const projectsInRegistry = new Set(); - objects.featureViews?.forEach((fv: any) => { - if (fv?.spec?.project) projectsInRegistry.add(fv.spec.project); - }); - objects.entities?.forEach((entity: any) => { - if (entity?.spec?.project) - projectsInRegistry.add(entity.spec.project); - }); - - // Only apply filtering if there are actually multiple projects in the registry - // OR if the projectName matches one of the projects in the registry - const shouldFilter = - projectsInRegistry.size > 1 || - projectsInRegistry.has(projectName); - - if (shouldFilter && projectsInRegistry.has(projectName)) { - if (objects.featureViews) { - objects.featureViews = objects.featureViews.filter( - (fv: any) => fv?.spec?.project === projectName, - ); - } - if (objects.entities) { - objects.entities = objects.entities.filter( - (entity: any) => entity?.spec?.project === projectName, - ); - } - if (objects.dataSources) { - objects.dataSources = objects.dataSources.filter( - (ds: any) => ds?.project === projectName, - ); - } - if (objects.featureServices) { - objects.featureServices = objects.featureServices.filter( - (fs: any) => fs?.spec?.project === projectName, - ); - } - if (objects.onDemandFeatureViews) { - objects.onDemandFeatureViews = - objects.onDemandFeatureViews.filter( - (odfv: any) => odfv?.spec?.project === projectName, - ); - } - if (objects.streamFeatureViews) { - objects.streamFeatureViews = objects.streamFeatureViews.filter( - (sfv: any) => sfv?.spec?.project === projectName, - ); - } - if (objects.savedDatasets) { - objects.savedDatasets = objects.savedDatasets.filter( - (sd: any) => sd?.spec?.project === projectName, - ); - } - if (objects.validationReferences) { - objects.validationReferences = - objects.validationReferences.filter( - (vr: any) => vr?.project === projectName, - ); - } - if (objects.permissions) { - objects.permissions = objects.permissions.filter( - (perm: any) => - perm?.spec?.project === projectName || !perm?.spec?.project, - ); - } - } - } - - if ( - process.env.NODE_ENV === "test" && - objects.featureViews.length === 0 - ) { - try { - const fs = require("fs"); - const path = require("path"); - const { feast } = require("../protos"); - - const registry = fs.readFileSync( - path.resolve(__dirname, "../../public/registry.db"), - ); - const parsedRegistry = feast.core.Registry.decode(registry); - - if ( - parsedRegistry.featureViews && - parsedRegistry.featureViews.length > 0 - ) { - objects.featureViews = parsedRegistry.featureViews; - } - } catch (e) { - console.error("Error loading test registry:", e); - } - } - - const { mergedFVMap, mergedFVList } = mergedFVTypes(objects); - - const relationships = parseEntityRelationships(objects); - - // Only contains Entity -> FS or DS -> FS relationships - const indirectRelationships = parseIndirectRelationships( - relationships, - objects, - ); +// --------------------------------------------------------------------------- +// Shared post-processing (used by the bulk REST fetch) +// --------------------------------------------------------------------------- + +const assembleFeatureStoreData = ( + objects: any, + projectName?: string, +): FeatureStoreAllData => { + const { mergedFVMap, mergedFVList } = mergedFVTypes(objects); + const relationships = parseEntityRelationships(objects); + const indirectRelationships = parseIndirectRelationships( + relationships, + objects, + ); - // console.log({ - // objects, - // mergedFVMap, - // mergedFVList, - // relationships, - // indirectRelationships, - // }); - const allFeatures: Feature[] = - objects.featureViews?.flatMap( - (fv: any) => - fv?.spec?.features?.map((feature: any) => ({ - name: feature.name ?? "Unknown", - featureView: fv?.spec?.name || "Unknown FeatureView", - type: - feature.valueType != null - ? feast.types.ValueType.Enum[feature.valueType] - : "Unknown Type", - project: fv?.spec?.project, // Include project from parent feature view - })) || [], - ) || []; + const allFeatures: Feature[] = + objects.featureViews?.flatMap( + (fv: any) => + fv?.spec?.features?.map((feature: any) => ({ + name: feature.name ?? "Unknown", + featureView: fv?.spec?.name || "Unknown FeatureView", + type: + feature.valueType != null + ? typeof feature.valueType === "number" + ? String(feature.valueType) + : feature.valueType + : "Unknown Type", + project: fv?.spec?.project || fv?.project, + })) || [], + ) || []; + + let resolvedProjectName: string = + projectName === "all" + ? "All Projects" + : projectName || + (objects.projects && + objects.projects.length > 0 && + objects.projects[0].spec && + objects.projects[0].spec.name + ? objects.projects[0].spec.name + : objects.project + ? objects.project + : "default"); + + let projectDescription: string | undefined; + if (projectName === "all") { + projectDescription = "View data across all projects"; + } else if (objects.projects && objects.projects.length > 0) { + const currentProject = objects.projects.find( + (p: any) => p?.spec?.name === resolvedProjectName, + ); + if (currentProject?.spec) { + projectDescription = currentProject.spec.description; + } + } + + return { + project: resolvedProjectName, + description: projectDescription, + objects, + mergedFVMap, + mergedFVList, + relationships, + indirectRelationships, + allFeatures, + permissions: objects.permissions || [], + }; +}; - // Use the provided projectName parameter if available, otherwise try to determine from registry - let resolvedProjectName: string = - projectName === "all" - ? "All Projects" - : projectName || - (process.env.NODE_ENV === "test" - ? "credit_scoring_aws" - : objects.projects && - objects.projects.length > 0 && - objects.projects[0].spec && - objects.projects[0].spec.name - ? objects.projects[0].spec.name - : objects.project - ? objects.project - : "credit_scoring_aws"); +// --------------------------------------------------------------------------- +// REST fetch strategy +// --------------------------------------------------------------------------- + +const fetchREST = async ( + apiBaseUrl: string, + projectName?: string, + fetchOptions?: FetchOptions, +): Promise => { + const projectParam = + projectName && projectName !== "all" + ? `?project=${encodeURIComponent(projectName)}` + : ""; + const useAllEndpoint = !projectParam; + + const [ + entitiesResp, + featureViewsResp, + labelViewsResp, + featureServicesResp, + dataSourcesResp, + savedDatasetsResp, + projectsResp, + ] = await Promise.all([ + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/entities/all?include_relationships=true" + : `/entities${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/feature_views/all?include_relationships=true" + : `/feature_views${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/label_views/all?include_relationships=true" + : `/label_views${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/feature_services/all?include_relationships=true" + : `/feature_services${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/data_sources/all?include_relationships=true" + : `/data_sources${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch( + apiBaseUrl, + useAllEndpoint + ? "/saved_datasets/all?include_relationships=true" + : `/saved_datasets${projectParam}&include_relationships=true`, + fetchOptions, + ), + restFetch(apiBaseUrl, "/projects", fetchOptions), + ]); + + const entities = entitiesResp.entities || []; + const allFeatureViews = featureViewsResp.featureViews || []; + const labelViews: any[] = labelViewsResp.featureViews || []; + const featureServices = featureServicesResp.featureServices || []; + const dataSources = dataSourcesResp.dataSources || []; + const savedDatasets = savedDatasetsResp.savedDatasets || []; + const projects = projectsResp.projects || []; + + const featureViews: any[] = []; + const onDemandFeatureViews: any[] = []; + const streamFeatureViews: any[] = []; + + for (const fv of allFeatureViews) { + const fvType = fv.type; + if (fvType === "onDemandFeatureView") { + onDemandFeatureViews.push(fv); + } else if (fvType === "streamFeatureView") { + streamFeatureViews.push(fv); + } else { + featureViews.push(fv); + } + } + + const objects: any = { + entities, + featureViews, + onDemandFeatureViews, + streamFeatureViews, + labelViews, + featureServices, + dataSources, + savedDatasets, + projects, + }; + + return assembleFeatureStoreData(objects, projectName); +}; - let projectDescription = undefined; +// --------------------------------------------------------------------------- +// Public hook +// --------------------------------------------------------------------------- - // Find project description from the projects array - if (projectName === "all") { - projectDescription = "View data across all projects"; - } else if (objects.projects && objects.projects.length > 0) { - const currentProject = objects.projects.find( - (p: any) => p?.spec?.name === resolvedProjectName, - ); - if (currentProject?.spec) { - projectDescription = currentProject.spec.description; - } - } +const useLoadRegistry = (url: string, projectName?: string) => { + const { fetchOptions } = useDataMode(); - return { - project: resolvedProjectName, - description: projectDescription, - objects, - mergedFVMap, - mergedFVList, - relationships, - indirectRelationships, - allFeatures, - permissions: - objects.permissions && objects.permissions.length > 0 - ? objects.permissions - : [ - { - spec: { - name: "zipcode-features-reader", - types: [2], // FeatureView - name_patterns: ["zipcode_features"], - policy: { roles: ["analyst", "data_scientist"] }, - actions: [1, 4, 5], // DESCRIBE, READ_ONLINE, READ_OFFLINE - }, - }, - { - spec: { - name: "zipcode-source-writer", - types: [7], // FileSource - name_patterns: ["zipcode"], - policy: { roles: ["admin", "data_engineer"] }, - actions: [0, 2, 7], // CREATE, UPDATE, WRITE_OFFLINE - }, - }, - { - spec: { - name: "credit-score-v1-reader", - types: [6], // FeatureService - name_patterns: ["credit_score_v1"], - policy: { roles: ["model_user", "data_scientist"] }, - actions: [1, 4], // DESCRIBE, READ_ONLINE - }, - }, - { - spec: { - name: "risky-features-reader", - types: [2, 6], // FeatureView, FeatureService - name_patterns: [], - required_tags: { stage: "prod" }, - policy: { roles: ["trusted_analyst"] }, - actions: [5], // READ_OFFLINE - }, - }, - ], - }; - }); - }, + return useQuery( + ["registry-rest-bulk", url, projectName || "all"], + () => fetchREST(url, projectName, fetchOptions), { - staleTime: Infinity, // Given that we are reading from a registry dump, this seems reasonable for now. + staleTime: 30_000, + enabled: !!url, }, ); }; diff --git a/ui/src/queries/useMonitoringApi.ts b/ui/src/queries/useMonitoringApi.ts new file mode 100644 index 00000000000..c4f8f7636a6 --- /dev/null +++ b/ui/src/queries/useMonitoringApi.ts @@ -0,0 +1,303 @@ +import { useContext } from "react"; +import { useQuery, useMutation, useQueryClient } from "react-query"; +import MonitoringContext from "../contexts/MonitoringContext"; +import { useDataMode } from "../contexts/DataModeContext"; +import type { FetchOptions } from "../contexts/DataModeContext"; + +interface FeatureMetric { + project_id: string; + feature_view_name: string; + feature_name: string; + metric_date: string; + granularity: string; + data_source_type: string; + computed_at: string; + is_baseline: boolean; + feature_type: string; + row_count: number; + null_count: number; + null_rate: number; + mean: number | null; + stddev: number | null; + min_val: number | null; + max_val: number | null; + p50: number | null; + p75: number | null; + p90: number | null; + p95: number | null; + p99: number | null; + histogram: NumericHistogram | CategoricalHistogram | null; +} + +interface NumericHistogram { + bins: number[]; + counts: number[]; + bin_width: number; +} + +interface CategoricalHistogram { + values: { value: string; count: number }[]; + other_count: number; + unique_count: number; +} + +interface FeatureViewMetric { + project_id: string; + feature_view_name: string; + metric_date: string; + granularity: string; + data_source_type: string; + computed_at: string; + is_baseline: boolean; + total_row_count: number; + total_features: number; + features_with_nulls: number; + avg_null_rate: number; + max_null_rate: number; +} + +interface FeatureServiceMetric { + project_id: string; + feature_service_name: string; + metric_date: string; + granularity: string; + data_source_type: string; + computed_at: string; + is_baseline: boolean; + total_feature_views: number; + total_features: number; + avg_null_rate: number; + max_null_rate: number; +} + +interface MonitoringFilters { + project: string; + feature_view_name?: string; + feature_name?: string; + feature_service_name?: string; + granularity?: string; + data_source_type?: string; + start_date?: string; + end_date?: string; + is_baseline?: boolean; +} + +const toQueryParams = ( + filters: MonitoringFilters, +): Record => { + return { + project: filters.project, + feature_view_name: filters.feature_view_name, + feature_name: filters.feature_name, + feature_service_name: filters.feature_service_name, + granularity: filters.granularity, + data_source_type: filters.data_source_type, + start_date: filters.start_date, + end_date: filters.end_date, + is_baseline: filters.is_baseline ? "true" : undefined, + }; +}; + +const buildQueryString = (params: Record) => { + const entries = Object.entries(params).filter( + ([, v]) => v !== undefined && v !== "", + ); + if (entries.length === 0) return ""; + return ( + "?" + entries.map(([k, v]) => `${k}=${encodeURIComponent(v!)}`).join("&") + ); +}; + +const fetchMonitoring = async ( + baseUrl: string, + path: string, + params: Record, + fetchOptions?: FetchOptions, +): Promise => { + const qs = buildQueryString(params); + const res = await fetch(`${baseUrl}${path}${qs}`, { + method: "GET", + headers: { + Accept: "application/json", + ...fetchOptions?.headers, + }, + credentials: fetchOptions?.credentials, + }); + if (!res.ok) { + throw new Error(`Failed to fetch ${path}: ${res.status} ${res.statusText}`); + } + const text = await res.text(); + const sanitized = text + .replace(/:\s*NaN/g, ": null") + .replace(/:\s*Infinity/g, ": null") + .replace(/:\s*-Infinity/g, ": null"); + return JSON.parse(sanitized); +}; + +const STALE_TIME = 30_000; + +const useFeatureMetrics = (filters: MonitoringFilters) => { + const { apiBaseUrl } = useContext(MonitoringContext); + const { fetchOptions } = useDataMode(); + const path = filters.is_baseline + ? "/monitoring/metrics/baseline" + : "/monitoring/metrics/features"; + return useQuery( + ["monitoring-features", filters], + () => + fetchMonitoring( + apiBaseUrl, + path, + toQueryParams(filters), + fetchOptions, + ), + { staleTime: STALE_TIME, retry: 1 }, + ); +}; + +const aggregateToFeatureViewMetrics = ( + features: FeatureMetric[], +): FeatureViewMetric[] => { + const grouped = new Map(); + for (const f of features) { + const key = f.feature_view_name; + if (!grouped.has(key)) grouped.set(key, []); + grouped.get(key)!.push(f); + } + return Array.from(grouped.entries()).map(([fvName, feats]) => { + const nullRates = feats.map((f) => f.null_rate ?? 0); + const maxRowCount = Math.max(...feats.map((f) => f.row_count ?? 0)); + return { + project_id: feats[0].project_id, + feature_view_name: fvName, + metric_date: feats[0].metric_date, + granularity: feats[0].granularity, + data_source_type: feats[0].data_source_type, + computed_at: feats[0].computed_at, + is_baseline: feats[0].is_baseline, + total_row_count: maxRowCount, + total_features: feats.length, + features_with_nulls: feats.filter((f) => (f.null_count ?? 0) > 0).length, + avg_null_rate: + nullRates.length > 0 + ? nullRates.reduce((a, b) => a + b, 0) / nullRates.length + : 0, + max_null_rate: nullRates.length > 0 ? Math.max(...nullRates) : 0, + }; + }); +}; + +const useFeatureViewMetrics = (filters: MonitoringFilters) => { + const { apiBaseUrl } = useContext(MonitoringContext); + const { fetchOptions } = useDataMode(); + const isBaseline = !!filters.is_baseline; + return useQuery( + ["monitoring-feature-views", filters], + async () => { + if (isBaseline) { + const features = await fetchMonitoring( + apiBaseUrl, + "/monitoring/metrics/baseline", + toQueryParams(filters), + fetchOptions, + ); + return aggregateToFeatureViewMetrics(features); + } + return fetchMonitoring( + apiBaseUrl, + "/monitoring/metrics/feature_views", + toQueryParams(filters), + fetchOptions, + ); + }, + { staleTime: STALE_TIME, retry: 1 }, + ); +}; + +const useFeatureServiceMetrics = (filters: MonitoringFilters) => { + const { apiBaseUrl } = useContext(MonitoringContext); + const { fetchOptions } = useDataMode(); + return useQuery( + ["monitoring-feature-services", filters], + () => + fetchMonitoring( + apiBaseUrl, + "/monitoring/metrics/feature_services", + toQueryParams(filters), + fetchOptions, + ), + { staleTime: STALE_TIME, retry: 1 }, + ); +}; + +const useBaselineMetrics = ( + project: string, + featureViewName?: string, + featureName?: string, + dataSourceType?: string, +) => { + const { apiBaseUrl } = useContext(MonitoringContext); + const { fetchOptions } = useDataMode(); + return useQuery( + ["monitoring-baseline", project, featureViewName, featureName], + () => + fetchMonitoring( + apiBaseUrl, + "/monitoring/metrics/baseline", + { + project, + feature_view_name: featureViewName, + feature_name: featureName, + data_source_type: dataSourceType, + }, + fetchOptions, + ), + { staleTime: STALE_TIME, retry: 1 }, + ); +}; + +const useComputeMetrics = () => { + const { apiBaseUrl } = useContext(MonitoringContext); + const { fetchOptions } = useDataMode(); + const queryClient = useQueryClient(); + return useMutation( + async (body: { project: string; feature_view_name?: string }) => { + const res = await fetch(`${apiBaseUrl}/monitoring/auto_compute`, { + method: "POST", + headers: { + "Content-Type": "application/json", + ...fetchOptions?.headers, + }, + credentials: fetchOptions?.credentials, + body: JSON.stringify(body), + }); + if (!res.ok) { + throw new Error(`Failed to trigger compute: ${res.status}`); + } + return res.json(); + }, + { + onSuccess: () => { + queryClient.invalidateQueries("monitoring-features"); + queryClient.invalidateQueries("monitoring-feature-views"); + queryClient.invalidateQueries("monitoring-feature-services"); + }, + }, + ); +}; + +export { + useFeatureMetrics, + useFeatureViewMetrics, + useFeatureServiceMetrics, + useBaselineMetrics, + useComputeMetrics, +}; +export type { + FeatureMetric, + FeatureViewMetric, + FeatureServiceMetric, + NumericHistogram, + CategoricalHistogram, + MonitoringFilters, +}; diff --git a/ui/src/queries/useResourceQuery.ts b/ui/src/queries/useResourceQuery.ts new file mode 100644 index 00000000000..857eeefc131 --- /dev/null +++ b/ui/src/queries/useResourceQuery.ts @@ -0,0 +1,222 @@ +import { useContext } from "react"; +import { useQuery, UseQueryResult } from "react-query"; +import RegistryPathContext from "../contexts/RegistryPathContext"; +import { useDataMode } from "../contexts/DataModeContext"; +import restFetch from "./restApiClient"; +import { FEAST_FV_TYPES, genericFVType } from "../parsers/mergedFVTypes"; + +interface ResourceQueryOptions { + resourceType: string; + project?: string; + restPath: string; + restSelect?: (data: any) => T | undefined; + enabled?: boolean; +} + +/** + * Generic hook for fetching a specific resource slice via REST API. + * + * Each caller fires its own lightweight endpoint request, and react-query + * deduplicates identical keys automatically. + */ +function useResourceQuery({ + resourceType, + project, + restPath, + restSelect, + enabled = true, +}: ResourceQueryOptions): UseQueryResult { + const registryUrl = useContext(RegistryPathContext); + const { fetchOptions } = useDataMode(); + + return useQuery( + ["rest", resourceType, registryUrl, project || "all"], + () => restFetch(registryUrl, restPath, fetchOptions), + { + enabled: !!registryUrl && enabled, + staleTime: 30_000, + select: restSelect, + }, + ); +} + +// --------------------------------------------------------------------------- +// REST endpoint path builders +// --------------------------------------------------------------------------- + +function entityListPath(project?: string): string { + if (project && project !== "all") { + return `/entities?project=${encodeURIComponent(project)}&include_relationships=true`; + } + return "/entities/all?limit=100&include_relationships=true"; +} + +function entityDetailPath(name: string, project: string): string { + return `/entities/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}&include_relationships=true`; +} + +function featureViewListPath(project?: string): string { + if (project && project !== "all") { + return `/feature_views?project=${encodeURIComponent(project)}&include_relationships=true`; + } + return "/feature_views/all?limit=100&include_relationships=true"; +} + +function featureViewDetailPath(name: string, project: string): string { + return `/feature_views/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}&include_relationships=true`; +} + +function featureServiceListPath(project?: string): string { + if (project && project !== "all") { + return `/feature_services?project=${encodeURIComponent(project)}&include_relationships=true`; + } + return "/feature_services/all?limit=100&include_relationships=true"; +} + +function featureServiceDetailPath(name: string, project: string): string { + return `/feature_services/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}&include_relationships=true`; +} + +function dataSourceListPath(project?: string): string { + if (project && project !== "all") { + return `/data_sources?project=${encodeURIComponent(project)}&include_relationships=true`; + } + return "/data_sources/all?limit=100&include_relationships=true"; +} + +function dataSourceDetailPath(name: string, project: string): string { + return `/data_sources/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}&include_relationships=true`; +} + +function savedDatasetListPath(project?: string): string { + if (project && project !== "all") { + return `/saved_datasets?project=${encodeURIComponent(project)}`; + } + return "/saved_datasets/all?limit=100"; +} + +function savedDatasetDetailPath(name: string, project: string): string { + return `/saved_datasets/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}`; +} + +function labelViewListPath(project?: string): string { + if (project && project !== "all") { + return `/label_views?project=${encodeURIComponent(project)}&include_relationships=true`; + } + return "/label_views/all?limit=100&include_relationships=true"; +} + +function labelViewDetailPath(name: string, project: string): string { + return `/label_views/${encodeURIComponent(name)}?project=${encodeURIComponent(project)}&include_relationships=true`; +} + +function featuresListPath(project?: string): string { + if (project && project !== "all") { + return `/features?project=${encodeURIComponent(project)}`; + } + return "/features/all?limit=100"; +} + +function featureDetailPath( + featureViewName: string, + featureName: string, + project: string, +): string { + return `/features/${encodeURIComponent(featureViewName)}/${encodeURIComponent(featureName)}?project=${encodeURIComponent(project)}`; +} + +// --------------------------------------------------------------------------- +// REST response → mergedFVList converter +// --------------------------------------------------------------------------- + +function restFeatureViewsToMergedList(resp: any): genericFVType[] { + const featureViews = resp?.featureViews || []; + return featureViews + .filter((fv: any) => fv.type !== "labelView") + .map((fv: any) => { + const fvType = fv.type; + if (fvType === "onDemandFeatureView") { + return { + name: fv.spec?.name, + type: FEAST_FV_TYPES.ondemand, + features: fv.spec?.features || [], + object: fv, + }; + } + if (fvType === "streamFeatureView") { + return { + name: fv.spec?.name, + type: FEAST_FV_TYPES.stream, + features: fv.spec?.features || [], + object: fv, + }; + } + return { + name: fv.spec?.name, + type: FEAST_FV_TYPES.regular, + features: fv.spec?.features || [], + object: fv, + }; + }); +} + +function restLabelViewsFromResponse(resp: any): any[] { + const featureViews = resp?.featureViews || []; + return featureViews.filter((fv: any) => fv.type === "labelView"); +} + +function restFeatureViewDetailToGeneric(resp: any): genericFVType | undefined { + if (!resp || !resp.spec) return undefined; + const fvType = resp.type; + if (fvType === "onDemandFeatureView") { + return { + name: resp.spec.name, + type: FEAST_FV_TYPES.ondemand, + features: resp.spec.features || [], + object: resp, + }; + } + if (fvType === "streamFeatureView") { + return { + name: resp.spec.name, + type: FEAST_FV_TYPES.stream, + features: resp.spec.features || [], + object: resp, + }; + } + if (fvType === "labelView") { + return { + name: resp.spec.name, + type: FEAST_FV_TYPES.label, + features: resp.spec.features || [], + object: resp, + }; + } + return { + name: resp.spec.name, + type: FEAST_FV_TYPES.regular, + features: resp.spec.features || [], + object: resp, + }; +} + +export default useResourceQuery; +export { + entityListPath, + entityDetailPath, + featureViewListPath, + featureViewDetailPath, + featureServiceListPath, + featureServiceDetailPath, + dataSourceListPath, + dataSourceDetailPath, + savedDatasetListPath, + savedDatasetDetailPath, + labelViewListPath, + labelViewDetailPath, + featuresListPath, + featureDetailPath, + restFeatureViewsToMergedList, + restFeatureViewDetailToGeneric, + restLabelViewsFromResponse, +}; diff --git a/ui/src/setupProxy.js b/ui/src/setupProxy.js new file mode 100644 index 00000000000..94762f63557 --- /dev/null +++ b/ui/src/setupProxy.js @@ -0,0 +1,332 @@ +const fs = require("fs"); +const path = require("path"); +const express = require("express"); +const { feast } = require("./protos"); + +const registryBuf = fs.readFileSync( + path.resolve(__dirname, "../public/registry.db"), +); +const parsedRegistry = feast.core.Registry.decode(registryBuf); +const projectsList = JSON.parse( + fs.readFileSync(path.resolve(__dirname, "../public/projects-list.json")), +); + +const toJSON = (obj) => (obj && obj.toJSON ? obj.toJSON() : obj); + +const withType = (type) => (fv) => ({ + ...toJSON(fv), + type, +}); + +const state = { + entities: (parsedRegistry.entities || []).map(toJSON), + featureViews: (parsedRegistry.featureViews || []).map( + withType("featureView"), + ), + onDemandFeatureViews: (parsedRegistry.onDemandFeatureViews || []).map( + withType("onDemandFeatureView"), + ), + streamFeatureViews: (parsedRegistry.streamFeatureViews || []).map( + withType("streamFeatureView"), + ), + featureServices: (parsedRegistry.featureServices || []).map(toJSON), + dataSources: (parsedRegistry.dataSources || []).map(toJSON), + savedDatasets: (parsedRegistry.savedDatasets || []).map(toJSON), + projects: (parsedRegistry.projects || []).map(toJSON), +}; + +const allFeatureViews = () => [ + ...state.featureViews, + ...state.onDemandFeatureViews, + ...state.streamFeatureViews, +]; + +const objectProject = (obj) => obj?.spec?.project || obj?.project; + +const filterByProject = (items, project) => { + if (!project || project === "all") return items; + return items.filter((item) => objectProject(item) === project); +}; + +const allFeatures = (project) => + filterByProject(allFeatureViews(), project).flatMap((fv) => + (fv?.spec?.features || []).map((feature) => ({ + name: feature.name, + featureViewName: fv.spec?.name, + valueType: feature.valueType, + project: fv.spec?.project, + })), + ); + +const responseList = (res, key, items) => { + res.json({ + [key]: items, + pagination: {}, + relationships: {}, + }); +}; + +const findByName = (items, name) => + items.find((item) => item?.spec?.name === name || item?.name === name); + +const entityPayloadToResource = (payload) => ({ + spec: { + name: payload.name, + joinKey: payload.join_key || payload.name, + valueType: payload.value_type, + description: payload.description || "", + tags: payload.tags || {}, + owner: payload.owner || "", + project: payload.project, + }, + meta: {}, +}); + +const dataSourcePayloadToResource = (payload) => ({ + name: payload.name, + type: payload.type, + timestampField: payload.timestamp_field, + fieldMapping: payload.field_mapping || {}, + description: payload.description || "", + tags: payload.tags || {}, + owner: payload.owner || "", + project: payload.project, + fileOptions: payload.file_options, + bigqueryOptions: payload.bigquery_options, + snowflakeOptions: payload.snowflake_options, + redshiftOptions: payload.redshift_options, + kafkaOptions: payload.kafka_options, + sparkOptions: payload.spark_options, +}); + +const featureViewPayloadToResource = (payload) => ({ + spec: { + name: payload.name, + description: payload.description || "", + owner: payload.owner || "", + entities: payload.entities || [], + features: payload.features || [], + ttl: payload.ttl, + online: payload.online, + tags: payload.tags || {}, + project: payload.project, + batchSource: payload.batch_source + ? { name: payload.batch_source } + : undefined, + }, + meta: {}, + type: "featureView", +}); + +module.exports = function setupProxy(app) { + app.use("/api/v1", express.json()); + + app.get("/projects-list.json", (_req, res) => { + res.json({ + ...projectsList, + projects: projectsList.projects.map((project) => + project.id === "credit_scoring_aws" + ? { ...project, registryPath: "/api/v1" } + : project, + ), + }); + }); + + app.get("/api/v1/entities/all", (_req, res) => + responseList(res, "entities", state.entities), + ); + app.get("/api/v1/feature_views/all", (_req, res) => + responseList(res, "featureViews", allFeatureViews()), + ); + app.get("/api/v1/feature_services/all", (_req, res) => + responseList(res, "featureServices", state.featureServices), + ); + app.get("/api/v1/data_sources/all", (_req, res) => + responseList(res, "dataSources", state.dataSources), + ); + app.get("/api/v1/saved_datasets/all", (_req, res) => + responseList(res, "savedDatasets", state.savedDatasets), + ); + app.get("/api/v1/features/all", (_req, res) => + responseList(res, "features", allFeatures()), + ); + app.get("/api/v1/label_views/all", (_req, res) => + responseList(res, "featureViews", []), + ); + + app.get("/api/v1/entities", (req, res) => + responseList( + res, + "entities", + filterByProject(state.entities, req.query.project), + ), + ); + app.get("/api/v1/feature_views", (req, res) => + responseList( + res, + "featureViews", + filterByProject(allFeatureViews(), req.query.project), + ), + ); + app.get("/api/v1/feature_services", (req, res) => + responseList( + res, + "featureServices", + filterByProject(state.featureServices, req.query.project), + ), + ); + app.get("/api/v1/data_sources", (req, res) => + responseList( + res, + "dataSources", + filterByProject(state.dataSources, req.query.project), + ), + ); + app.get("/api/v1/saved_datasets", (req, res) => + responseList( + res, + "savedDatasets", + filterByProject(state.savedDatasets, req.query.project), + ), + ); + app.get("/api/v1/features", (req, res) => + responseList(res, "features", allFeatures(req.query.project)), + ); + app.get("/api/v1/label_views", (_req, res) => + responseList(res, "featureViews", []), + ); + app.get("/api/v1/labels", (_req, res) => responseList(res, "labels", [])); + app.get("/api/v1/projects", (_req, res) => + responseList(res, "projects", state.projects), + ); + app.get("/api/v1/permissions", (_req, res) => + responseList(res, "permissions", []), + ); + app.get("/api/v1/metrics/:type", (_req, res) => res.json({})); + + app.get("/api/v1/entities/:name", (req, res) => { + const entity = findByName(state.entities, req.params.name); + if (!entity) return res.status(404).json({ detail: "Not found" }); + return res.json(entity); + }); + app.get("/api/v1/feature_views/:name", (req, res) => { + const featureView = findByName(allFeatureViews(), req.params.name); + if (!featureView) return res.status(404).json({ detail: "Not found" }); + return res.json(featureView); + }); + app.get("/api/v1/feature_services/:name", (req, res) => { + const featureService = findByName(state.featureServices, req.params.name); + if (!featureService) return res.status(404).json({ detail: "Not found" }); + return res.json(featureService); + }); + app.get("/api/v1/data_sources/:name", (req, res) => { + const dataSource = findByName(state.dataSources, req.params.name); + if (!dataSource) return res.status(404).json({ detail: "Not found" }); + return res.json(dataSource); + }); + app.get("/api/v1/saved_datasets/:name", (req, res) => { + const savedDataset = findByName(state.savedDatasets, req.params.name); + if (!savedDataset) return res.status(404).json({ detail: "Not found" }); + return res.json(savedDataset); + }); + app.get("/api/v1/features/:fvName/:featureName", (req, res) => { + const featureView = findByName(allFeatureViews(), req.params.fvName); + const feature = featureView?.spec?.features?.find( + (f) => f.name === req.params.featureName, + ); + if (!feature) return res.status(404).json({ detail: "Not found" }); + return res.json({ + featureViewName: req.params.fvName, + featureName: req.params.featureName, + feature, + featureView, + }); + }); + + app.post("/api/v1/entities", (req, res) => { + const body = req.body || {}; + const existingIndex = state.entities.findIndex( + (entity) => entity?.spec?.name === body.name, + ); + const entity = entityPayloadToResource(body); + if (existingIndex >= 0) { + state.entities[existingIndex] = entity; + } else { + state.entities.push(entity); + } + res.json({ + name: body.name, + project: body.project, + status: "applied", + }); + }); + + app.post("/api/v1/data_sources", (req, res) => { + const body = req.body || {}; + const existingIndex = state.dataSources.findIndex( + (dataSource) => dataSource?.name === body.name, + ); + const dataSource = dataSourcePayloadToResource(body); + if (existingIndex >= 0) { + state.dataSources[existingIndex] = dataSource; + } else { + state.dataSources.push(dataSource); + } + res.json({ + name: body.name, + project: body.project, + status: "applied", + }); + }); + + app.post("/api/v1/feature_views", (req, res) => { + const body = req.body || {}; + const existingIndex = state.featureViews.findIndex( + (featureView) => featureView?.spec?.name === body.name, + ); + const featureView = featureViewPayloadToResource(body); + if (existingIndex >= 0) { + state.featureViews[existingIndex] = featureView; + } else { + state.featureViews.push(featureView); + } + res.json({ + name: body.name, + project: body.project, + status: "applied", + }); + }); + + app.delete("/api/v1/entities/:name", (req, res) => { + state.entities = state.entities.filter( + (entity) => entity?.spec?.name !== req.params.name, + ); + res.json({ + name: req.params.name, + project: req.query.project, + status: "deleted", + }); + }); + + app.delete("/api/v1/data_sources/:name", (req, res) => { + state.dataSources = state.dataSources.filter( + (dataSource) => dataSource?.name !== req.params.name, + ); + res.json({ + name: req.params.name, + project: req.query.project, + status: "deleted", + }); + }); + + app.delete("/api/v1/feature_views/:name", (req, res) => { + state.featureViews = state.featureViews.filter( + (featureView) => featureView?.spec?.name !== req.params.name, + ); + res.json({ + name: req.params.name, + project: req.query.project, + status: "deleted", + }); + }); +}; diff --git a/ui/src/utils/permissionUtils.ts b/ui/src/utils/permissionUtils.ts index 9caa162ec1c..c4c4cef032e 100644 --- a/ui/src/utils/permissionUtils.ts +++ b/ui/src/utils/permissionUtils.ts @@ -1,5 +1,4 @@ import { FEAST_FCO_TYPES } from "../parsers/types"; -import { feast } from "../protos"; /** * Get permissions for a specific entity diff --git a/ui/src/utils/timestamp.ts b/ui/src/utils/timestamp.ts index 390195f467b..5c85bc0de65 100644 --- a/ui/src/utils/timestamp.ts +++ b/ui/src/utils/timestamp.ts @@ -1,13 +1,20 @@ import Long from "long"; import { google } from "../protos"; -export function toDate(ts: google.protobuf.ITimestamp) { - var seconds: number; - if (ts.seconds instanceof Long) { - seconds = ts.seconds.low; - } else { - seconds = ts.seconds!; +export function toDate(ts: google.protobuf.ITimestamp | string | any): Date { + if (typeof ts === "string") { + return new Date(ts); } - return new Date(seconds * 1000); + if (ts && ts.seconds != null) { + var seconds: number; + if (ts.seconds instanceof Long) { + seconds = ts.seconds.low; + } else { + seconds = ts.seconds; + } + return new Date(seconds * 1000); + } + + return new Date(NaN); } diff --git a/ui/yarn.lock b/ui/yarn.lock index e0fa4f12a72..cca5da3763e 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -4,12 +4,12 @@ "@adobe/css-tools@^4.4.0": version "4.4.4" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.4.tgz#2856c55443d3d461693f32d2b96fb6ea92e1ffa9" + resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz" integrity sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg== "@apideck/better-ajv-errors@^0.3.1": version "0.3.6" - resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" + resolved "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz" integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== dependencies: json-schema "^0.4.0" @@ -18,7 +18,7 @@ "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.8.3": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== dependencies: "@babel/helper-validator-identifier" "^7.27.1" @@ -27,12 +27,12 @@ "@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz" integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.8": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz" integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== dependencies: "@babel/code-frame" "^7.27.1" @@ -53,7 +53,7 @@ "@babel/eslint-parser@^7.16.3": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz#0b8883a4a1c2cbed7b3cd9d7765d80e8f480b9ae" + resolved "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz" integrity sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" @@ -62,7 +62,7 @@ "@babel/generator@^7.28.5", "@babel/generator@^7.7.2": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz" integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== dependencies: "@babel/parser" "^7.28.5" @@ -73,14 +73,14 @@ "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz" integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== dependencies: "@babel/types" "^7.27.3" "@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2": version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz" integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: "@babel/compat-data" "^7.27.2" @@ -91,7 +91,7 @@ "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz" integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" @@ -104,7 +104,7 @@ "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz" integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" @@ -113,7 +113,7 @@ "@babel/helper-define-polyfill-provider@^0.6.5": version "0.6.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz" integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg== dependencies: "@babel/helper-compilation-targets" "^7.27.2" @@ -124,12 +124,12 @@ "@babel/helper-globals@^7.28.0": version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== "@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz" integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: "@babel/traverse" "^7.28.5" @@ -137,7 +137,7 @@ "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz" integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== dependencies: "@babel/traverse" "^7.27.1" @@ -145,7 +145,7 @@ "@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz" integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== dependencies: "@babel/helper-module-imports" "^7.27.1" @@ -154,19 +154,19 @@ "@babel/helper-optimise-call-expression@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz" integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== dependencies: "@babel/types" "^7.27.1" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== "@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz" integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.1" @@ -175,7 +175,7 @@ "@babel/helper-replace-supers@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz" integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA== dependencies: "@babel/helper-member-expression-to-functions" "^7.27.1" @@ -184,7 +184,7 @@ "@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz" integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== dependencies: "@babel/traverse" "^7.27.1" @@ -192,22 +192,22 @@ "@babel/helper-string-parser@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== "@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz" integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== "@babel/helper-validator-option@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== "@babel/helper-wrap-function@^7.27.1": version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz#fe4872092bc1438ffd0ce579e6f699609f9d0a7a" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz" integrity sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g== dependencies: "@babel/template" "^7.27.2" @@ -216,7 +216,7 @@ "@babel/helpers@^7.28.4": version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz" integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== dependencies: "@babel/template" "^7.27.2" @@ -224,14 +224,14 @@ "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz" integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: "@babel/types" "^7.28.5" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz" integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -239,21 +239,21 @@ "@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz" integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz" integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz" integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -262,7 +262,7 @@ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3": version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz#373f6e2de0016f73caf8f27004f61d167743742a" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz" integrity sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -270,7 +270,7 @@ "@babel/plugin-proposal-class-properties@^7.16.0": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" @@ -278,7 +278,7 @@ "@babel/plugin-proposal-decorators@^7.16.4": version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz#419c8acc31088e05a774344c021800f7ddc39bf0" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz" integrity sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg== dependencies: "@babel/helper-create-class-features-plugin" "^7.27.1" @@ -287,7 +287,7 @@ "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: "@babel/helper-plugin-utils" "^7.18.6" @@ -295,7 +295,7 @@ "@babel/plugin-proposal-numeric-separator@^7.16.0": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== dependencies: "@babel/helper-plugin-utils" "^7.18.6" @@ -303,7 +303,7 @@ "@babel/plugin-proposal-optional-chaining@^7.16.0": version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== dependencies: "@babel/helper-plugin-utils" "^7.20.2" @@ -312,7 +312,7 @@ "@babel/plugin-proposal-private-methods@^7.16.0": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" @@ -320,12 +320,12 @@ "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz" integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== "@babel/plugin-proposal-private-property-in-object@^7.16.7", "@babel/plugin-proposal-private-property-in-object@^7.21.11": version "7.21.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz" integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" @@ -335,147 +335,147 @@ "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-bigint@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-class-static-block@^7.14.5": version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-decorators@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz#ee7dd9590aeebc05f9d4c8c0560007b05979a63d" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz" integrity sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-flow@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz#6c83cf0d7d635b716827284b7ecd5aead9237662" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz" integrity sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-import-assertions@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz" integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz" integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-jsx@^7.27.1", "@babel/plugin-syntax-jsx@^7.7.2": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz" integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-private-property-in-object@^7.14.5": version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.27.1", "@babel/plugin-syntax-typescript@^7.7.2": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz" integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz" integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" @@ -483,14 +483,14 @@ "@babel/plugin-transform-arrow-functions@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz" integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-async-generator-functions@^7.28.0": version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz" integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -499,7 +499,7 @@ "@babel/plugin-transform-async-to-generator@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz" integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA== dependencies: "@babel/helper-module-imports" "^7.27.1" @@ -508,21 +508,21 @@ "@babel/plugin-transform-block-scoped-functions@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz" integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-block-scoping@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz" integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-class-properties@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz" integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== dependencies: "@babel/helper-create-class-features-plugin" "^7.27.1" @@ -530,7 +530,7 @@ "@babel/plugin-transform-class-static-block@^7.28.3": version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz#d1b8e69b54c9993bc558203e1f49bfc979bfd852" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz" integrity sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg== dependencies: "@babel/helper-create-class-features-plugin" "^7.28.3" @@ -538,7 +538,7 @@ "@babel/plugin-transform-classes@^7.28.4": version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz" integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" @@ -550,7 +550,7 @@ "@babel/plugin-transform-computed-properties@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz" integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -558,7 +558,7 @@ "@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz" integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -566,7 +566,7 @@ "@babel/plugin-transform-dotall-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz" integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -574,14 +574,14 @@ "@babel/plugin-transform-duplicate-keys@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz" integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz" integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -589,14 +589,14 @@ "@babel/plugin-transform-dynamic-import@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz" integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-explicit-resource-management@^7.28.0": version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a" + resolved "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz" integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -604,21 +604,21 @@ "@babel/plugin-transform-exponentiation-operator@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz" integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-export-namespace-from@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" + resolved "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz" integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-flow-strip-types@^7.16.0": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz#5def3e1e7730f008d683144fb79b724f92c5cdf9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz" integrity sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -626,7 +626,7 @@ "@babel/plugin-transform-for-of@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz" integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -634,7 +634,7 @@ "@babel/plugin-transform-function-name@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz" integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== dependencies: "@babel/helper-compilation-targets" "^7.27.1" @@ -643,35 +643,35 @@ "@babel/plugin-transform-json-strings@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c" + resolved "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz" integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-literals@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz" integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-logical-assignment-operators@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" + resolved "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz" integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-member-expression-literals@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz" integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-amd@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz" integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== dependencies: "@babel/helper-module-transforms" "^7.27.1" @@ -679,7 +679,7 @@ "@babel/plugin-transform-modules-commonjs@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz" integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== dependencies: "@babel/helper-module-transforms" "^7.27.1" @@ -687,7 +687,7 @@ "@babel/plugin-transform-modules-systemjs@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz" integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== dependencies: "@babel/helper-module-transforms" "^7.28.3" @@ -697,7 +697,7 @@ "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz" integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== dependencies: "@babel/helper-module-transforms" "^7.27.1" @@ -705,7 +705,7 @@ "@babel/plugin-transform-named-capturing-groups-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz" integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -713,28 +713,28 @@ "@babel/plugin-transform-new-target@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz" integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" + resolved "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz" integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-numeric-separator@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz" integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-object-rest-spread@^7.28.4": version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz" integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== dependencies: "@babel/helper-compilation-targets" "^7.27.2" @@ -745,7 +745,7 @@ "@babel/plugin-transform-object-super@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz" integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -753,14 +753,14 @@ "@babel/plugin-transform-optional-catch-binding@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz" integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz" integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -768,14 +768,14 @@ "@babel/plugin-transform-parameters@^7.27.7": version "7.27.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz" integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-private-methods@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz" integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA== dependencies: "@babel/helper-create-class-features-plugin" "^7.27.1" @@ -783,7 +783,7 @@ "@babel/plugin-transform-private-property-in-object@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz" integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ== dependencies: "@babel/helper-annotate-as-pure" "^7.27.1" @@ -792,35 +792,35 @@ "@babel/plugin-transform-property-literals@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz" integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-react-constant-elements@^7.21.3": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz#6c6b50424e749a6e48afd14cf7b92f98cb9383f9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz" integrity sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.28.0": version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz" integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-react-jsx-development@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz" integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== dependencies: "@babel/plugin-transform-react-jsx" "^7.27.1" "@babel/plugin-transform-react-jsx@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz" integrity sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw== dependencies: "@babel/helper-annotate-as-pure" "^7.27.1" @@ -831,7 +831,7 @@ "@babel/plugin-transform-react-pure-annotations@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz" integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.1" @@ -839,14 +839,14 @@ "@babel/plugin-transform-regenerator@^7.28.4": version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz" integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-regexp-modifiers@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz" integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -854,14 +854,14 @@ "@babel/plugin-transform-reserved-words@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz" integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-runtime@^7.16.4": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz" integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w== dependencies: "@babel/helper-module-imports" "^7.27.1" @@ -873,14 +873,14 @@ "@babel/plugin-transform-shorthand-properties@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz" integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-spread@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz" integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -888,28 +888,28 @@ "@babel/plugin-transform-sticky-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz" integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-template-literals@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz" integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-typeof-symbol@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz" integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-typescript@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz" integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" @@ -920,14 +920,14 @@ "@babel/plugin-transform-unicode-escapes@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz" integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-unicode-property-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz" integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -935,7 +935,7 @@ "@babel/plugin-transform-unicode-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz" integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -943,7 +943,7 @@ "@babel/plugin-transform-unicode-sets-regex@^7.27.1": version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz" integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.27.1" @@ -951,7 +951,7 @@ "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.16.4", "@babel/preset-env@^7.20.2", "@babel/preset-env@^7.25.8": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz" integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== dependencies: "@babel/compat-data" "^7.28.5" @@ -1027,7 +1027,7 @@ "@babel/preset-modules@0.1.6-no-external-plugins": version "0.1.6-no-external-plugins" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz" integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -1036,7 +1036,7 @@ "@babel/preset-react@^7.16.0", "@babel/preset-react@^7.18.6", "@babel/preset-react@^7.25.7": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" + resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz" integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -1048,7 +1048,7 @@ "@babel/preset-typescript@^7.16.0", "@babel/preset-typescript@^7.21.0": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz" integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -1059,12 +1059,12 @@ "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.8", "@babel/runtime@^7.24.1", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.9.2": version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3": version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz" integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== dependencies: "@babel/code-frame" "^7.27.1" @@ -1073,7 +1073,7 @@ "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz" integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== dependencies: "@babel/code-frame" "^7.27.1" @@ -1086,7 +1086,7 @@ "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz" integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== dependencies: "@babel/helper-string-parser" "^7.27.1" @@ -1094,22 +1094,22 @@ "@base2/pretty-print-object@1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" + resolved "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz" integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== "@bcoe/v8-coverage@^0.2.3": version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@csstools/normalize.css@*": version "12.1.1" - resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.1.1.tgz#f0ad221b7280f3fc814689786fd9ee092776ef8f" + resolved "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz" integrity sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ== "@csstools/postcss-cascade-layers@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad" + resolved "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz" integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== dependencies: "@csstools/selector-specificity" "^2.0.2" @@ -1117,7 +1117,7 @@ "@csstools/postcss-color-function@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz#2bd36ab34f82d0497cfacdc9b18d34b5e6f64b6b" + resolved "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz" integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== dependencies: "@csstools/postcss-progressive-custom-properties" "^1.1.0" @@ -1125,21 +1125,21 @@ "@csstools/postcss-font-format-keywords@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz#677b34e9e88ae997a67283311657973150e8b16a" + resolved "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz" integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-hwb-function@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz#ab54a9fce0ac102c754854769962f2422ae8aa8b" + resolved "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz" integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-ic-unit@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz#28237d812a124d1a16a5acc5c3832b040b303e58" + resolved "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz" integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== dependencies: "@csstools/postcss-progressive-custom-properties" "^1.1.0" @@ -1147,7 +1147,7 @@ "@csstools/postcss-is-pseudo-class@^2.0.7": version "2.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz#846ae6c0d5a1eaa878fce352c544f9c295509cd1" + resolved "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz" integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== dependencies: "@csstools/selector-specificity" "^2.0.0" @@ -1155,21 +1155,21 @@ "@csstools/postcss-nested-calc@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz#d7e9d1d0d3d15cf5ac891b16028af2a1044d0c26" + resolved "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz" integrity sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-normalize-display-values@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz#15da54a36e867b3ac5163ee12c1d7f82d4d612c3" + resolved "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz" integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-oklab-function@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz#88cee0fbc8d6df27079ebd2fa016ee261eecf844" + resolved "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz" integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== dependencies: "@csstools/postcss-progressive-custom-properties" "^1.1.0" @@ -1177,57 +1177,57 @@ "@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": version "1.3.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + resolved "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz" integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-stepped-value-functions@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz#f8772c3681cc2befed695e2b0b1d68e22f08c4f4" + resolved "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz" integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-text-decoration-shorthand@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz#ea96cfbc87d921eca914d3ad29340d9bcc4c953f" + resolved "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz" integrity sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-trigonometric-functions@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz#94d3e4774c36d35dcdc88ce091336cb770d32756" + resolved "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz" integrity sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og== dependencies: postcss-value-parser "^4.2.0" "@csstools/postcss-unset-value@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz#c99bb70e2cdc7312948d1eb41df2412330b81f77" + resolved "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz" integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== "@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": version "2.2.0" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" + resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz" integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== "@elastic/datemath@^5.0.3": version "5.0.3" - resolved "https://registry.yarnpkg.com/@elastic/datemath/-/datemath-5.0.3.tgz#7baccdab672b9a3ecb7fe8387580670936b58573" + resolved "https://registry.npmjs.org/@elastic/datemath/-/datemath-5.0.3.tgz" integrity sha512-8Hbr1Uyjm5OcYBfEB60K7sCP6U3IXuWDaLaQmYv3UxgI4jqBWbakoemwWvsqPVUvnwEjuX6z7ghPZbefs8xiaA== dependencies: tslib "^1.9.3" "@elastic/eui-theme-borealis@1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@elastic/eui-theme-borealis/-/eui-theme-borealis-1.0.0.tgz#f85679d2d72dfc43a620241cbf4161d4e4e81841" + resolved "https://registry.npmjs.org/@elastic/eui-theme-borealis/-/eui-theme-borealis-1.0.0.tgz" integrity sha512-Zf3ZX5siUhF+TNOdP0FZ3PNEpVmfe3DDXFm5biAKFlGp4e5yrR1FKPYOzkOdJtPWlOoNaedawnALXNVjp1UH8w== "@elastic/eui@^95.12.0": version "95.12.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-95.12.0.tgz#862f2be8b72248a62b40704b9e62f2f5d7d43853" + resolved "https://registry.npmjs.org/@elastic/eui/-/eui-95.12.0.tgz" integrity sha512-SW4ru97FY2VitSqyCgURrM5OMk1W+Ww12b6S+VZN5ex50aNT296DfED/ByidlYaAoVihqjZuoB3HlQBBXydFpA== dependencies: "@hello-pangea/dnd" "^16.6.0" @@ -1266,7 +1266,7 @@ "@emotion/babel-plugin@^11.13.5": version "11.13.5" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz#eab8d65dbded74e0ecfd28dc218e75607c4e7bc0" + resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz" integrity sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ== dependencies: "@babel/helper-module-imports" "^7.16.7" @@ -1283,7 +1283,7 @@ "@emotion/cache@^11.13.5", "@emotion/cache@^11.14.0": version "11.14.0" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" + resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz" integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== dependencies: "@emotion/memoize" "^0.9.0" @@ -1294,7 +1294,7 @@ "@emotion/css@^11.13.0": version "11.13.5" - resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.13.5.tgz#db2d3be6780293640c082848e728a50544b9dfa4" + resolved "https://registry.npmjs.org/@emotion/css/-/css-11.13.5.tgz" integrity sha512-wQdD0Xhkn3Qy2VNcIzbLP9MR8TafI0MJb7BEAXKp+w4+XqErksWR4OXomuDzPsN4InLdGhVe6EYcn2ZIUCpB8w== dependencies: "@emotion/babel-plugin" "^11.13.5" @@ -1305,29 +1305,29 @@ "@emotion/hash@^0.9.2": version "0.9.2" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" + resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz" integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== "@emotion/is-prop-valid@1.2.2": version "1.2.2" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" + resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz" integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== dependencies: "@emotion/memoize" "^0.8.1" "@emotion/memoize@^0.8.1": version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== "@emotion/memoize@^0.9.0": version "0.9.0" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102" + resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz" integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== "@emotion/react@^11.13.3": version "11.14.0" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d" + resolved "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz" integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== dependencies: "@babel/runtime" "^7.18.3" @@ -1341,7 +1341,7 @@ "@emotion/serialize@^1.3.3": version "1.3.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8" + resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz" integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== dependencies: "@emotion/hash" "^0.9.2" @@ -1352,49 +1352,49 @@ "@emotion/sheet@^1.4.0": version "1.4.0" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" + resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== "@emotion/unitless@0.8.1": version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== "@emotion/unitless@^0.10.0": version "0.10.0" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" + resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz" integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== "@emotion/use-insertion-effect-with-fallbacks@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf" + resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz" integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg== "@emotion/utils@^1.4.2": version "1.4.2" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.2.tgz#6df6c45881fcb1c412d6688a311a98b7f59c1b52" + resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz" integrity sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== "@emotion/weak-memoize@^0.4.0": version "0.4.0" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" + resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz" integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== "@eslint-community/eslint-utils@^4.2.0": version "4.9.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz" integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== dependencies: eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": version "4.12.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz" integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== "@eslint/eslintrc@^2.1.4": version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" @@ -1409,12 +1409,12 @@ "@eslint/js@8.57.1": version "8.57.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== "@happy-dom/jest-environment@^16.7.3": version "16.8.1" - resolved "https://registry.yarnpkg.com/@happy-dom/jest-environment/-/jest-environment-16.8.1.tgz#c2c49923d7aec45123361d7756615884fddb4756" + resolved "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-16.8.1.tgz" integrity sha512-TNzYvCYyNySVM+an4fM5l4FIiRtBFiu7m5eyiXtIDWHkS3WLGvJ9yrRkzHtSEqDA7YOYdTIsEn5SQNQ7LCNn0Q== dependencies: "@jest/environment" "^29.4.0" @@ -1426,7 +1426,7 @@ "@hello-pangea/dnd@^16.6.0": version "16.6.0" - resolved "https://registry.yarnpkg.com/@hello-pangea/dnd/-/dnd-16.6.0.tgz#7509639c7bd13f55e537b65a9dcfcd54e7c99ac7" + resolved "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-16.6.0.tgz" integrity sha512-vfZ4GydqbtUPXSLfAvKvXQ6xwRzIjUSjVU0Sx+70VOhc2xx6CdmJXJ8YhH70RpbTUGjxctslQTHul9sIOxCfFQ== dependencies: "@babel/runtime" "^7.24.1" @@ -1439,7 +1439,7 @@ "@humanwhocodes/config-array@^0.13.0": version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz" integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: "@humanwhocodes/object-schema" "^2.0.3" @@ -1448,22 +1448,22 @@ "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^2.0.3": version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== "@inquirer/ansi@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-1.0.2.tgz#674a4c4d81ad460695cb2a1fc69d78cd187f337e" + resolved "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz" integrity sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ== "@inquirer/confirm@^5.0.0": version "5.1.21" - resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.21.tgz#610c4acd7797d94890a6e2dde2c98eb1e891dd12" + resolved "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz" integrity sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ== dependencies: "@inquirer/core" "^10.3.2" @@ -1471,7 +1471,7 @@ "@inquirer/core@^10.3.2": version "10.3.2" - resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.3.2.tgz#535979ff3ff4fe1e7cc4f83e2320504c743b7e20" + resolved "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz" integrity sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A== dependencies: "@inquirer/ansi" "^1.0.2" @@ -1485,29 +1485,29 @@ "@inquirer/figures@^1.0.15": version "1.0.15" - resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.15.tgz#dbb49ed80df11df74268023b496ac5d9acd22b3a" + resolved "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz" integrity sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== "@inquirer/type@^3.0.10": version "3.0.10" - resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.10.tgz#11ed564ec78432a200ea2601a212d24af8150d50" + resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz" integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== "@isaacs/balanced-match@^4.0.1": version "4.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" + resolved "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz" integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== "@isaacs/brace-expansion@^5.0.0": version "5.0.0" - resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" + resolved "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz" integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== dependencies: "@isaacs/balanced-match" "^4.0.1" "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" @@ -1518,12 +1518,12 @@ "@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== "@jest/console@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz" integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== dependencies: "@jest/types" "^29.6.3" @@ -1535,7 +1535,7 @@ "@jest/core@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz" integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: "@jest/console" "^29.7.0" @@ -1569,7 +1569,7 @@ "@jest/environment@^29.4.0", "@jest/environment@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz" integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: "@jest/fake-timers" "^29.7.0" @@ -1579,14 +1579,14 @@ "@jest/expect-utils@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== dependencies: jest-get-type "^29.6.3" "@jest/expect@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz" integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== dependencies: expect "^29.7.0" @@ -1594,7 +1594,7 @@ "@jest/fake-timers@^29.4.0", "@jest/fake-timers@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: "@jest/types" "^29.6.3" @@ -1606,7 +1606,7 @@ "@jest/globals@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== dependencies: "@jest/environment" "^29.7.0" @@ -1616,7 +1616,7 @@ "@jest/reporters@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz" integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== dependencies: "@bcoe/v8-coverage" "^0.2.3" @@ -1646,14 +1646,14 @@ "@jest/schemas@^29.6.3": version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" "@jest/source-map@^29.6.3": version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz" integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== dependencies: "@jridgewell/trace-mapping" "^0.3.18" @@ -1662,7 +1662,7 @@ "@jest/test-result@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz" integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== dependencies: "@jest/console" "^29.7.0" @@ -1672,7 +1672,7 @@ "@jest/test-sequencer@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz" integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== dependencies: "@jest/test-result" "^29.7.0" @@ -1682,7 +1682,7 @@ "@jest/transform@^27.5.1": version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz" integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== dependencies: "@babel/core" "^7.1.0" @@ -1703,7 +1703,7 @@ "@jest/transform@^29.7.0": version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== dependencies: "@babel/core" "^7.11.6" @@ -1724,7 +1724,7 @@ "@jest/types@^27.5.1": version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + resolved "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz" integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" @@ -1735,7 +1735,7 @@ "@jest/types@^29.4.0", "@jest/types@^29.6.3": version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: "@jest/schemas" "^29.6.3" @@ -1747,7 +1747,7 @@ "@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz" integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" @@ -1755,7 +1755,7 @@ "@jridgewell/remapping@^2.3.5": version "2.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + resolved "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz" integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== dependencies: "@jridgewell/gen-mapping" "^0.3.5" @@ -1763,12 +1763,12 @@ "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/source-map@^0.3.3": version "0.3.11" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz" integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== dependencies: "@jridgewell/gen-mapping" "^0.3.5" @@ -1776,12 +1776,12 @@ "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== dependencies: "@jridgewell/resolve-uri" "^3.1.0" @@ -1789,26 +1789,26 @@ "@jsdoc/salty@^0.2.1": version "0.2.9" - resolved "https://registry.yarnpkg.com/@jsdoc/salty/-/salty-0.2.9.tgz#4d8c147f7ca011532681ce86352a77a0178f1dec" + resolved "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz" integrity sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw== dependencies: lodash "^4.17.21" "@leichtgewicht/ip-codec@^2.0.1": version "2.0.5" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" + resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz" integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== "@mapbox/hast-util-table-cell-style@^0.2.0": version "0.2.1" - resolved "https://registry.yarnpkg.com/@mapbox/hast-util-table-cell-style/-/hast-util-table-cell-style-0.2.1.tgz#b8e92afdd38b668cf0762400de980073d2ade101" + resolved "https://registry.npmjs.org/@mapbox/hast-util-table-cell-style/-/hast-util-table-cell-style-0.2.1.tgz" integrity sha512-LyQz4XJIdCdY/+temIhD/Ed0x/p4GAOUycpFSEK2Ads1CPKZy6b7V/2ROEtQiLLQ8soIs0xe/QAoR6kwpyW/yw== dependencies: unist-util-visit "^1.4.1" "@mswjs/interceptors@^0.40.0": version "0.40.0" - resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.40.0.tgz#1b45f215ba8c2983ed133763ca03af92896083d6" + resolved "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.40.0.tgz" integrity sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ== dependencies: "@open-draft/deferred-promise" "^2.2.0" @@ -1820,14 +1820,14 @@ "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" + resolved "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz" integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== dependencies: eslint-scope "5.1.1" "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -1835,12 +1835,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -1848,12 +1848,12 @@ "@open-draft/deferred-promise@^2.2.0": version "2.2.0" - resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" + resolved "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz" integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== "@open-draft/logger@^0.3.0": version "0.3.0" - resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954" + resolved "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz" integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== dependencies: is-node-process "^1.2.0" @@ -1861,12 +1861,12 @@ "@open-draft/until@^2.0.0": version "2.1.0" - resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" + resolved "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz" integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": version "0.5.17" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz#8c2f34ca8651df74895422046e11ce5a120e7930" + resolved "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz" integrity sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ== dependencies: ansi-html "^0.0.9" @@ -1879,27 +1879,27 @@ "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz" integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== "@protobufjs/base64@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz" integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== "@protobufjs/codegen@^2.0.4": version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz" integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz" integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== "@protobufjs/fetch@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz" integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== dependencies: "@protobufjs/aspromise" "^1.1.1" @@ -1907,32 +1907,32 @@ "@protobufjs/float@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz" integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== "@protobufjs/inquire@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz" integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== "@protobufjs/path@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz" integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== "@protobufjs/pool@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz" integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== "@protobufjs/utf8@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== "@reactflow/background@11.3.14": version "11.3.14" - resolved "https://registry.yarnpkg.com/@reactflow/background/-/background-11.3.14.tgz#778ca30174f3de77fc321459ab3789e66e71a699" + resolved "https://registry.npmjs.org/@reactflow/background/-/background-11.3.14.tgz" integrity sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA== dependencies: "@reactflow/core" "11.11.4" @@ -1941,7 +1941,7 @@ "@reactflow/controls@11.2.14": version "11.2.14" - resolved "https://registry.yarnpkg.com/@reactflow/controls/-/controls-11.2.14.tgz#508ed2c40d23341b3b0919dd11e76fd49cf850c7" + resolved "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.14.tgz" integrity sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw== dependencies: "@reactflow/core" "11.11.4" @@ -1950,7 +1950,7 @@ "@reactflow/core@11.11.4": version "11.11.4" - resolved "https://registry.yarnpkg.com/@reactflow/core/-/core-11.11.4.tgz#89bd86d1862aa1416f3f49926cede7e8c2aab6a7" + resolved "https://registry.npmjs.org/@reactflow/core/-/core-11.11.4.tgz" integrity sha512-H4vODklsjAq3AMq6Np4LE12i1I4Ta9PrDHuBR9GmL8uzTt2l2jh4CiQbEMpvMDcp7xi4be0hgXj+Ysodde/i7Q== dependencies: "@types/d3" "^7.4.0" @@ -1965,7 +1965,7 @@ "@reactflow/minimap@11.7.14": version "11.7.14" - resolved "https://registry.yarnpkg.com/@reactflow/minimap/-/minimap-11.7.14.tgz#298d7a63cb1da06b2518c99744f716560c88ca73" + resolved "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.14.tgz" integrity sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ== dependencies: "@reactflow/core" "11.11.4" @@ -1978,7 +1978,7 @@ "@reactflow/node-resizer@2.2.14": version "2.2.14" - resolved "https://registry.yarnpkg.com/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz#1810c0ce51aeb936f179466a6660d1e02c7a77a8" + resolved "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz" integrity sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA== dependencies: "@reactflow/core" "11.11.4" @@ -1989,7 +1989,7 @@ "@reactflow/node-toolbar@1.3.14": version "1.3.14" - resolved "https://registry.yarnpkg.com/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz#c6ffc76f82acacdce654f2160dc9852162d6e7c9" + resolved "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz" integrity sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ== dependencies: "@reactflow/core" "11.11.4" @@ -1998,12 +1998,12 @@ "@remix-run/router@1.23.1": version "1.23.1" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.23.1.tgz#0ce8857b024e24fc427585316383ad9d295b3a7f" + resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz" integrity sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ== "@rollup/plugin-babel@^5.2.0", "@rollup/plugin-babel@^5.3.1": version "5.3.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" + resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz" integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== dependencies: "@babel/helper-module-imports" "^7.10.4" @@ -2011,7 +2011,7 @@ "@rollup/plugin-commonjs@^21.0.2": version "21.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz#45576d7b47609af2db87f55a6d4b46e44fc3a553" + resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz" integrity sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA== dependencies: "@rollup/pluginutils" "^3.1.0" @@ -2024,14 +2024,14 @@ "@rollup/plugin-json@^4.1.0": version "4.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" + resolved "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz" integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== dependencies: "@rollup/pluginutils" "^3.0.8" "@rollup/plugin-node-resolve@^11.2.1": version "11.2.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz" integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== dependencies: "@rollup/pluginutils" "^3.1.0" @@ -2043,7 +2043,7 @@ "@rollup/plugin-node-resolve@^13.1.3": version "13.3.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz#da1c5c5ce8316cef96a2f823d111c1e4e498801c" + resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz" integrity sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw== dependencies: "@rollup/pluginutils" "^3.1.0" @@ -2055,7 +2055,7 @@ "@rollup/plugin-replace@^2.4.1": version "2.4.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz" integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== dependencies: "@rollup/pluginutils" "^3.1.0" @@ -2063,7 +2063,7 @@ "@rollup/plugin-typescript@^8.3.1": version "8.5.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz#7ea11599a15b0a30fa7ea69ce3b791d41b862515" + resolved "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz" integrity sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ== dependencies: "@rollup/pluginutils" "^3.1.0" @@ -2071,7 +2071,7 @@ "@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0": version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz" integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== dependencies: "@types/estree" "0.0.39" @@ -2080,7 +2080,7 @@ "@rollup/pluginutils@^5.1.3": version "5.3.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz#57ba1b0cbda8e7a3c597a4853c807b156e21a7b4" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz" integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q== dependencies: "@types/estree" "^1.0.0" @@ -2089,36 +2089,36 @@ "@rtsao/scc@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" + resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== "@rushstack/eslint-patch@^1.1.0": version "1.15.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz#8184bcb37791e6d3c3c13a9bfbe4af263f66665f" + resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz" integrity sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw== "@sinclair/typebox@^0.27.8": version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinonjs/commons@^3.0.0": version "3.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz" integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^10.0.2": version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz" integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== dependencies: "@sinonjs/commons" "^3.0.0" "@surma/rollup-plugin-off-main-thread@^2.2.3": version "2.2.3" - resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" + resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz" integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== dependencies: ejs "^3.1.6" @@ -2128,47 +2128,47 @@ "@svgr/babel-plugin-add-jsx-attribute@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz" integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== "@svgr/babel-plugin-remove-jsx-attribute@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz" integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== "@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz" integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== "@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz" integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== "@svgr/babel-plugin-svg-dynamic-title@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz" integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== "@svgr/babel-plugin-svg-em-dimensions@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz" integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== "@svgr/babel-plugin-transform-react-native-svg@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz" integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== "@svgr/babel-plugin-transform-svg-component@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz" integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== "@svgr/babel-preset@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + resolved "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz" integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== dependencies: "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" @@ -2182,7 +2182,7 @@ "@svgr/core@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== dependencies: "@babel/core" "^7.21.3" @@ -2193,7 +2193,7 @@ "@svgr/hast-util-to-babel-ast@8.0.0": version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + resolved "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz" integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== dependencies: "@babel/types" "^7.21.3" @@ -2201,7 +2201,7 @@ "@svgr/plugin-jsx@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + resolved "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz" integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== dependencies: "@babel/core" "^7.21.3" @@ -2211,7 +2211,7 @@ "@svgr/plugin-svgo@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz#b115b7b967b564f89ac58feae89b88c3decd0f00" + resolved "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz" integrity sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA== dependencies: cosmiconfig "^8.1.3" @@ -2220,7 +2220,7 @@ "@svgr/webpack@^8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-8.1.0.tgz#16f1b5346f102f89fda6ec7338b96a701d8be0c2" + resolved "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz" integrity sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA== dependencies: "@babel/core" "^7.21.3" @@ -2234,7 +2234,7 @@ "@testing-library/dom@^10.4.0": version "10.4.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.1.tgz#d444f8a889e9a46e9a3b4f3b88e0fcb3efb6cf95" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz" integrity sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg== dependencies: "@babel/code-frame" "^7.10.4" @@ -2248,7 +2248,7 @@ "@testing-library/jest-dom@^6.5.0": version "6.9.1" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz#7613a04e146dd2976d24ddf019730d57a89d56c2" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz" integrity sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA== dependencies: "@adobe/css-tools" "^4.4.0" @@ -2260,34 +2260,34 @@ "@testing-library/react@^16.0.1": version "16.3.0" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-16.3.0.tgz#3a85bb9bdebf180cd76dba16454e242564d598a6" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz" integrity sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/user-event@^14.5.2": version "14.6.1" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.6.1.tgz#13e09a32d7a8b7060fe38304788ebf4197cd2149" + resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz" integrity sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw== "@tootallnate/once@2": version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== "@trysound/sax@0.2.0": version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== "@types/aria-query@^5.0.1": version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz" integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" @@ -2298,14 +2298,14 @@ "@types/babel__generator@*": version "7.27.0" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz" integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" @@ -2313,14 +2313,14 @@ "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": version "7.28.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz" integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== dependencies: "@babel/types" "^7.28.2" "@types/body-parser@*": version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz" integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== dependencies: "@types/connect" "*" @@ -2328,14 +2328,14 @@ "@types/bonjour@^3.5.9": version "3.5.13" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz" integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" "@types/connect-history-api-fallback@^1.3.5": version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz" integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" @@ -2343,43 +2343,43 @@ "@types/connect@*": version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/d3-array@*": version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.2.tgz#e02151464d02d4a1b44646d0fcdb93faf88fde8c" + resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz" integrity sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw== "@types/d3-axis@*": version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795" + resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== dependencies: "@types/d3-selection" "*" "@types/d3-brush@*": version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c" + resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== dependencies: "@types/d3-selection" "*" "@types/d3-chord@*": version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d" + resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== "@types/d3-color@*": version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== "@types/d3-contour@*": version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231" + resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== dependencies: "@types/d3-array" "*" @@ -2387,136 +2387,136 @@ "@types/d3-delaunay@*": version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1" + resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== "@types/d3-dispatch@*": version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz#ef004d8a128046cfce434d17182f834e44ef95b2" + resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz" integrity sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA== "@types/d3-drag@*", "@types/d3-drag@^3.0.1": version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02" + resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== dependencies: "@types/d3-selection" "*" "@types/d3-dsv@*": version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" + resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== "@types/d3-ease@*": version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== "@types/d3-fetch@*": version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" + resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== dependencies: "@types/d3-dsv" "*" "@types/d3-force@*": version "3.0.10" - resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a" + resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz" integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== "@types/d3-format@*": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90" + resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== "@types/d3-geo@*": version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" + resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== dependencies: "@types/geojson" "*" "@types/d3-hierarchy@*": version "3.1.7" - resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b" + resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz" integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== "@types/d3-interpolate@*": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== dependencies: "@types/d3-color" "*" "@types/d3-path@*": version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz" integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== "@types/d3-polygon@*": version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c" + resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== "@types/d3-quadtree@*": version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f" + resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== "@types/d3-random@*": version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb" + resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== "@types/d3-scale-chromatic@*": version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39" + resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== "@types/d3-scale@*": version "4.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz" integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== dependencies: "@types/d3-time" "*" "@types/d3-selection@*", "@types/d3-selection@^3.0.3": version "3.0.11" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz" integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== "@types/d3-shape@*": version "3.1.7" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz" integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== dependencies: "@types/d3-path" "*" "@types/d3-time-format@*": version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2" + resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== "@types/d3-time@*": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz" integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== "@types/d3-timer@*": version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== "@types/d3-transition@*": version "3.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706" + resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz" integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== dependencies: "@types/d3-selection" "*" "@types/d3-zoom@*", "@types/d3-zoom@^3.0.1": version "3.0.8" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b" + resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== dependencies: "@types/d3-interpolate" "*" @@ -2524,7 +2524,7 @@ "@types/d3@^7.4.0": version "7.4.3" - resolved "https://registry.yarnpkg.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2" + resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== dependencies: "@types/d3-array" "*" @@ -2560,46 +2560,38 @@ "@types/dagre@^0.7.52": version "0.7.53" - resolved "https://registry.yarnpkg.com/@types/dagre/-/dagre-0.7.53.tgz#4dab441bf31b6fb08af0b3e2a3f5ab0c0217a701" + resolved "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.53.tgz" integrity sha512-f4gkWqzPZvYmKhOsDnhq/R8mO4UMcKdxZo+i5SCkOU1wvGeHJeUXGIHeE9pnwGyPMDof1Vx5ZQo4nxpeg2TTVQ== "@types/eslint-scope@^3.7.7": version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz" integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" -"@types/eslint@*": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" - integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/eslint@^7.29.0 || ^8.4.1": +"@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": version "8.56.12" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.12.tgz#1657c814ffeba4d2f84c0d4ba0f44ca7ea1ca53a" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz" integrity sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== - -"@types/estree@0.0.39": +"@types/estree@*", "@types/estree@0.0.39": version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": +"@types/estree@^1.0.0", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/express-serve-static-core@*": version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz#74f47555b3d804b54cb7030e6f9aa0c7485cfc5b" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz" integrity sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA== dependencies: "@types/node" "*" @@ -2609,7 +2601,7 @@ "@types/express-serve-static-core@^4.17.33": version "4.19.7" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz#f1d306dcc03b1aafbfb6b4fe684cce8a31cffc10" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz" integrity sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg== dependencies: "@types/node" "*" @@ -2617,18 +2609,9 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@*": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.5.tgz#3ba069177caa34ab96585ca23b3984d752300cdc" - integrity sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^5.0.0" - "@types/serve-static" "^1" - -"@types/express@^4.17.13": +"@types/express@*", "@types/express@^4.17.13": version "4.17.25" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz" integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== dependencies: "@types/body-parser" "*" @@ -2638,19 +2621,19 @@ "@types/fs-extra@^8.0.1": version "8.1.5" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.5.tgz#33aae2962d3b3ec9219b5aca2555ee00274f5927" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz" integrity sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ== dependencies: "@types/node" "*" "@types/geojson@*": version "7946.0.16" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" + resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz" integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== "@types/glob@^7.1.1": version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" @@ -2658,64 +2641,64 @@ "@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" "@types/hast@^2.0.0": version "2.3.10" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643" + resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz" integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw== dependencies: "@types/unist" "^2" "@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.1": version "3.3.7" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz#306e3a3a73828522efa1341159da4846e7573a6c" + resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz" integrity sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g== dependencies: hoist-non-react-statics "^3.3.0" "@types/html-minifier-terser@^6.0.0": version "6.1.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-errors@*": version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz" integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== "@types/http-proxy@^1.17.8": version "1.17.17" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.17.tgz#d9e2c4571fe3507343cb210cd41790375e59a533" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz" integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz" integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz" integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^27.0.1": version "27.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + resolved "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz" integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== dependencies: jest-matcher-utils "^27.0.0" @@ -2723,7 +2706,7 @@ "@types/jsdom@^20.0.0": version "20.0.1" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" + resolved "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz" integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== dependencies: "@types/node" "*" @@ -2732,27 +2715,27 @@ "@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/linkify-it@^5": version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" + resolved "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz" integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== "@types/lodash@^4.14.202": version "4.17.20" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.20.tgz#1ca77361d7363432d29f5e55950d9ec1e1c6ea93" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz" integrity sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA== "@types/markdown-it@^14.1.1": version "14.1.2" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.2.tgz#57f2532a0800067d9b934f3521429a2e8bfb4c61" + resolved "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz" integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog== dependencies: "@types/linkify-it" "^5" @@ -2760,106 +2743,92 @@ "@types/mdast@^3.0.0": version "3.0.15" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz" integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== dependencies: "@types/unist" "^2" "@types/mdurl@^2": version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" + resolved "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz" integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== "@types/mime@^1": version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@*", "@types/minimatch@^6.0.0": version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-6.0.0.tgz#4d207b1cc941367bdcd195a3a781a7e4fc3b1e03" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-6.0.0.tgz" integrity sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA== dependencies: minimatch "*" "@types/node-forge@^1.3.0": version "1.3.14" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b" + resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz" integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=13.7.0": - version "24.10.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.1.tgz#91e92182c93db8bd6224fca031e2370cef9a8f01" - integrity sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ== - dependencies: - undici-types "~7.16.0" - -"@types/node@^22.12.0": +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.12.0": version "22.19.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.1.tgz#1188f1ddc9f46b4cc3aec76749050b4e1f459b7b" + resolved "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz" integrity sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ== dependencies: undici-types "~6.21.0" "@types/numeral@^2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/numeral/-/numeral-2.0.5.tgz#388e5c4ff4b0e1787f130753cbbe83d3ba770858" + resolved "https://registry.npmjs.org/@types/numeral/-/numeral-2.0.5.tgz" integrity sha512-kH8I7OSSwQu9DS9JYdFWbuvhVzvFRoCPCkGxNwoGgaPeDfEPJlcxNvEOypZhQ3XXHsGbfIuYcxcJxKUfJHnRfw== "@types/parse-json@^4.0.0": version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/parse5@^5.0.0": version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + resolved "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== "@types/prismjs@*": version "1.26.5" - resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6" + resolved "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz" integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ== "@types/prop-types@*": version "15.7.15" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz" integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== "@types/qs@*": version "6.14.0" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz" integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== "@types/range-parser@*": version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/react-dom@^18.3.0": version "18.3.7" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz" integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== "@types/react-window@^1.8.8": version "1.8.8" - resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.8.tgz#c20645414d142364fbe735818e1c1e0a145696e3" + resolved "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz" integrity sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q== dependencies: "@types/react" "*" -"@types/react@*": - version "19.2.6" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.6.tgz#d27db1ff45012d53980f5589fda925278e1249ca" - integrity sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w== - dependencies: - csstype "^3.2.2" - -"@types/react@^18.3.11": +"@types/react@*", "@types/react@^18.3.11": version "18.3.27" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.27.tgz#74a3b590ea183983dc65a474dc17553ae1415c34" + resolved "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz" integrity sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w== dependencies: "@types/prop-types" "*" @@ -2867,38 +2836,38 @@ "@types/refractor@^3.4.0": version "3.4.1" - resolved "https://registry.yarnpkg.com/@types/refractor/-/refractor-3.4.1.tgz#8b109804f77b3da8fad543d3f575fef1ece8835a" + resolved "https://registry.npmjs.org/@types/refractor/-/refractor-3.4.1.tgz" integrity sha512-wYuorIiCTSuvRT9srwt+taF6mH/ww+SyN2psM0sjef2qW+sS8GmshgDGTEDgWB1sTVGgYVE6EK7dBA2MxQxibg== dependencies: "@types/prismjs" "*" "@types/resolve@1.17.1": version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz" integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== dependencies: "@types/node" "*" "@types/retry@0.12.0": version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/semver@^7.3.12": version "7.7.1" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz" integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== "@types/send@*": version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" + resolved "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz" integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== dependencies: "@types/node" "*" "@types/send@<1": version "0.17.6" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz" integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== dependencies: "@types/mime" "^1" @@ -2906,14 +2875,14 @@ "@types/serve-index@^1.9.1": version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz" integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" "@types/serve-static@^1", "@types/serve-static@^1.13.10": version "1.15.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz" integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== dependencies: "@types/http-errors" "*" @@ -2922,24 +2891,24 @@ "@types/sockjs@^0.3.33": version "0.3.36" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz" integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" "@types/stack-utils@^2.0.0": version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/statuses@^2.0.4": version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.6.tgz#66748315cc9a96d63403baa8671b2c124f8633aa" + resolved "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz" integrity sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA== "@types/styled-components@^5.1.34": version "5.1.36" - resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.36.tgz#d63db8ad9005afc82f173012036c4c101dc93d57" + resolved "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.36.tgz" integrity sha512-pGMRNY5G2rNDKEv2DOiFYa7Ft1r0jrhmgBwHhOMzPTgCjO76bCot0/4uEfqj7K0Jf1KdQmDtAuaDk9EAs9foSw== dependencies: "@types/hoist-non-react-statics" "*" @@ -2948,58 +2917,58 @@ "@types/stylis@4.2.5": version "4.2.5" - resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.5.tgz#1daa6456f40959d06157698a653a9ab0a70281df" + resolved "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz" integrity sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw== "@types/tough-cookie@*": version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== "@types/trusted-types@^2.0.2": version "2.0.7" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": version "2.0.11" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz" integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== "@types/use-sync-external-store@^0.0.3": version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz" integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== "@types/ws@^8.5.5": version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz" integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" "@types/yargs-parser@*": version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^16.0.0": version "16.0.11" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.11.tgz#de958fb62e77fc383fa6cd8066eabdd13da88f04" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz" integrity sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": version "17.0.35" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz" integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.5.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz" integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== dependencies: "@eslint-community/regexpp" "^4.4.0" @@ -3015,14 +2984,14 @@ "@typescript-eslint/experimental-utils@^5.0.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz" integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== dependencies: "@typescript-eslint/utils" "5.62.0" "@typescript-eslint/parser@^5.5.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: "@typescript-eslint/scope-manager" "5.62.0" @@ -3032,7 +3001,7 @@ "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz" integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: "@typescript-eslint/types" "5.62.0" @@ -3040,7 +3009,7 @@ "@typescript-eslint/type-utils@5.62.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz" integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: "@typescript-eslint/typescript-estree" "5.62.0" @@ -3050,12 +3019,12 @@ "@typescript-eslint/types@5.62.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz" integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: "@typescript-eslint/types" "5.62.0" @@ -3068,7 +3037,7 @@ "@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.58.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -3082,7 +3051,7 @@ "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz" integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: "@typescript-eslint/types" "5.62.0" @@ -3090,12 +3059,12 @@ "@ungap/structured-clone@^1.2.0": version "1.3.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz" integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: "@webassemblyjs/helper-numbers" "1.13.2" @@ -3103,22 +3072,22 @@ "@webassemblyjs/floating-point-hex-parser@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz" integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== "@webassemblyjs/helper-api-error@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz" integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== "@webassemblyjs/helper-buffer@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz" integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== "@webassemblyjs/helper-numbers@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz" integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: "@webassemblyjs/floating-point-hex-parser" "1.13.2" @@ -3127,12 +3096,12 @@ "@webassemblyjs/helper-wasm-bytecode@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz" integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== "@webassemblyjs/helper-wasm-section@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz" integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3142,26 +3111,26 @@ "@webassemblyjs/ieee754@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz" integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" "@webassemblyjs/leb128@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz" integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" "@webassemblyjs/utf8@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz" integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== "@webassemblyjs/wasm-edit@^1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz" integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3175,7 +3144,7 @@ "@webassemblyjs/wasm-gen@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz" integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3186,7 +3155,7 @@ "@webassemblyjs/wasm-opt@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz" integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3196,7 +3165,7 @@ "@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz" integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3208,7 +3177,7 @@ "@webassemblyjs/wast-printer@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz" integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -3216,22 +3185,22 @@ "@xtuc/ieee754@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== "@xtuc/long@4.2.2": version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== abab@^2.0.5, abab@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: mime-types "~2.1.34" @@ -3239,7 +3208,7 @@ accepts@~1.3.4, accepts@~1.3.8: acorn-globals@^7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz" integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== dependencies: acorn "^8.1.0" @@ -3247,34 +3216,34 @@ acorn-globals@^7.0.0: acorn-import-phases@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + resolved "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz" integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.0.2: version "8.3.4" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz" integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== dependencies: acorn "^8.11.0" acorn@^8.1.0, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.8.1, acorn@^8.9.0: version "8.15.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== address@^1.0.1, address@^1.1.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + resolved "https://registry.npmjs.org/address/-/address-1.2.2.tgz" integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== adjust-sourcemap-loader@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + resolved "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz" integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== dependencies: loader-utils "^2.0.0" @@ -3282,33 +3251,33 @@ adjust-sourcemap-loader@^4.0.0: agent-base@6: version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" ajv-formats@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== dependencies: ajv "^8.0.0" ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv-keywords@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -3318,7 +3287,7 @@ ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: version "8.17.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== dependencies: fast-deep-equal "^3.1.3" @@ -3328,51 +3297,51 @@ ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: ansi-escapes@^4.2.1: version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-escapes@^6.0.0: version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.1.tgz#76c54ce9b081dad39acec4b5d53377913825fb0f" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz" integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig== ansi-html-community@^0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + resolved "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== ansi-html@^0.0.9: version "0.0.9" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.9.tgz#6512d02342ae2cc68131952644a129cb734cd3f0" + resolved "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz" integrity sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: version "6.2.2" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -3380,38 +3349,38 @@ anymatch@^3.0.3, anymatch@~3.1.2: argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== aria-hidden@^1.2.5: version "1.2.6" - resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a" + resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz" integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== dependencies: tslib "^2.0.0" -aria-query@5.3.0: +aria-query@5.3.0, aria-query@^5.0.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== dependencies: dequal "^2.0.3" -aria-query@^5.0.0, aria-query@^5.3.2: +aria-query@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz" integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz" integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw== dependencies: call-bound "^1.0.3" @@ -3419,12 +3388,12 @@ array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2: array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9: version "3.1.9" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz" integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ== dependencies: call-bind "^1.0.8" @@ -3438,12 +3407,12 @@ array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.findlast@^1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" + resolved "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz" integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== dependencies: call-bind "^1.0.7" @@ -3455,7 +3424,7 @@ array.prototype.findlast@^1.2.5: array.prototype.findlastindex@^1.2.6: version "1.2.6" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564" + resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz" integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ== dependencies: call-bind "^1.0.8" @@ -3468,7 +3437,7 @@ array.prototype.findlastindex@^1.2.6: array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz" integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== dependencies: call-bind "^1.0.8" @@ -3478,7 +3447,7 @@ array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3: array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz" integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== dependencies: call-bind "^1.0.8" @@ -3488,7 +3457,7 @@ array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3: array.prototype.tosorted@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz" integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== dependencies: call-bind "^1.0.7" @@ -3499,7 +3468,7 @@ array.prototype.tosorted@^1.1.4: arraybuffer.prototype.slice@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz" integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== dependencies: array-buffer-byte-length "^1.0.1" @@ -3512,42 +3481,42 @@ arraybuffer.prototype.slice@^1.0.4: asap@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== ast-types-flow@^0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz" integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== async-function@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b" + resolved "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz" integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== async@^3.2.6: version "3.2.6" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + resolved "https://registry.npmjs.org/async/-/async-3.2.6.tgz" integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== attr-accept@^2.2.2: version "2.2.5" - resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e" + resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz" integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ== autoprefixer@^10.4.13: version "10.4.22" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.22.tgz#90b27ab55ec0cf0684210d1f056f7d65dac55f16" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz" integrity sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg== dependencies: browserslist "^4.27.0" @@ -3559,24 +3528,24 @@ autoprefixer@^10.4.13: available-typed-arrays@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== dependencies: possible-typed-array-names "^1.0.0" axe-core@^4.10.0: version "4.11.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.0.tgz#16f74d6482e343ff263d4f4503829e9ee91a86b6" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz" integrity sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ== axobject-query@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" + resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz" integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== babel-jest@^27.4.2: version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz" integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== dependencies: "@jest/transform" "^27.5.1" @@ -3590,7 +3559,7 @@ babel-jest@^27.4.2: babel-jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== dependencies: "@jest/transform" "^29.7.0" @@ -3603,7 +3572,7 @@ babel-jest@^29.7.0: babel-loader@^8.2.3: version "8.4.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.4.1.tgz#6ccb75c66e62c3b144e1c5f2eaec5b8f6c08c675" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz" integrity sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA== dependencies: find-cache-dir "^3.3.1" @@ -3613,7 +3582,7 @@ babel-loader@^8.2.3: babel-plugin-istanbul@^6.1.1: version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -3624,7 +3593,7 @@ babel-plugin-istanbul@^6.1.1: babel-plugin-jest-hoist@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz" integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== dependencies: "@babel/template" "^7.3.3" @@ -3634,7 +3603,7 @@ babel-plugin-jest-hoist@^27.5.1: babel-plugin-jest-hoist@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== dependencies: "@babel/template" "^7.3.3" @@ -3644,7 +3613,7 @@ babel-plugin-jest-hoist@^29.6.3: babel-plugin-macros@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== dependencies: "@babel/runtime" "^7.12.5" @@ -3653,12 +3622,12 @@ babel-plugin-macros@^3.1.0: babel-plugin-named-asset-import@^0.3.8: version "0.3.8" - resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" + resolved "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz" integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== babel-plugin-polyfill-corejs2@^0.4.14: version "0.4.14" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz" integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg== dependencies: "@babel/compat-data" "^7.27.7" @@ -3667,7 +3636,7 @@ babel-plugin-polyfill-corejs2@^0.4.14: babel-plugin-polyfill-corejs3@^0.13.0: version "0.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz" integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== dependencies: "@babel/helper-define-polyfill-provider" "^0.6.5" @@ -3675,19 +3644,19 @@ babel-plugin-polyfill-corejs3@^0.13.0: babel-plugin-polyfill-regenerator@^0.6.5: version "0.6.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz" integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg== dependencies: "@babel/helper-define-polyfill-provider" "^0.6.5" babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + resolved "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz" integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== babel-preset-current-node-syntax@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz#20730d6cdc7dda5d89401cab10ac6a32067acde6" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz" integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" @@ -3708,7 +3677,7 @@ babel-preset-current-node-syntax@^1.0.0: babel-preset-jest@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz" integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== dependencies: babel-plugin-jest-hoist "^27.5.1" @@ -3716,7 +3685,7 @@ babel-preset-jest@^27.5.1: babel-preset-jest@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== dependencies: babel-plugin-jest-hoist "^29.6.3" @@ -3724,7 +3693,7 @@ babel-preset-jest@^29.6.3: babel-preset-react-app@^10.0.1: version "10.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.1.0.tgz#e367f223f6c27878e6cc28471d0d506a9ab9f96c" + resolved "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.1.0.tgz" integrity sha512-f9B1xMdnkCIqe+2dHrJsoQFRz7reChaAHE/65SdaykPklQqhme2WaC08oD3is77x9ff98/9EazAKFDZv5rFEQg== dependencies: "@babel/core" "^7.16.0" @@ -3747,27 +3716,27 @@ babel-preset-react-app@^10.0.1: bail@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz" integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== baseline-browser-mapping@^2.8.25: version "2.8.29" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.29.tgz#d8800b71399c783cb1bf2068c2bcc3b6cfd7892c" + resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.29.tgz" integrity sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA== batch@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== bfj@^7.0.2: version "7.1.0" - resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.1.0.tgz#c5177d522103f9040e1b12980fe8c38cf41d3f8b" + resolved "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz" integrity sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw== dependencies: bluebird "^3.7.2" @@ -3778,27 +3747,27 @@ bfj@^7.0.2: big-integer@^1.6.16: version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz" integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== big.js@^5.2.2: version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== bluebird@^3.7.2: version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== body-parser@1.20.3: version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz" integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== dependencies: bytes "3.1.2" @@ -3816,7 +3785,7 @@ body-parser@1.20.3: bonjour-service@^1.0.11: version "1.3.0" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" + resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz" integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== dependencies: fast-deep-equal "^3.1.3" @@ -3824,12 +3793,12 @@ bonjour-service@^1.0.11: boolbase@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== brace-expansion@^1.1.7: version "1.1.12" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" @@ -3837,21 +3806,21 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz" integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== dependencies: balanced-match "^1.0.0" braces@^3.0.3, braces@~3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" broadcast-channel@^3.4.1: version "3.7.0" - resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" + resolved "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz" integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== dependencies: "@babel/runtime" "^7.7.2" @@ -3865,7 +3834,7 @@ broadcast-channel@^3.4.1: browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.4, browserslist@^4.24.0, browserslist@^4.26.3, browserslist@^4.27.0, browserslist@^4.28.0: version "4.28.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.0.tgz#9cefece0a386a17a3cd3d22ebf67b9deca1b5929" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz" integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ== dependencies: baseline-browser-mapping "^2.8.25" @@ -3876,29 +3845,29 @@ browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.4, browserslist@^4 bser@2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== builtin-modules@^3.1.0, builtin-modules@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== bytes@3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== dependencies: es-errors "^1.3.0" @@ -3906,7 +3875,7 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply- call-bind@^1.0.7, call-bind@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz" integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== dependencies: call-bind-apply-helpers "^1.0.0" @@ -3916,7 +3885,7 @@ call-bind@^1.0.7, call-bind@^1.0.8: call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz" integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== dependencies: call-bind-apply-helpers "^1.0.2" @@ -3924,12 +3893,12 @@ call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camel-case@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + resolved "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz" integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== dependencies: pascal-case "^3.1.2" @@ -3937,22 +3906,22 @@ camel-case@^4.1.2: camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.2.0, camelcase@^6.2.1: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== camelize@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz" integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== caniuse-api@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz" integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== dependencies: browserslist "^4.0.0" @@ -3962,29 +3931,29 @@ caniuse-api@^3.0.0: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001754: version "1.0.30001756" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz#fe80104631102f88e58cad8aa203a2c3e5ec9ebd" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz" integrity sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + resolved "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== catharsis@^0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + resolved "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz" integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== dependencies: lodash "^4.17.15" ccount@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" + resolved "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -3992,47 +3961,47 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: chalk@^5.2.0: version "5.6.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== char-regex@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.2.tgz#81385bb071af4df774bff8721d0ca15ef29ea0bb" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz" integrity sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg== character-entities-html4@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz" integrity sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g== character-entities-legacy@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== character-entities@^1.0.0: version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== character-reference-invalid@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== check-types@^11.2.3: version "11.2.3" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71" + resolved "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz" integrity sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg== chokidar@^3.4.2, chokidar@^3.5.3: version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" @@ -4047,49 +4016,49 @@ chokidar@^3.4.2, chokidar@^3.5.3: chroma-js@^2.4.2: version "2.6.0" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.6.0.tgz#578743dd359698a75067a19fa5571dec54d0b70b" + resolved "https://registry.npmjs.org/chroma-js/-/chroma-js-2.6.0.tgz" integrity sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A== chrome-trace-event@^1.0.2: version "1.0.4" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== ci-info@^3.2.0: version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: version "1.4.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz" integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== classcat@^5.0.3, classcat@^5.0.4: version "5.0.5" - resolved "https://registry.yarnpkg.com/classcat/-/classcat-5.0.5.tgz#8c209f359a93ac302404a10161b501eba9c09c77" + resolved "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz" integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w== classnames@^2.5.1: version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== clean-css@^5.2.2: version "5.3.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz" integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== dependencies: source-map "~0.6.0" cli-width@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz" integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== cliui@^8.0.1: version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -4098,93 +4067,93 @@ cliui@^8.0.1: co@^4.6.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collapse-white-space@^1.0.2: version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz" integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== collect-v8-coverage@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz#cc1f01eb8d02298cbc9a437c74c70ab4e5210b80" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz" integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colord@^2.9.1: version "2.9.3" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + resolved "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== colorette@^1.1.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + resolved "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== colorette@^2.0.10: version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" comma-separated-tokens@^1.0.0: version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== commander@^2.20.0: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== commander@^8.3.0: version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== common-tags@^1.8.0: version "1.8.2" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz" integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== commondir@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== compressible@~2.0.18: version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: mime-db ">= 1.43.0 < 2" compression@^1.7.4: version "1.8.1" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" + resolved "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz" integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== dependencies: bytes "3.1.2" @@ -4197,81 +4166,81 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== confusing-browser-globals@^1.0.11: version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + resolved "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== connect-history-api-fallback@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== content-disposition@0.5.4: version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== convert-source-map@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== cookie@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.0.2.tgz#27360701532116bd3f1f9416929d176afe1e4610" + resolved "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz" integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== core-js-compat@^3.43.0: version "3.47.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.47.0.tgz#698224bbdbb6f2e3f39decdda4147b161e3772a3" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz" integrity sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ== dependencies: browserslist "^4.28.0" core-js-pure@^3.23.3: version "3.47.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.47.0.tgz#1104df8a3b6eb9189fcc559b5a65b90f66e7e887" + resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.47.0.tgz" integrity sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw== core-js@^3.19.2: version "3.47.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.47.0.tgz#436ef07650e191afeb84c24481b298bd60eb4a17" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz" integrity sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg== core-util-is@~1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== dependencies: "@types/parse-json" "^4.0.0" @@ -4282,7 +4251,7 @@ cosmiconfig@^6.0.0: cosmiconfig@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" @@ -4293,7 +4262,7 @@ cosmiconfig@^7.0.0: cosmiconfig@^8.1.3: version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz" integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== dependencies: import-fresh "^3.3.0" @@ -4303,7 +4272,7 @@ cosmiconfig@^8.1.3: create-jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== dependencies: "@jest/types" "^29.6.3" @@ -4316,7 +4285,7 @@ create-jest@^29.7.0: cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" @@ -4325,43 +4294,43 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: crypto-random-string@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== css-blank-pseudo@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + resolved "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz" integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== dependencies: postcss-selector-parser "^6.0.9" css-box-model@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + resolved "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz" integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== dependencies: tiny-invariant "^1.0.6" css-color-keywords@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz" integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== css-declaration-sorter@^6.3.1: version "6.4.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz" integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== css-has-pseudo@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + resolved "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz" integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== dependencies: postcss-selector-parser "^6.0.9" css-loader@^6.5.1: version "6.11.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz" integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" @@ -4375,7 +4344,7 @@ css-loader@^6.5.1: css-minimizer-webpack-plugin@^3.2.0: version "3.4.1" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" + resolved "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz" integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== dependencies: cssnano "^5.0.6" @@ -4387,12 +4356,12 @@ css-minimizer-webpack-plugin@^3.2.0: css-prefers-color-scheme@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + resolved "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz" integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== css-select@^4.1.3: version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: boolbase "^1.0.0" @@ -4403,7 +4372,7 @@ css-select@^4.1.3: css-select@^5.1.0: version "5.2.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.2.2.tgz#01b6e8d163637bb2dd6c982ca4ed65863682786e" + resolved "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz" integrity sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw== dependencies: boolbase "^1.0.0" @@ -4414,7 +4383,7 @@ css-select@^5.1.0: css-to-react-native@3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz" integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== dependencies: camelize "^1.0.0" @@ -4423,7 +4392,7 @@ css-to-react-native@3.2.0: css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz" integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: mdn-data "2.0.14" @@ -4431,7 +4400,7 @@ css-tree@^1.1.2, css-tree@^1.1.3: css-tree@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz" integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== dependencies: mdn-data "2.0.30" @@ -4439,7 +4408,7 @@ css-tree@^2.3.1: css-tree@~2.2.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz" integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== dependencies: mdn-data "2.0.28" @@ -4447,27 +4416,27 @@ css-tree@~2.2.0: css-what@^6.0.1, css-what@^6.1.0: version "6.2.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.2.2.tgz#cdcc8f9b6977719fdfbd1de7aec24abf756b9dea" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz" integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== css.escape@^1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== cssdb@^7.1.0: version "7.11.2" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.11.2.tgz#127a2f5b946ee653361a5af5333ea85a39df5ae5" + resolved "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz" integrity sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A== cssesc@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== cssnano-preset-default@^5.2.14: version "5.2.14" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz" integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== dependencies: css-declaration-sorter "^6.3.1" @@ -4502,12 +4471,12 @@ cssnano-preset-default@^5.2.14: cssnano-utils@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + resolved "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz" integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== cssnano@^5.0.6: version "5.1.15" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + resolved "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz" integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== dependencies: cssnano-preset-default "^5.2.14" @@ -4516,58 +4485,58 @@ cssnano@^5.0.6: csso@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + resolved "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz" integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: css-tree "^1.1.2" csso@^5.0.5: version "5.0.5" - resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + resolved "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz" integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== dependencies: css-tree "~2.2.0" cssom@^0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz" integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== cssom@~0.3.6: version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== cssstyle@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: cssom "~0.3.6" csstype@3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== csstype@^3.0.2, csstype@^3.2.2: version "3.2.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== "d3-color@1 - 3": version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== "d3-dispatch@1 - 3": version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== "d3-drag@2 - 3", d3-drag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== dependencies: d3-dispatch "1 - 3" @@ -4575,29 +4544,29 @@ csstype@^3.0.2, csstype@^3.2.2: "d3-ease@1 - 3": version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== "d3-interpolate@1 - 3": version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: d3-color "1 - 3" "d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== "d3-timer@1 - 3": version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== "d3-transition@2 - 3": version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== dependencies: d3-color "1 - 3" @@ -4608,7 +4577,7 @@ csstype@^3.0.2, csstype@^3.2.2: d3-zoom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== dependencies: d3-dispatch "1 - 3" @@ -4619,7 +4588,7 @@ d3-zoom@^3.0.0: dagre@^0.8.5: version "0.8.5" - resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" + resolved "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz" integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== dependencies: graphlib "^2.1.8" @@ -4627,12 +4596,12 @@ dagre@^0.8.5: damerau-levenshtein@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== data-urls@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" + resolved "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz" integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== dependencies: abab "^2.0.6" @@ -4641,7 +4610,7 @@ data-urls@^3.0.2: data-view-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570" + resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz" integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ== dependencies: call-bound "^1.0.3" @@ -4650,7 +4619,7 @@ data-view-buffer@^1.0.2: data-view-byte-length@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz#9e80f7ca52453ce3e93d25a35318767ea7704735" + resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz" integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ== dependencies: call-bound "^1.0.3" @@ -4659,7 +4628,7 @@ data-view-byte-length@^1.0.2: data-view-byte-offset@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz#068307f9b71ab76dbbe10291389e020856606191" + resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz" integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ== dependencies: call-bound "^1.0.2" @@ -4668,60 +4637,60 @@ data-view-byte-offset@^1.0.1: debug@2.6.9, debug@^2.6.0: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1: version "4.4.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: ms "^2.1.3" debug@^3.2.7: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" decimal.js@^10.4.2: version "10.6.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz" integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg== decode-uri-component@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== dedent@^1.0.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" + resolved "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz" integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== default-gateway@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== dependencies: execa "^5.0.0" define-data-property@^1.0.1, define-data-property@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz" integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: es-define-property "^1.0.0" @@ -4730,12 +4699,12 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: define-lazy-prop@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.3, define-properties@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: define-data-property "^1.0.1" @@ -4744,47 +4713,47 @@ define-properties@^1.1.3, define-properties@^1.2.1: delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== depd@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== depd@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== dequal@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== destroy@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-newline@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== detect-node-es@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== detect-node@^2.0.4, detect-node@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== detect-port-alt@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + resolved "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz" integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== dependencies: address "^1.0.1" @@ -4792,62 +4761,62 @@ detect-port-alt@^1.1.6: diff-sequences@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== diff-sequences@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" dns-packet@^5.2.2: version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz" integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== dependencies: "@leichtgewicht/ip-codec" "^2.0.1" doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-accessibility-api@^0.5.9: version "0.5.16" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== dom-accessibility-api@^0.6.3: version "0.6.3" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz" integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== dom-converter@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz" integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== dependencies: utila "~0.4" dom-serializer@^1.0.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: domelementtype "^2.0.1" @@ -4856,7 +4825,7 @@ dom-serializer@^1.0.1: dom-serializer@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== dependencies: domelementtype "^2.3.0" @@ -4865,33 +4834,33 @@ dom-serializer@^2.0.0: domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domexception@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz" integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== dependencies: webidl-conversions "^7.0.0" domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: domelementtype "^2.2.0" domhandler@^5.0.2, domhandler@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== dependencies: domelementtype "^2.3.0" domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: dom-serializer "^1.0.1" @@ -4900,7 +4869,7 @@ domutils@^2.5.2, domutils@^2.8.0: domutils@^3.0.1: version "3.2.2" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78" + resolved "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz" integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw== dependencies: dom-serializer "^2.0.0" @@ -4909,7 +4878,7 @@ domutils@^3.0.1: dot-case@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== dependencies: no-case "^3.0.4" @@ -4917,17 +4886,17 @@ dot-case@^3.0.4: dotenv-expand@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== dotenv@^10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== dunder-proto@^1.0.0, dunder-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== dependencies: call-bind-apply-helpers "^1.0.1" @@ -4936,64 +4905,64 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1: duplexer@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== ee-first@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.6: version "3.1.10" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz" integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" electron-to-chromium@^1.5.249: version "1.5.258" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.258.tgz#094b0280928b1bf967b202e4be5b335aa4754b69" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.258.tgz" integrity sha512-rHUggNV5jKQ0sSdWwlaRDkFc3/rRJIVnOSe9yR4zrR07m3ZxhP4N27Hlg8VeJGGYgFTxK5NqDmWI4DSH72vIJg== emittery@^0.13.1: version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== emojis-list@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== emoticon@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-3.2.0.tgz#c008ca7d7620fac742fe1bf4af8ff8fed154ae7f" + resolved "https://registry.npmjs.org/emoticon/-/emoticon-3.2.0.tgz" integrity sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== encodeurl@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== enhanced-resolve@^5.17.3: version "5.18.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz" integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== dependencies: graceful-fs "^4.2.4" @@ -5001,36 +4970,36 @@ enhanced-resolve@^5.17.3: entities@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== entities@^4.2.0, entities@^4.4.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== entities@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + resolved "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz" integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== error-ex@^1.3.1: version "1.3.4" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz" integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== dependencies: is-arrayish "^0.2.1" error-stack-parser@^2.0.6: version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz" integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== dependencies: stackframe "^1.3.4" es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0: version "1.24.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.0.tgz#c44732d2beb0acc1ed60df840869e3106e7af328" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz" integrity sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg== dependencies: array-buffer-byte-length "^1.0.2" @@ -5090,17 +5059,17 @@ es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23 es-define-property@^1.0.0, es-define-property@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz" integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== es-errors@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-iterator-helpers@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz#d1dd0f58129054c0ad922e6a9a1e65eef435fe75" + resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz" integrity sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w== dependencies: call-bind "^1.0.8" @@ -5122,19 +5091,19 @@ es-iterator-helpers@^1.2.1: es-module-lexer@^1.2.1: version "1.7.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz" integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz" integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== dependencies: es-errors "^1.3.0" es-set-tostringtag@^2.0.3, es-set-tostringtag@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz" integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== dependencies: es-errors "^1.3.0" @@ -5144,14 +5113,14 @@ es-set-tostringtag@^2.0.3, es-set-tostringtag@^2.1.0: es-shim-unscopables@^1.0.2, es-shim-unscopables@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz" integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw== dependencies: hasown "^2.0.2" es-to-primitive@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz" integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== dependencies: is-callable "^1.2.7" @@ -5160,27 +5129,27 @@ es-to-primitive@^1.3.0: escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^1.13.0, escodegen@^1.8.1: version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz" integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== dependencies: esprima "^4.0.1" @@ -5192,7 +5161,7 @@ escodegen@^1.13.0, escodegen@^1.8.1: escodegen@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz" integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" @@ -5203,7 +5172,7 @@ escodegen@^2.0.0: eslint-config-react-app@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz#73ba3929978001c5c86274c017ea57eb5fa644b4" + resolved "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz" integrity sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA== dependencies: "@babel/core" "^7.16.0" @@ -5223,7 +5192,7 @@ eslint-config-react-app@^7.0.1: eslint-import-resolver-node@^0.3.9: version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" @@ -5232,14 +5201,14 @@ eslint-import-resolver-node@^0.3.9: eslint-module-utils@^2.12.1: version "2.12.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz" integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw== dependencies: debug "^3.2.7" eslint-plugin-flowtype@^8.0.3: version "8.0.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" + resolved "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz" integrity sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ== dependencies: lodash "^4.17.21" @@ -5247,7 +5216,7 @@ eslint-plugin-flowtype@^8.0.3: eslint-plugin-import@^2.25.3: version "2.32.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz" integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA== dependencies: "@rtsao/scc" "^1.1.0" @@ -5272,14 +5241,14 @@ eslint-plugin-import@^2.25.3: eslint-plugin-jest@^25.3.0: version "25.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz#ff4ac97520b53a96187bad9c9814e7d00de09a6a" + resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz" integrity sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ== dependencies: "@typescript-eslint/experimental-utils" "^5.0.0" eslint-plugin-jsx-a11y@^6.5.1: version "6.10.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz#d2812bb23bf1ab4665f1718ea442e8372e638483" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz" integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q== dependencies: aria-query "^5.3.2" @@ -5300,12 +5269,12 @@ eslint-plugin-jsx-a11y@^6.5.1: eslint-plugin-react-hooks@^4.3.0: version "4.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz" integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== eslint-plugin-react@^7.27.1: version "7.37.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz" integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== dependencies: array-includes "^3.1.8" @@ -5329,14 +5298,14 @@ eslint-plugin-react@^7.27.1: eslint-plugin-testing-library@^5.0.1: version "5.11.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz#5b46cdae96d4a78918711c0b4792f90088e62d20" + resolved "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz" integrity sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw== dependencies: "@typescript-eslint/utils" "^5.58.0" eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -5344,7 +5313,7 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: eslint-scope@^7.2.2: version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" @@ -5352,17 +5321,17 @@ eslint-scope@^7.2.2: eslint-visitor-keys@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint-webpack-plugin@^3.1.1: version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" + resolved "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz" integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== dependencies: "@types/eslint" "^7.29.0 || ^8.4.1" @@ -5373,7 +5342,7 @@ eslint-webpack-plugin@^3.1.1: eslint@^8.3.0: version "8.57.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz" integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -5417,7 +5386,7 @@ eslint@^8.3.0: espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" @@ -5426,76 +5395,76 @@ espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: esprima@1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.2.tgz#76a0fd66fcfe154fd292667dc264019750b1657b" + resolved "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz" integrity sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A== esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2: version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz" integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== estree-walker@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz" integrity sha512-6/I1dwNKk0N9iGOU3ydzAAurz4NPo/ttxZNCqgIVbWFvWyzWBSNonRrJ5CpjDuyBfmM7ENN7WCzUi9aT/UPXXQ== estree-walker@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== estree-walker@^2.0.1, estree-walker@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== eventemitter3@^4.0.0: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.2.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== execa@^5.0.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -5510,12 +5479,12 @@ execa@^5.0.0: exit@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== expect@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== dependencies: "@jest/expect-utils" "^29.7.0" @@ -5526,7 +5495,7 @@ expect@^29.7.0: express@^4.17.3: version "4.21.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" + resolved "https://registry.npmjs.org/express/-/express-4.21.2.tgz" integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== dependencies: accepts "~1.3.8" @@ -5563,17 +5532,17 @@ express@^4.17.3: extend@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.0.3, fast-glob@^3.2.9: version "3.3.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -5584,57 +5553,57 @@ fast-glob@^3.0.3, fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: version "3.1.0" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz" integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== fastq@^1.6.0: version "1.19.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz" integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== dependencies: reusify "^1.0.4" fault@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz" integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== dependencies: format "^0.2.0" faye-websocket@^0.11.3: version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" fb-watchman@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" file-loader@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" @@ -5642,38 +5611,38 @@ file-loader@^6.2.0: file-selector@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.4.0.tgz#59ec4f27aa5baf0841e9c6385c8386bef4d18b17" + resolved "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz" integrity sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg== dependencies: tslib "^2.0.3" filelist@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: minimatch "^5.0.1" filesize@^8.0.6: version "8.0.7" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" + resolved "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz" integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" filter-obj@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz" integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== finalhandler@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz" integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" @@ -5686,7 +5655,7 @@ finalhandler@1.3.1: find-cache-dir@^3.3.1: version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== dependencies: commondir "^1.0.1" @@ -5695,19 +5664,19 @@ find-cache-dir@^3.3.1: find-root@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== find-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.0.0" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -5715,7 +5684,7 @@ find-up@^4.0.0, find-up@^4.1.0: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -5723,7 +5692,7 @@ find-up@^5.0.0: flat-cache@^3.0.4: version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" @@ -5732,31 +5701,31 @@ flat-cache@^3.0.4: flatted@^3.2.9: version "3.3.3" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz" integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== focus-lock@^1.3.6: version "1.3.6" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.3.6.tgz#955eec1e10591d56f679258edb94aedb11d691cd" + resolved "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.6.tgz" integrity sha512-Ik/6OCk9RQQ0T5Xw+hKNLWrjSMtv51dD4GRmJjbD5a58TIEpI5a5iXagKVl3Z5UuyslMCA8Xwnu76jQob62Yhg== dependencies: tslib "^2.0.3" follow-redirects@^1.0.0: version "1.15.11" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz" integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== for-each@^0.3.3, for-each@^0.3.5: version "0.3.5" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz" integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== dependencies: is-callable "^1.2.7" fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz" integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== dependencies: "@babel/code-frame" "^7.8.3" @@ -5775,7 +5744,7 @@ fork-ts-checker-webpack-plugin@^6.5.0: form-data@^4.0.0: version "4.0.5" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.5.tgz#b49e48858045ff4cbf6b03e1805cebcad3679053" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz" integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== dependencies: asynckit "^0.4.0" @@ -5786,27 +5755,27 @@ form-data@^4.0.0: format@^0.2.0: version "0.2.2" - resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== forwarded@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fraction.js@^5.3.4: version "5.3.4" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz" integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== fresh@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^10.0.0: version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" @@ -5815,7 +5784,7 @@ fs-extra@^10.0.0: fs-extra@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: graceful-fs "^4.2.0" @@ -5824,7 +5793,7 @@ fs-extra@^8.1.0: fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -5834,27 +5803,27 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: fs-monkey@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.1.0.tgz#632aa15a20e71828ed56b24303363fb1414e5997" + resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz" integrity sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== function.prototype.name@^1.1.6, function.prototype.name@^1.1.8: version "1.1.8" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz" integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q== dependencies: call-bind "^1.0.8" @@ -5866,27 +5835,27 @@ function.prototype.name@^1.1.6, function.prototype.name@^1.1.8: functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== generator-function@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2" + resolved "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz" integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== dependencies: call-bind-apply-helpers "^1.0.2" @@ -5902,22 +5871,22 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@ get-nonce@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + resolved "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz" integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-proto@^1.0.0, get-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== dependencies: dunder-proto "^1.0.1" @@ -5925,12 +5894,12 @@ get-proto@^1.0.0, get-proto@^1.0.1: get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-symbol-description@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz" integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== dependencies: call-bound "^1.0.3" @@ -5939,26 +5908,26 @@ get-symbol-description@^1.1.0: glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" glob-to-regexp@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -5970,7 +5939,7 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: glob@^8.0.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" @@ -5981,14 +5950,14 @@ glob@^8.0.0: global-modules@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== dependencies: global-prefix "^3.0.0" global-prefix@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz" integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== dependencies: ini "^1.3.5" @@ -5997,14 +5966,14 @@ global-prefix@^3.0.0: globals@^13.19.0: version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globalthis@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz" integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: define-properties "^1.2.1" @@ -6012,7 +5981,7 @@ globalthis@^1.0.4: globby@10.0.1: version "10.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22" + resolved "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz" integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A== dependencies: "@types/glob" "^7.1.1" @@ -6026,7 +5995,7 @@ globby@10.0.1: globby@^11.0.4, globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -6038,46 +6007,46 @@ globby@^11.0.4, globby@^11.1.0: gopd@^1.0.1, gopd@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== graphlib@^2.1.8: version "2.1.8" - resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + resolved "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz" integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== dependencies: lodash "^4.17.15" graphql@^16.8.1: version "16.12.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.12.0.tgz#28cc2462435b1ac3fdc6976d030cef83a0c13ac7" + resolved "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz" integrity sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ== gzip-size@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + resolved "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz" integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== dependencies: duplexer "^0.1.2" handle-thing@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== happy-dom@^16.8.1: version "16.8.1" - resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-16.8.1.tgz#43d7e998fd36aa6062acbdfa88262ef0bc0a105e" + resolved "https://registry.npmjs.org/happy-dom/-/happy-dom-16.8.1.tgz" integrity sha512-n0QrmT9lD81rbpKsyhnlz3DgnMZlaOkJPpgi746doA+HvaMC79bdWkwjrNnGJRvDrWTI8iOcJiVTJ5CdT/AZRw== dependencies: webidl-conversions "^7.0.0" @@ -6085,55 +6054,55 @@ happy-dom@^16.8.1: harmony-reflect@^1.4.6: version "1.6.2" - resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + resolved "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz" integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== has-bigints@^1.0.2: version "1.1.0" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz" integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz" integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: es-define-property "^1.0.0" has-proto@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz" integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== dependencies: dunder-proto "^1.0.0" has-symbols@^1.0.3, has-symbols@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== has-tostringtag@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: has-symbols "^1.0.3" hasown@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" hast-to-hyperscript@^9.0.0: version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" + resolved "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz" integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== dependencies: "@types/unist" "^2.0.3" @@ -6146,7 +6115,7 @@ hast-to-hyperscript@^9.0.0: hast-util-from-parse5@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" + resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz" integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== dependencies: "@types/parse5" "^5.0.0" @@ -6158,17 +6127,17 @@ hast-util-from-parse5@^6.0.0: hast-util-is-element@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425" + resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz" integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ== hast-util-parse-selector@^2.0.0: version "2.2.5" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz" integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== hast-util-raw@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.1.0.tgz#e16a3c2642f65cc7c480c165400a40d604ab75d0" + resolved "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.1.0.tgz" integrity sha512-5FoZLDHBpka20OlZZ4I/+RBw5piVQ8iI1doEvffQhx5CbCyTtP8UCq8Tw6NmTAMtXgsQxmhW7Ly8OdFre5/YMQ== dependencies: "@types/hast" "^2.0.0" @@ -6185,7 +6154,7 @@ hast-util-raw@^6.1.0: hast-util-to-html@^7.1.1: version "7.1.3" - resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz#9f339ca9bea71246e565fc79ff7dbfe98bb50f5e" + resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz" integrity sha512-yk2+1p3EJTEE9ZEUkgHsUSVhIpCsL/bvT8E5GzmWc+N1Po5gBw+0F8bo7dpxXR0nu0bQVxVZGX2lBGF21CmeDw== dependencies: ccount "^1.0.0" @@ -6201,7 +6170,7 @@ hast-util-to-html@^7.1.1: hast-util-to-parse5@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" + resolved "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz" integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== dependencies: hast-to-hyperscript "^9.0.0" @@ -6212,12 +6181,12 @@ hast-util-to-parse5@^6.0.0: hast-util-whitespace@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz" integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A== hastscript@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz" integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== dependencies: "@types/hast" "^2.0.0" @@ -6228,39 +6197,39 @@ hastscript@^6.0.0: he@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== headers-polyfill@^4.0.2: version "4.0.3" - resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" + resolved "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz" integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== highlight.js@^10.4.1, highlight.js@~10.7.0: version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== highlightjs-vue@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz#fdfe97fbea6354e70ee44e3a955875e114db086d" + resolved "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz" integrity sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA== hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: react-is "^16.7.0" hoopy@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + resolved "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz" integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== hpack.js@^2.1.6: version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== dependencies: inherits "^2.0.1" @@ -6270,24 +6239,24 @@ hpack.js@^2.1.6: html-encoding-sniffer@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz" integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== dependencies: whatwg-encoding "^2.0.0" html-entities@^2.1.0, html-entities@^2.3.2: version "2.6.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" + resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== html-minifier-terser@^6.0.2: version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + resolved "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== dependencies: camel-case "^4.1.2" @@ -6300,12 +6269,12 @@ html-minifier-terser@^6.0.2: html-void-elements@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== html-webpack-plugin@^5.5.0: version "5.6.5" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz#d57defb83cabbf29bf56b2d4bf10b67b650066be" + resolved "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz" integrity sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g== dependencies: "@types/html-minifier-terser" "^6.0.0" @@ -6316,7 +6285,7 @@ html-webpack-plugin@^5.5.0: htmlparser2@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz" integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== dependencies: domelementtype "^2.0.1" @@ -6326,12 +6295,12 @@ htmlparser2@^6.1.0: http-deceiver@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== http-errors@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: depd "2.0.0" @@ -6342,7 +6311,7 @@ http-errors@2.0.0: http-errors@~1.6.2: version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== dependencies: depd "~1.1.2" @@ -6352,12 +6321,12 @@ http-errors@~1.6.2: http-parser-js@>=0.5.1: version "0.5.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz" integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== http-proxy-agent@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: "@tootallnate/once" "2" @@ -6366,7 +6335,7 @@ http-proxy-agent@^5.0.0: http-proxy-middleware@^2.0.3: version "2.0.9" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz" integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== dependencies: "@types/http-proxy" "^1.17.8" @@ -6377,7 +6346,7 @@ http-proxy-middleware@^2.0.3: http-proxy@^1.18.1: version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: eventemitter3 "^4.0.0" @@ -6386,7 +6355,7 @@ http-proxy@^1.18.1: https-proxy-agent@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -6394,53 +6363,53 @@ https-proxy-agent@^5.0.1: human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== iconv-lite@0.4.24: version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== idb@^7.0.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + resolved "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz" integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== identity-obj-proxy@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + resolved "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz" integrity sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA== dependencies: harmony-reflect "^1.4.6" ignore@^5.1.1, ignore@^5.2.0: version "5.3.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== immer@^9.0.7: version "9.0.21" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz" integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== dependencies: parent-module "^1.0.0" @@ -6448,7 +6417,7 @@ import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: import-local@^3.0.2: version "3.2.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz" integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== dependencies: pkg-dir "^4.2.0" @@ -6456,17 +6425,17 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -6474,32 +6443,32 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== ini@^1.3.5: version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== inline-style-parser@0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== inter-ui@^3.19.3: version "3.19.3" - resolved "https://registry.yarnpkg.com/inter-ui/-/inter-ui-3.19.3.tgz#cf4b4b6d30de8d5463e2462588654b325206488c" + resolved "https://registry.npmjs.org/inter-ui/-/inter-ui-3.19.3.tgz" integrity sha512-5FG9fjuYOXocIfjzcCBhICL5cpvwEetseL3FU6tP3d6Bn7g8wODhB+I9RNGRTizCT7CUG4GOK54OPxqq3msQgg== internal-slot@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz" integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== dependencies: es-errors "^1.3.0" @@ -6508,22 +6477,22 @@ internal-slot@^1.1.0: ipaddr.js@1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== ipaddr.js@^2.0.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== is-alphabetical@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== is-alphanumerical@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== dependencies: is-alphabetical "^1.0.0" @@ -6531,7 +6500,7 @@ is-alphanumerical@^1.0.0: is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: version "3.0.5" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz" integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== dependencies: call-bind "^1.0.8" @@ -6540,12 +6509,12 @@ is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-async-function@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.1.1.tgz#3e69018c8e04e73b738793d020bfe884b9fd3523" + resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz" integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ== dependencies: async-function "^1.0.0" @@ -6556,21 +6525,21 @@ is-async-function@^2.0.0: is-bigint@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz" integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== dependencies: has-bigints "^1.0.2" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.2.1: version "1.2.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz" integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A== dependencies: call-bound "^1.0.3" @@ -6578,31 +6547,31 @@ is-boolean-object@^1.2.1: is-buffer@^2.0.0: version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== is-builtin-module@^3.1.0: version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz" integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== dependencies: builtin-modules "^3.3.0" is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.13.0, is-core-module@^2.16.1: version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz" integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: hasown "^2.0.2" is-data-view@^1.0.1, is-data-view@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e" + resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz" integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== dependencies: call-bound "^1.0.2" @@ -6611,7 +6580,7 @@ is-data-view@^1.0.1, is-data-view@^1.0.2: is-date-object@^1.0.5, is-date-object@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz" integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== dependencies: call-bound "^1.0.2" @@ -6619,39 +6588,39 @@ is-date-object@^1.0.5, is-date-object@^1.1.0: is-decimal@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-finalizationregistry@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90" + resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz" integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== dependencies: call-bound "^1.0.3" is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-fn@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-generator-function@^1.0.10: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5" + resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz" integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA== dependencies: call-bound "^1.0.4" @@ -6662,39 +6631,39 @@ is-generator-function@^1.0.10: is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-hexadecimal@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== is-map@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz" integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== is-module@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== is-negative-zero@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-node-process@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" + resolved "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz" integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== is-number-object@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz" integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== dependencies: call-bound "^1.0.3" @@ -6702,54 +6671,54 @@ is-number-object@^1.1.1: is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-obj@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-plain-obj@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== is-plain-object@5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== is-plain-object@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz" integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g== is-potential-custom-element-name@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-reference@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + resolved "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz" integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== dependencies: "@types/estree" "*" is-regex@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz" integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== dependencies: call-bound "^1.0.2" @@ -6759,34 +6728,34 @@ is-regex@^1.2.1: is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-root@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + resolved "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== is-set@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz" integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== is-shared-array-buffer@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz" integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== dependencies: call-bound "^1.0.3" is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz" integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== dependencies: call-bound "^1.0.3" @@ -6794,7 +6763,7 @@ is-string@^1.1.1: is-symbol@^1.0.4, is-symbol@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz" integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== dependencies: call-bound "^1.0.2" @@ -6803,31 +6772,31 @@ is-symbol@^1.0.4, is-symbol@^1.1.1: is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15: version "1.1.15" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz" integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== dependencies: which-typed-array "^1.1.16" is-typedarray@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== is-weakmap@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz" integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== is-weakref@^1.0.2, is-weakref@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.1.tgz#eea430182be8d64174bd96bffbc46f21bf3f9293" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz" integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew== dependencies: call-bound "^1.0.3" is-weakset@^2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz" integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== dependencies: call-bound "^1.0.3" @@ -6835,44 +6804,44 @@ is-weakset@^2.0.3: is-whitespace-character@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + resolved "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz" integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== is-word-character@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + resolved "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz" integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== is-wsl@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4: version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" @@ -6883,7 +6852,7 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-instrument@^6.0.0: version "6.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz" integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== dependencies: "@babel/core" "^7.23.9" @@ -6894,7 +6863,7 @@ istanbul-lib-instrument@^6.0.0: istanbul-lib-report@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" @@ -6903,7 +6872,7 @@ istanbul-lib-report@^3.0.0: istanbul-lib-source-maps@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" @@ -6912,7 +6881,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-reports@^3.1.3: version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz#cb4535162b5784aa623cee21a7252cf2c807ac93" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz" integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== dependencies: html-escaper "^2.0.0" @@ -6920,7 +6889,7 @@ istanbul-reports@^3.1.3: iterator.prototype@^1.1.4: version "1.1.5" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39" + resolved "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz" integrity sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g== dependencies: define-data-property "^1.1.4" @@ -6932,7 +6901,7 @@ iterator.prototype@^1.1.4: jake@^10.8.5: version "10.9.4" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6" + resolved "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz" integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA== dependencies: async "^3.2.6" @@ -6941,7 +6910,7 @@ jake@^10.8.5: jest-changed-files@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz" integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: execa "^5.0.0" @@ -6950,7 +6919,7 @@ jest-changed-files@^29.7.0: jest-circus@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz" integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== dependencies: "@jest/environment" "^29.7.0" @@ -6976,7 +6945,7 @@ jest-circus@^29.7.0: jest-cli@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz" integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: "@jest/core" "^29.7.0" @@ -6993,7 +6962,7 @@ jest-cli@^29.7.0: jest-config@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz" integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== dependencies: "@babel/core" "^7.11.6" @@ -7021,7 +6990,7 @@ jest-config@^29.7.0: jest-diff@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz" integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== dependencies: chalk "^4.0.0" @@ -7031,7 +7000,7 @@ jest-diff@^27.5.1: jest-diff@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" @@ -7041,14 +7010,14 @@ jest-diff@^29.7.0: jest-docblock@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz" integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== dependencies: detect-newline "^3.0.0" jest-each@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz" integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== dependencies: "@jest/types" "^29.6.3" @@ -7059,7 +7028,7 @@ jest-each@^29.7.0: jest-environment-jsdom@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f" + resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz" integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA== dependencies: "@jest/environment" "^29.7.0" @@ -7073,7 +7042,7 @@ jest-environment-jsdom@^29.7.0: jest-environment-node@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: "@jest/environment" "^29.7.0" @@ -7085,17 +7054,17 @@ jest-environment-node@^29.7.0: jest-get-type@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== jest-get-type@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== jest-haste-map@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz" integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== dependencies: "@jest/types" "^27.5.1" @@ -7115,7 +7084,7 @@ jest-haste-map@^27.5.1: jest-haste-map@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz" integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== dependencies: "@jest/types" "^29.6.3" @@ -7134,7 +7103,7 @@ jest-haste-map@^29.7.0: jest-leak-detector@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz" integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== dependencies: jest-get-type "^29.6.3" @@ -7142,7 +7111,7 @@ jest-leak-detector@^29.7.0: jest-matcher-utils@^27.0.0: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz" integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== dependencies: chalk "^4.0.0" @@ -7152,7 +7121,7 @@ jest-matcher-utils@^27.0.0: jest-matcher-utils@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== dependencies: chalk "^4.0.0" @@ -7162,7 +7131,7 @@ jest-matcher-utils@^29.7.0: jest-message-util@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" @@ -7177,7 +7146,7 @@ jest-message-util@^29.7.0: jest-mock@^29.4.0, jest-mock@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz" integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: "@jest/types" "^29.6.3" @@ -7186,22 +7155,22 @@ jest-mock@^29.4.0, jest-mock@^29.7.0: jest-pnp-resolver@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== jest-regex-util@^29.0.0, jest-regex-util@^29.6.3: version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== jest-resolve-dependencies@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz" integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: jest-regex-util "^29.6.3" @@ -7209,7 +7178,7 @@ jest-resolve-dependencies@^29.7.0: jest-resolve@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== dependencies: chalk "^4.0.0" @@ -7224,7 +7193,7 @@ jest-resolve@^29.7.0: jest-runner@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz" integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== dependencies: "@jest/console" "^29.7.0" @@ -7251,7 +7220,7 @@ jest-runner@^29.7.0: jest-runtime@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz" integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== dependencies: "@jest/environment" "^29.7.0" @@ -7279,7 +7248,7 @@ jest-runtime@^29.7.0: jest-serializer@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz" integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== dependencies: "@types/node" "*" @@ -7287,7 +7256,7 @@ jest-serializer@^27.5.1: jest-snapshot@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz" integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== dependencies: "@babel/core" "^7.11.6" @@ -7313,7 +7282,7 @@ jest-snapshot@^29.7.0: jest-util@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz" integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== dependencies: "@jest/types" "^27.5.1" @@ -7325,7 +7294,7 @@ jest-util@^27.5.1: jest-util@^29.4.0, jest-util@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: "@jest/types" "^29.6.3" @@ -7337,7 +7306,7 @@ jest-util@^29.4.0, jest-util@^29.7.0: jest-validate@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz" integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: "@jest/types" "^29.6.3" @@ -7349,7 +7318,7 @@ jest-validate@^29.7.0: jest-watch-typeahead@^2.2.2: version "2.2.2" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-2.2.2.tgz#5516d3cd006485caa5cfc9bd1de40f1f8b136abf" + resolved "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-2.2.2.tgz" integrity sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ== dependencies: ansi-escapes "^6.0.0" @@ -7362,7 +7331,7 @@ jest-watch-typeahead@^2.2.2: jest-watcher@^29.0.0, jest-watcher@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz" integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== dependencies: "@jest/test-result" "^29.7.0" @@ -7376,7 +7345,7 @@ jest-watcher@^29.0.0, jest-watcher@^29.7.0: jest-worker@^26.2.1: version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" @@ -7385,7 +7354,7 @@ jest-worker@^26.2.1: jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" @@ -7394,7 +7363,7 @@ jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: jest-worker@^28.0.2: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz" integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== dependencies: "@types/node" "*" @@ -7403,7 +7372,7 @@ jest-worker@^28.0.2: jest-worker@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz" integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" @@ -7413,7 +7382,7 @@ jest-worker@^29.7.0: jest@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: "@jest/core" "^29.7.0" @@ -7423,17 +7392,17 @@ jest@^29.7.0: js-sha3@0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.2" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz" integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== dependencies: argparse "^1.0.7" @@ -7441,21 +7410,21 @@ js-yaml@^3.13.1: js-yaml@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz" integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== dependencies: argparse "^2.0.1" js2xmlparser@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz#2a1fdf01e90585ef2ae872a01bc169c6a8d5e60a" + resolved "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz" integrity sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA== dependencies: xmlcreate "^2.0.4" jsdoc@^4.0.0: version "4.0.5" - resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-4.0.5.tgz#fbed70e04a3abcf2143dad6b184947682bbc7315" + resolved "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.5.tgz" integrity sha512-P4C6MWP9yIlMiK8nwoZvxN84vb6MsnXcHuy7XzVOvQoCizWX5JFCBsWIIWKXBltpoRZXddUOVQmCTOZt9yDj9g== dependencies: "@babel/parser" "^7.20.15" @@ -7476,7 +7445,7 @@ jsdoc@^4.0.0: jsdom@^20.0.0: version "20.0.3" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz" integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== dependencies: abab "^2.0.6" @@ -7508,61 +7477,61 @@ jsdom@^20.0.0: jsesc@^3.0.2, jsesc@~3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== json-buffer@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-schema@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" json5@^2.1.2, json5@^2.2.0, json5@^2.2.3: version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== optionalDependencies: graceful-fs "^4.1.6" jsonfile@^6.0.1: version "6.2.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz" integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== dependencies: universalify "^2.0.0" @@ -7571,7 +7540,7 @@ jsonfile@^6.0.1: jsonpath@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-1.1.1.tgz#0ca1ed8fb65bb3309248cc9d5466d12d5b0b9901" + resolved "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz" integrity sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w== dependencies: esprima "1.2.2" @@ -7580,12 +7549,12 @@ jsonpath@^1.1.1: jsonpointer@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== dependencies: array-includes "^3.1.6" @@ -7595,48 +7564,48 @@ jsonpointer@^5.0.0: keyv@^4.5.3: version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" kind-of@^6.0.2: version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== klaw@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + resolved "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz" integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== dependencies: graceful-fs "^4.1.9" kleur@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== klona@^2.0.4, klona@^2.0.5: version "2.0.6" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== language-subtag-registry@^0.3.20: version "0.3.23" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" + resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz" integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== language-tags@^1.0.9: version "1.0.9" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz" integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== dependencies: language-subtag-registry "^0.3.20" launch-editor@^2.6.0: version "2.12.0" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.12.0.tgz#cc740f4e0263a6b62ead2485f9896e545321f817" + resolved "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz" integrity sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg== dependencies: picocolors "^1.1.1" @@ -7644,12 +7613,12 @@ launch-editor@^2.6.0: leven@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -7657,7 +7626,7 @@ levn@^0.4.1: levn@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== dependencies: prelude-ls "~1.1.2" @@ -7665,29 +7634,29 @@ levn@~0.3.0: lilconfig@^2.0.3: version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== linkify-it@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" + resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz" integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== dependencies: uc.micro "^2.0.0" loader-runner@^4.3.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz" integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" @@ -7696,12 +7665,12 @@ loader-utils@^2.0.0, loader-utils@^2.0.4: loader-utils@^3.2.0: version "3.3.1" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.3.1.tgz#735b9a19fd63648ca7adbd31c2327dfe281304e5" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz" integrity sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg== locate-path@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: p-locate "^3.0.0" @@ -7709,70 +7678,70 @@ locate-path@^3.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.debounce@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.memoize@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.sortby@^4.7.0: version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== lodash.uniq@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== long@^5.0.0, long@^5.2.3: version "5.3.2" - resolved "https://registry.yarnpkg.com/long/-/long-5.3.2.tgz#1d84463095999262d7d7b7f8bfd4a8cc55167f83" + resolved "https://registry.npmjs.org/long/-/long-5.3.2.tgz" integrity sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA== loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lower-case@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== dependencies: tslib "^2.0.3" lowlight@^1.17.0: version "1.20.0" - resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz" integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== dependencies: fault "^1.0.0" @@ -7780,57 +7749,57 @@ lowlight@^1.17.0: lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lz-string@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== magic-string@^0.25.0, magic-string@^0.25.7: version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== dependencies: sourcemap-codec "^1.4.8" make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" make-dir@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: semver "^7.5.3" makeerror@1.0.12: version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: tmpl "1.0.5" markdown-escapes@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + resolved "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== markdown-it-anchor@^8.6.7: version "8.6.7" - resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz#ee6926daf3ad1ed5e4e3968b1740eef1c6399634" + resolved "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz" integrity sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA== markdown-it@^14.1.0: version "14.1.0" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz" integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg== dependencies: argparse "^2.0.1" @@ -7842,32 +7811,32 @@ markdown-it@^14.1.0: marked@^4.0.10: version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" + resolved "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz" integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== match-sorter@^6.0.2: - version "6.4.0" - resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.4.0.tgz#ae9c166cb3c9efd337690b3160c0e28cb8377c13" - integrity sha512-d4664ahzdL1QTTvmK1iI0JsrxWeJ6gn33qkYtnPg3mcn+naBLtXSgSPOe+X2vUgtgGwaAk3eiaj7gwKjjMAq+Q== + version "6.3.4" + resolved "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz" + integrity sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg== dependencies: "@babel/runtime" "^7.23.8" remove-accents "0.5.0" math-intrinsics@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== mdast-util-definitions@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" + resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz" integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== dependencies: unist-util-visit "^2.0.0" mdast-util-to-hast@^10.2.0: version "10.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz" integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ== dependencies: "@types/mdast" "^3.0.0" @@ -7881,74 +7850,74 @@ mdast-util-to-hast@^10.2.0: mdn-data@2.0.14: version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== mdn-data@2.0.28: version "2.0.28" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz" integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== mdn-data@2.0.30: version "2.0.30" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz" integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== mdurl@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== mdurl@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" + resolved "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz" integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w== media-typer@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memfs@^3.1.2, memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + version "3.5.3" + resolved "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz" + integrity sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw== dependencies: fs-monkey "^1.0.4" "memoize-one@>=3.1.1 <6": version "5.2.1" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== memoize-one@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" + resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz" integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== merge-descriptors@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz" integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== methods@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: braces "^3.0.3" @@ -7956,44 +7925,39 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8: microseconds@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz" integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== -mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== min-indent@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== mini-css-extract-plugin@^2.4.5: version "2.9.4" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz#cafa1a42f8c71357f49cd1566810d74ff1cb0200" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz" integrity sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ== dependencies: schema-utils "^4.0.0" @@ -8001,58 +7965,58 @@ mini-css-extract-plugin@^2.4.5: minimalistic-assert@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimatch@*, minimatch@^10.0.3: version "10.1.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz" integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ== dependencies: "@isaacs/brace-expansion" "^5.0.0" minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" minimatch@^5.0.1: version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== moment@^2.29.1: version "2.30.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + resolved "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz" integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.3, ms@^2.1.1, ms@^2.1.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== msw@^2.7.0: version "2.12.2" - resolved "https://registry.yarnpkg.com/msw/-/msw-2.12.2.tgz#9e5c25ca5cffce6e9bd96c8ae1105096e81a82a2" + resolved "https://registry.npmjs.org/msw/-/msw-2.12.2.tgz" integrity sha512-Fsr8AR5Yu6C0thoWa1Z8qGBFQLDvLsWlAn/v3CNLiUizoRqBYArK3Ex3thXpMWRr1Li5/MKLOEZ5mLygUmWi1A== dependencies: "@inquirer/confirm" "^5.0.0" @@ -8076,7 +8040,7 @@ msw@^2.7.0: multicast-dns@^7.2.5: version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== dependencies: dns-packet "^5.2.2" @@ -8084,49 +8048,49 @@ multicast-dns@^7.2.5: mute-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz" integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== nano-time@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + resolved "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz" integrity sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA== dependencies: big-integer "^1.6.16" nanoid@^3.3.11, nanoid@^3.3.7: version "3.3.11" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== natural-compare-lite@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3: version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== negotiator@~0.6.4: version "0.6.4" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== neo-async@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== no-case@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== dependencies: lower-case "^2.0.2" @@ -8134,58 +8098,58 @@ no-case@^3.0.4: node-emoji@^1.10.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + resolved "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz" integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== dependencies: lodash "^4.17.21" node-forge@^1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.3.tgz#0ad80f6333b3a0045e827ac20b7f735f93716751" - integrity sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg== + version "1.3.1" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-int64@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-releases@^2.0.27: version "2.0.27" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-range@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== normalize-url@^6.0.1: version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" nth-check@^2.0.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== dependencies: boolbase "^1.0.0" numeral@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" + resolved "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz" integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA== nwsapi@2.2.13, nwsapi@^2.2.2: @@ -8195,22 +8159,22 @@ nwsapi@2.2.13, nwsapi@^2.2.2: object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-inspect@^1.13.3, object-inspect@^1.13.4: version "1.13.4" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.4, object.assign@^4.1.7: version "4.1.7" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz" integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== dependencies: call-bind "^1.0.8" @@ -8222,7 +8186,7 @@ object.assign@^4.1.4, object.assign@^4.1.7: object.entries@^1.1.9: version "1.1.9" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.9.tgz#e4770a6a1444afb61bd39f984018b5bede25f8b3" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz" integrity sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw== dependencies: call-bind "^1.0.8" @@ -8232,7 +8196,7 @@ object.entries@^1.1.9: object.fromentries@^2.0.8: version "2.0.8" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz" integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: call-bind "^1.0.7" @@ -8242,7 +8206,7 @@ object.fromentries@^2.0.8: object.groupby@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz" integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== dependencies: call-bind "^1.0.7" @@ -8251,7 +8215,7 @@ object.groupby@^1.0.3: object.values@^1.1.6, object.values@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz" integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== dependencies: call-bind "^1.0.8" @@ -8261,43 +8225,43 @@ object.values@^1.1.6, object.values@^1.2.1: oblivious-set@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" + resolved "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz" integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== on-finished@2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" on-headers@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz" integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" open@^8.0.9, open@^8.4.0: version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== dependencies: define-lazy-prop "^2.0.0" @@ -8306,7 +8270,7 @@ open@^8.0.9, open@^8.4.0: optionator@^0.8.1: version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" @@ -8318,7 +8282,7 @@ optionator@^0.8.1: optionator@^0.9.3: version "0.9.4" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz" integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: deep-is "^0.1.3" @@ -8330,12 +8294,12 @@ optionator@^0.9.3: outvariant@^1.4.0, outvariant@^1.4.3: version "1.4.3" - resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873" + resolved "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz" integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== own-keys@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" + resolved "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz" integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== dependencies: get-intrinsic "^1.2.6" @@ -8344,42 +8308,42 @@ own-keys@^1.0.1: p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: p-limit "^2.0.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-retry@^4.5.0: version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== dependencies: "@types/retry" "0.12.0" @@ -8387,12 +8351,12 @@ p-retry@^4.5.0: p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== param-case@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz" integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: dot-case "^3.0.4" @@ -8400,14 +8364,14 @@ param-case@^3.0.4: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-entities@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== dependencies: character-entities "^1.0.0" @@ -8419,7 +8383,7 @@ parse-entities@^2.0.0: parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -8429,24 +8393,24 @@ parse-json@^5.0.0, parse-json@^5.2.0: parse5@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parse5@^7.0.0, parse5@^7.1.1: version "7.3.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz" integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== dependencies: entities "^6.0.0" parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascal-case@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + resolved "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz" integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== dependencies: no-case "^3.0.4" @@ -8454,103 +8418,103 @@ pascal-case@^3.1.2: path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-to-regexp@0.1.12: version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz" integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== path-to-regexp@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz" integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== picocolors@1.1.1, picocolors@^1.0.0, picocolors@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== picomatch@^4.0.2: version "4.0.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== pirates@^4.0.4: version "4.0.7" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz" integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" pkg-up@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz" integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== dependencies: find-up "^3.0.0" possible-typed-array-names@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz" integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== postcss-attribute-case-insensitive@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" + resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz" integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== dependencies: postcss-selector-parser "^6.0.10" postcss-browser-comments@^4: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz#bcfc86134df5807f5d3c0eefa191d42136b5e72a" + resolved "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz" integrity sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg== postcss-calc@^8.2.3: version "8.2.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz" integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== dependencies: postcss-selector-parser "^6.0.9" @@ -8558,35 +8522,35 @@ postcss-calc@^8.2.3: postcss-clamp@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + resolved "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz" integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== dependencies: postcss-value-parser "^4.2.0" postcss-color-functional-notation@^4.2.4: version "4.2.4" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz#21a909e8d7454d3612d1659e471ce4696f28caec" + resolved "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz" integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== dependencies: postcss-value-parser "^4.2.0" postcss-color-hex-alpha@^8.0.4: version "8.0.4" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz#c66e2980f2fbc1a63f5b079663340ce8b55f25a5" + resolved "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz" integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== dependencies: postcss-value-parser "^4.2.0" postcss-color-rebeccapurple@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz#63fdab91d878ebc4dd4b7c02619a0c3d6a56ced0" + resolved "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz" integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== dependencies: postcss-value-parser "^4.2.0" postcss-colormin@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + resolved "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz" integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== dependencies: browserslist "^4.21.4" @@ -8596,7 +8560,7 @@ postcss-colormin@^5.3.1: postcss-convert-values@^5.1.3: version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + resolved "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz" integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== dependencies: browserslist "^4.21.4" @@ -8604,55 +8568,55 @@ postcss-convert-values@^5.1.3: postcss-custom-media@^8.0.2: version "8.0.2" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz#c8f9637edf45fef761b014c024cee013f80529ea" + resolved "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz" integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== dependencies: postcss-value-parser "^4.2.0" postcss-custom-properties@^12.1.10: version "12.1.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz#d14bb9b3989ac4d40aaa0e110b43be67ac7845cf" + resolved "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz" integrity sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ== dependencies: postcss-value-parser "^4.2.0" postcss-custom-selectors@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz#1ab4684d65f30fed175520f82d223db0337239d9" + resolved "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz" integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== dependencies: postcss-selector-parser "^6.0.4" postcss-dir-pseudo-class@^6.0.5: version "6.0.5" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz#2bf31de5de76added44e0a25ecf60ae9f7c7c26c" + resolved "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz" integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== dependencies: postcss-selector-parser "^6.0.10" postcss-discard-comments@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + resolved "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz" integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== postcss-discard-duplicates@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + resolved "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz" integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== postcss-discard-empty@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + resolved "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz" integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== postcss-discard-overridden@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + resolved "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz" integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== postcss-double-position-gradients@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz#b96318fdb477be95997e86edd29c6e3557a49b91" + resolved "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz" integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== dependencies: "@csstools/postcss-progressive-custom-properties" "^1.1.0" @@ -8660,55 +8624,55 @@ postcss-double-position-gradients@^3.1.2: postcss-env-function@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" + resolved "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz" integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== dependencies: postcss-value-parser "^4.2.0" postcss-flexbugs-fixes@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" + resolved "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz" integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== postcss-focus-visible@^6.0.4: version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + resolved "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz" integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== dependencies: postcss-selector-parser "^6.0.9" postcss-focus-within@^5.0.4: version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + resolved "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz" integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== dependencies: postcss-selector-parser "^6.0.9" postcss-font-variant@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + resolved "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz" integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== postcss-gap-properties@^3.0.5: version "3.0.5" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz#f7e3cddcf73ee19e94ccf7cb77773f9560aa2fff" + resolved "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz" integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== postcss-image-set-function@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz#08353bd756f1cbfb3b6e93182c7829879114481f" + resolved "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz" integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== dependencies: postcss-value-parser "^4.2.0" postcss-initial@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + resolved "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz" integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== postcss-lab-function@^4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz#6fe4c015102ff7cd27d1bd5385582f67ebdbdc98" + resolved "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz" integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== dependencies: "@csstools/postcss-progressive-custom-properties" "^1.1.0" @@ -8716,7 +8680,7 @@ postcss-lab-function@^4.2.1: postcss-loader@^6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz" integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== dependencies: cosmiconfig "^7.0.0" @@ -8725,17 +8689,17 @@ postcss-loader@^6.2.1: postcss-logical@^5.0.4: version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + resolved "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz" integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== postcss-media-minmax@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + resolved "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz" integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== postcss-merge-longhand@^5.1.7: version "5.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + resolved "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz" integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== dependencies: postcss-value-parser "^4.2.0" @@ -8743,7 +8707,7 @@ postcss-merge-longhand@^5.1.7: postcss-merge-rules@^5.1.4: version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + resolved "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz" integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== dependencies: browserslist "^4.21.4" @@ -8753,14 +8717,14 @@ postcss-merge-rules@^5.1.4: postcss-minify-font-values@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + resolved "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz" integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== dependencies: postcss-value-parser "^4.2.0" postcss-minify-gradients@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + resolved "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz" integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== dependencies: colord "^2.9.1" @@ -8769,7 +8733,7 @@ postcss-minify-gradients@^5.1.1: postcss-minify-params@^5.1.4: version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + resolved "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz" integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== dependencies: browserslist "^4.21.4" @@ -8778,19 +8742,19 @@ postcss-minify-params@^5.1.4: postcss-minify-selectors@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + resolved "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz" integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== dependencies: postcss-selector-parser "^6.0.5" postcss-modules-extract-imports@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz" integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== postcss-modules-local-by-default@^4.0.5: version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz#d150f43837831dae25e4085596e84f6f5d6ec368" + resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz" integrity sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw== dependencies: icss-utils "^5.0.0" @@ -8799,21 +8763,21 @@ postcss-modules-local-by-default@^4.0.5: postcss-modules-scope@^3.2.0: version "3.2.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c" + resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz" integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA== dependencies: postcss-selector-parser "^7.0.0" postcss-modules-values@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== dependencies: icss-utils "^5.0.0" postcss-nesting@^10.2.0: version "10.2.0" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be" + resolved "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz" integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== dependencies: "@csstools/selector-specificity" "^2.0.0" @@ -8821,47 +8785,47 @@ postcss-nesting@^10.2.0: postcss-normalize-charset@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + resolved "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz" integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== postcss-normalize-display-values@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + resolved "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz" integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== dependencies: postcss-value-parser "^4.2.0" postcss-normalize-positions@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + resolved "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz" integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== dependencies: postcss-value-parser "^4.2.0" postcss-normalize-repeat-style@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + resolved "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz" integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== dependencies: postcss-value-parser "^4.2.0" postcss-normalize-string@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + resolved "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz" integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== dependencies: postcss-value-parser "^4.2.0" postcss-normalize-timing-functions@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + resolved "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz" integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== dependencies: postcss-value-parser "^4.2.0" postcss-normalize-unicode@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + resolved "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz" integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== dependencies: browserslist "^4.21.4" @@ -8869,7 +8833,7 @@ postcss-normalize-unicode@^5.1.1: postcss-normalize-url@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + resolved "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz" integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== dependencies: normalize-url "^6.0.1" @@ -8877,14 +8841,14 @@ postcss-normalize-url@^5.1.0: postcss-normalize-whitespace@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + resolved "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz" integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== dependencies: postcss-value-parser "^4.2.0" postcss-normalize@^10.0.1: version "10.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-10.0.1.tgz#464692676b52792a06b06880a176279216540dd7" + resolved "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz" integrity sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA== dependencies: "@csstools/normalize.css" "*" @@ -8893,12 +8857,12 @@ postcss-normalize@^10.0.1: postcss-opacity-percentage@^1.1.2: version "1.1.3" - resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz#5b89b35551a556e20c5d23eb5260fbfcf5245da6" + resolved "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz" integrity sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A== postcss-ordered-values@^5.1.3: version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + resolved "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz" integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== dependencies: cssnano-utils "^3.1.0" @@ -8906,26 +8870,26 @@ postcss-ordered-values@^5.1.3: postcss-overflow-shorthand@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz#7ed6486fec44b76f0eab15aa4866cda5d55d893e" + resolved "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz" integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== dependencies: postcss-value-parser "^4.2.0" postcss-page-break@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + resolved "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz" integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== postcss-place@^7.0.5: version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.5.tgz#95dbf85fd9656a3a6e60e832b5809914236986c4" + resolved "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz" integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== dependencies: postcss-value-parser "^4.2.0" postcss-preset-env@^7.0.1: version "7.8.3" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz#2a50f5e612c3149cc7af75634e202a5b2ad4f1e2" + resolved "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz" integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag== dependencies: "@csstools/postcss-cascade-layers" "^1.1.1" @@ -8980,14 +8944,14 @@ postcss-preset-env@^7.0.1: postcss-pseudo-class-any-link@^7.1.6: version "7.1.6" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz#2693b221902da772c278def85a4d9a64b6e617ab" + resolved "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz" integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== dependencies: postcss-selector-parser "^6.0.10" postcss-reduce-initial@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + resolved "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz" integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== dependencies: browserslist "^4.21.4" @@ -8995,26 +8959,26 @@ postcss-reduce-initial@^5.1.2: postcss-reduce-transforms@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + resolved "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz" integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== dependencies: postcss-value-parser "^4.2.0" postcss-replace-overflow-wrap@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + resolved "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz" integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== postcss-selector-not@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz#8f0a709bf7d4b45222793fc34409be407537556d" + resolved "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz" integrity sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ== dependencies: postcss-selector-parser "^6.0.10" postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz" integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== dependencies: cssesc "^3.0.0" @@ -9022,7 +8986,7 @@ postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selecto postcss-selector-parser@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz#4d6af97eba65d73bc4d84bcb343e865d7dd16262" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz" integrity sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA== dependencies: cssesc "^3.0.0" @@ -9030,7 +8994,7 @@ postcss-selector-parser@^7.0.0: postcss-svgo@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + resolved "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz" integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== dependencies: postcss-value-parser "^4.2.0" @@ -9038,19 +9002,19 @@ postcss-svgo@^5.1.0: postcss-unique-selectors@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + resolved "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz" integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== dependencies: postcss-selector-parser "^6.0.5" postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@8.4.49: version "8.4.49" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz" integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== dependencies: nanoid "^3.3.7" @@ -9059,7 +9023,7 @@ postcss@8.4.49: postcss@^8.2.14, postcss@^8.3.5, postcss@^8.4.33, postcss@^8.4.4: version "8.5.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== dependencies: nanoid "^3.3.11" @@ -9068,27 +9032,27 @@ postcss@^8.2.14, postcss@^8.3.5, postcss@^8.4.33, postcss@^8.4.4: prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prelude-ls@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== prettier@^3.5.3: version "3.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz" integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: version "5.6.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== pretty-error@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz" integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== dependencies: lodash "^4.17.20" @@ -9096,7 +9060,7 @@ pretty-error@^4.0.0: pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: ansi-regex "^5.0.1" @@ -9105,7 +9069,7 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: pretty-format@^29.7.0: version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: "@jest/schemas" "^29.6.3" @@ -9114,29 +9078,29 @@ pretty-format@^29.7.0: prismjs@^1.30.0: version "1.30.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz" integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== prismjs@~1.27.0: version "1.27.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== promise@^8.1.0: version "8.3.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + resolved "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz" integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== dependencies: asap "~2.0.6" prompts@^2.0.1, prompts@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" @@ -9144,7 +9108,7 @@ prompts@^2.0.1, prompts@^2.4.2: prop-types@^15.6.2, prop-types@^15.8.1: version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" @@ -9153,14 +9117,14 @@ prop-types@^15.6.2, prop-types@^15.8.1: property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== dependencies: xtend "^4.0.0" protobufjs-cli@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/protobufjs-cli/-/protobufjs-cli-1.1.3.tgz#c58b8566784f0fa1aff11e8d875a31de999637fe" + resolved "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.3.tgz" integrity sha512-MqD10lqF+FMsOayFiNOdOGNlXc4iKDCf0ZQPkPR+gizYh9gqUeGTWulABUCdI+N67w5RfJ6xhgX4J8pa8qmMXQ== dependencies: chalk "^4.0.0" @@ -9176,7 +9140,7 @@ protobufjs-cli@^1.1.3: protobufjs@^7.1.1: version "7.5.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.5.4.tgz#885d31fe9c4b37f25d1bb600da30b1c5b37d286a" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz" integrity sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg== dependencies: "@protobufjs/aspromise" "^1.1.2" @@ -9194,7 +9158,7 @@ protobufjs@^7.1.1: proxy-addr@~2.0.7: version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: forwarded "0.2.0" @@ -9202,36 +9166,36 @@ proxy-addr@~2.0.7: psl@^1.1.33: version "1.15.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.15.0.tgz#bdace31896f1d97cec6a79e8224898ce93d974c6" + resolved "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz" integrity sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w== dependencies: punycode "^2.3.1" punycode.js@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" + resolved "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz" integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== pure-rand@^6.0.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== qs@6.13.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz" integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: side-channel "^1.0.6" query-string@^7.1.1: version "7.1.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz" integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== dependencies: decode-uri-component "^0.2.2" @@ -9241,41 +9205,41 @@ query-string@^7.1.1: querystringify@^2.1.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== raf-schd@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a" + resolved "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz" integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== raf@^3.4.1: version "3.4.1" - resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== dependencies: performance-now "^2.1.0" randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== raw-body@2.5.2: version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" @@ -9285,7 +9249,7 @@ raw-body@2.5.2: react-app-polyfill@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" + resolved "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz" integrity sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w== dependencies: core-js "^3.19.2" @@ -9297,14 +9261,14 @@ react-app-polyfill@^3.0.0: react-clientside-effect@^1.2.7: version "1.2.8" - resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.8.tgz#0b90a9d7b2a1823a3a10ed1ea3f651f7e0301cb7" + resolved "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.8.tgz" integrity sha512-ma2FePH0z3px2+WOu6h+YycZcEvFmmxIlAb62cF52bG86eMySciO/EQZeQMXd07kPCYB0a1dWDT5J+KE9mCDUw== dependencies: "@babel/runtime" "^7.12.13" react-code-blocks@^0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/react-code-blocks/-/react-code-blocks-0.1.6.tgz#ec64e7899223d3e910eb916465a66d95ce1ae1b2" + resolved "https://registry.npmjs.org/react-code-blocks/-/react-code-blocks-0.1.6.tgz" integrity sha512-ENNuxG07yO+OuX1ChRje3ieefPRz6yrIpHmebQlaFQgzcAHbUfVeTINpOpoI9bSRSObeYo/OdHsporeToZ7fcg== dependencies: "@babel/runtime" "^7.10.4" @@ -9314,7 +9278,7 @@ react-code-blocks@^0.1.6: react-dev-utils@^12.0.1: version "12.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" + resolved "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz" integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== dependencies: "@babel/code-frame" "^7.16.0" @@ -9344,7 +9308,7 @@ react-dev-utils@^12.0.1: react-dom@^18.3.1: version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" @@ -9352,7 +9316,7 @@ react-dom@^18.3.1: react-dropzone@^11.7.1: version "11.7.1" - resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-11.7.1.tgz#3851bb75b26af0bf1b17ce1449fd980e643b9356" + resolved "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.7.1.tgz" integrity sha512-zxCMwhfPy1olUEbw3FLNPLhAm/HnaYH5aELIEglRbqabizKAdHs0h+WuyOpmA+v1JXn0++fpQDdNfUagWt5hJQ== dependencies: attr-accept "^2.2.2" @@ -9361,7 +9325,7 @@ react-dropzone@^11.7.1: react-element-to-jsx-string@^15.0.0: version "15.0.0" - resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz#1cafd5b6ad41946ffc8755e254da3fc752a01ac6" + resolved "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz" integrity sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ== dependencies: "@base2/pretty-print-object" "1.0.1" @@ -9370,12 +9334,12 @@ react-element-to-jsx-string@^15.0.0: react-error-overlay@^6.0.11: version "6.1.0" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.1.0.tgz#22b86256beb1c5856f08a9a228adb8121dd985f2" + resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz" integrity sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ== react-focus-lock@^2.13.6: version "2.13.6" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.13.6.tgz#29751bf2e4e30f6248673cd87a347c74ff2af672" + resolved "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.6.tgz" integrity sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg== dependencies: "@babel/runtime" "^7.0.0" @@ -9387,7 +9351,7 @@ react-focus-lock@^2.13.6: react-focus-on@^3.9.1: version "3.10.0" - resolved "https://registry.yarnpkg.com/react-focus-on/-/react-focus-on-3.10.0.tgz#60f6af03b59be5a0901f86cf9e24799c33e90327" + resolved "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.10.0.tgz" integrity sha512-r2yQchO6QfV5zB3J4Gj6cTYBoxD369vkt0oKj1NJLA5ChQzxjko6V/dqQ7nvmaUBm5pHC+pa8tzHT9jtsVRFMQ== dependencies: aria-hidden "^1.2.5" @@ -9399,27 +9363,27 @@ react-focus-on@^3.9.1: react-is@18.1.0: version "18.1.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-is@^17.0.1, react-is@^17.0.2: version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-is@^18.0.0: version "18.3.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-query@^3.39.3: version "3.39.3" - resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.39.3.tgz#4cea7127c6c26bdea2de5fb63e51044330b03f35" + resolved "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz" integrity sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g== dependencies: "@babel/runtime" "^7.5.5" @@ -9428,7 +9392,7 @@ react-query@^3.39.3: react-redux@^8.1.3: version "8.1.3" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.3.tgz#4fdc0462d0acb59af29a13c27ffef6f49ab4df46" + resolved "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz" integrity sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw== dependencies: "@babel/runtime" "^7.12.1" @@ -9440,12 +9404,12 @@ react-redux@^8.1.3: react-refresh@^0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.7: version "2.3.8" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223" + resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz" integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== dependencies: react-style-singleton "^2.2.2" @@ -9453,7 +9417,7 @@ react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.7: react-remove-scroll@^2.6.3: version "2.7.1" - resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz#d2101d414f6d81d7d3bf033f3c1cb4785789f753" + resolved "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz" integrity sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA== dependencies: react-remove-scroll-bar "^2.3.7" @@ -9464,7 +9428,7 @@ react-remove-scroll@^2.6.3: react-router-dom@^6.28.0: version "6.30.2" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.30.2.tgz#ee8c161bce4890d34484b552f8510f9af0e22b01" + resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz" integrity sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q== dependencies: "@remix-run/router" "1.23.1" @@ -9472,14 +9436,14 @@ react-router-dom@^6.28.0: react-router@6.30.2: version "6.30.2" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.30.2.tgz#c78a3b40f7011f49a373b1df89492e7d4ec12359" + resolved "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz" integrity sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA== dependencies: "@remix-run/router" "1.23.1" react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: version "2.2.3" - resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388" + resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz" integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== dependencies: get-nonce "^1.0.0" @@ -9487,7 +9451,7 @@ react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: react-syntax-highlighter@^15.5.0: version "15.6.6" - resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.6.6.tgz#77417c81ebdc554300d0332800a2e1efe5b1190b" + resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.6.tgz" integrity sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw== dependencies: "@babel/runtime" "^7.3.1" @@ -9499,12 +9463,12 @@ react-syntax-highlighter@^15.5.0: react-virtualized-auto-sizer@^1.0.24: version "1.0.26" - resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.26.tgz#e9470ef6a778dc4f1d5fd76305fa2d8b610c357a" + resolved "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.26.tgz" integrity sha512-CblNyiNVw2o+hsa5/49NH2ogGxZ+t+3aweRvNSq7TVjDIlwk7ir4lencEg5HxHeSzwNarSkNkiu0qJSOXtxm5A== react-window@^1.8.10: version "1.8.11" - resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.11.tgz#a857b48fa85bd77042d59cc460964ff2e0648525" + resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.11.tgz" integrity sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ== dependencies: "@babel/runtime" "^7.0.0" @@ -9512,14 +9476,14 @@ react-window@^1.8.10: react@^18.3.1: version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" reactflow@^11.11.4: version "11.11.4" - resolved "https://registry.yarnpkg.com/reactflow/-/reactflow-11.11.4.tgz#e3593e313420542caed81aecbd73fb9bc6576653" + resolved "https://registry.npmjs.org/reactflow/-/reactflow-11.11.4.tgz" integrity sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og== dependencies: "@reactflow/background" "11.3.14" @@ -9531,7 +9495,7 @@ reactflow@^11.11.4: readable-stream@^2.0.1: version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" @@ -9544,7 +9508,7 @@ readable-stream@^2.0.1: readable-stream@^3.0.6: version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" @@ -9553,21 +9517,21 @@ readable-stream@^3.0.6: readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" recursive-readdir@^2.2.2: version "2.2.3" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + resolved "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz" integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== dependencies: minimatch "^3.0.5" redent@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== dependencies: indent-string "^4.0.0" @@ -9575,14 +9539,14 @@ redent@^3.0.0: redux@^4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== dependencies: "@babel/runtime" "^7.9.2" reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: version "1.0.10" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9" + resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz" integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw== dependencies: call-bind "^1.0.8" @@ -9596,7 +9560,7 @@ reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: refractor@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" + resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== dependencies: hastscript "^6.0.0" @@ -9605,29 +9569,29 @@ refractor@^3.6.0: regenerate-unicode-properties@^10.2.2: version "10.2.2" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz#aa113812ba899b630658c7623466be71e1f86f66" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz" integrity sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g== dependencies: regenerate "^1.4.2" regenerate@^1.4.2: version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.9: version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regex-parser@^2.2.11: version "2.3.1" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.3.1.tgz#ee3f70e50bdd81a221d505242cb9a9c275a2ad91" + resolved "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz" integrity sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ== regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4: version "1.5.4" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz" integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA== dependencies: call-bind "^1.0.8" @@ -9639,7 +9603,7 @@ regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4: regexpu-core@^6.3.1: version "6.4.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz" integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== dependencies: regenerate "^1.4.2" @@ -9651,26 +9615,26 @@ regexpu-core@^6.3.1: regjsgen@^0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== regjsparser@^0.13.0: version "0.13.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz" integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== dependencies: jsesc "~3.1.0" rehype-raw@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-5.1.0.tgz#66d5e8d7188ada2d31bc137bc19a1000cf2c6b7e" + resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-5.1.0.tgz" integrity sha512-MDvHAb/5mUnif2R+0IPCYJU8WjHa9UzGtM/F4AVy5GixPlDZ1z3HacYy4xojDU+uBa+0X/3PIfyQI26/2ljJNA== dependencies: hast-util-raw "^6.1.0" rehype-react@^6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/rehype-react/-/rehype-react-6.2.1.tgz#9b9bf188451ad6f63796b784fe1f51165c67b73a" + resolved "https://registry.npmjs.org/rehype-react/-/rehype-react-6.2.1.tgz" integrity sha512-f9KIrjktvLvmbGc7si25HepocOg4z0MuNOtweigKzBcDjiGSTGhyz6VSgaV5K421Cq1O+z4/oxRJ5G9owo0KVg== dependencies: "@mapbox/hast-util-table-cell-style" "^0.2.0" @@ -9678,26 +9642,26 @@ rehype-react@^6.2.1: rehype-stringify@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-8.0.0.tgz#9b6afb599bcf3165f10f93fc8548f9a03d2ec2ba" + resolved "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz" integrity sha512-VkIs18G0pj2xklyllrPSvdShAV36Ff3yE5PUO9u36f6+2qJFnn22Z5gKwBOwgXviux4UC7K+/j13AnZfPICi/g== dependencies: hast-util-to-html "^7.1.1" relateurl@^0.2.7: version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + resolved "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz" integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== remark-breaks@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/remark-breaks/-/remark-breaks-2.0.2.tgz#55fdec6c7da84f659aa7fdb1aa95b632870cee8d" + resolved "https://registry.npmjs.org/remark-breaks/-/remark-breaks-2.0.2.tgz" integrity sha512-LsQnPPQ7Fzp9RTjj4IwdEmjPOr9bxe9zYKWhs9ZQOg9hMg8rOfeeqQ410cvVdIK87Famqza1CKRxNkepp2EvUA== dependencies: unist-util-visit "^2.0.0" remark-emoji@^2.1.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" + resolved "https://registry.npmjs.org/remark-emoji/-/remark-emoji-2.2.0.tgz" integrity sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w== dependencies: emoticon "^3.2.0" @@ -9706,7 +9670,7 @@ remark-emoji@^2.1.0: remark-parse-no-trim@^8.0.4: version "8.0.4" - resolved "https://registry.yarnpkg.com/remark-parse-no-trim/-/remark-parse-no-trim-8.0.4.tgz#f5c9531644284071d4a57a49e19a42ad4e8040bd" + resolved "https://registry.npmjs.org/remark-parse-no-trim/-/remark-parse-no-trim-8.0.4.tgz" integrity sha512-WtqeHNTZ0LSdyemmY1/G6y9WoEFblTtgckfKF5/NUnri919/0/dEu8RCDfvXtJvu96soMvT+mLWWgYVUaiHoag== dependencies: ccount "^1.0.0" @@ -9727,19 +9691,19 @@ remark-parse-no-trim@^8.0.4: remark-rehype@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945" + resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz" integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA== dependencies: mdast-util-to-hast "^10.2.0" remove-accents@0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.5.0.tgz#77991f37ba212afba162e375b627631315bed687" + resolved "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz" integrity sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A== renderkid@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + resolved "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz" integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== dependencies: css-select "^4.1.3" @@ -9750,51 +9714,51 @@ renderkid@^3.0.0: repeat-string@^1.5.4: version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== requires-port@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== requizzle@^0.2.3: version "0.2.4" - resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.4.tgz#319eb658b28c370f0c20f968fa8ceab98c13d27c" + resolved "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz" integrity sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw== dependencies: lodash "^4.17.21" resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-url-loader@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" + resolved "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz" integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== dependencies: adjust-sourcemap-loader "^4.0.0" @@ -9805,12 +9769,12 @@ resolve-url-loader@^5.0.0: resolve.exports@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz" integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.10, resolve@^1.22.4: version "1.22.11" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz" integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== dependencies: is-core-module "^2.16.1" @@ -9819,7 +9783,7 @@ resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.10, resolve@^1. resolve@^2.0.0-next.5: version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: is-core-module "^2.13.0" @@ -9828,29 +9792,29 @@ resolve@^2.0.0-next.5: retry@^0.13.1: version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== rettime@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/rettime/-/rettime-0.7.0.tgz#c040f1a65e396eaa4b8346dd96ed937edc79d96f" + resolved "https://registry.npmjs.org/rettime/-/rettime-0.7.0.tgz" integrity sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw== reusify@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rimraf@3.0.2, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" rollup-plugin-copy@^3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz#7ffa2a7a8303e143876fa64fb5eed9022d304eeb" + resolved "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz" integrity sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA== dependencies: "@types/fs-extra" "^8.0.1" @@ -9861,28 +9825,28 @@ rollup-plugin-copy@^3.5.0: rollup-plugin-import-css@^3.0.2: version "3.5.8" - resolved "https://registry.yarnpkg.com/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.8.tgz#f1f7b61ae56c3e1edc9c71dcfde85e5464500cf8" + resolved "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.8.tgz" integrity sha512-a3YsZnwHz66mRHCKHjaPCSfWczczvS/HTkgDc+Eogn0mt/0JZXz0WjK0fzM5WwBpVtOqHB4/gHdmEY40ILsaVg== dependencies: "@rollup/pluginutils" "^5.1.3" rollup-plugin-svg@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-svg/-/rollup-plugin-svg-2.0.0.tgz#ce11b55e915d5b2190328c4e6632bd6b4fe12ee9" + resolved "https://registry.npmjs.org/rollup-plugin-svg/-/rollup-plugin-svg-2.0.0.tgz" integrity sha512-DmE7dSQHo1SC5L2uH2qul3Mjyd5oV6U1aVVkyvTLX/mUsRink7f1b1zaIm+32GEBA6EHu8H/JJi3DdWqM53ySQ== dependencies: rollup-pluginutils "^1.3.1" rollup-plugin-svgo@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-svgo/-/rollup-plugin-svgo-2.0.0.tgz#d182c145fd11f3f8a43de804e3f5b4b70d580a7a" + resolved "https://registry.npmjs.org/rollup-plugin-svgo/-/rollup-plugin-svgo-2.0.0.tgz" integrity sha512-0ryWbGY3sP62brw5p8md5W+1WUMrLUE8d437nGh9gQ+fZFFjlYbyIkctBrTvCm3bIdqN4gxbxg1Xxen1tteD+A== dependencies: svgo "2.8.0" rollup-plugin-terser@^7.0.0, rollup-plugin-terser@^7.0.2: version "7.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz" integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== dependencies: "@babel/code-frame" "^7.10.4" @@ -9892,7 +9856,7 @@ rollup-plugin-terser@^7.0.0, rollup-plugin-terser@^7.0.2: rollup-pluginutils@^1.3.1: version "1.5.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + resolved "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz" integrity sha512-SjdWWWO/CUoMpDy8RUbZ/pSpG68YHmhk5ROKNIoi2En9bJ8bTt3IhYi254RWiTclQmL7Awmrq+rZFOhZkJAHmQ== dependencies: estree-walker "^0.2.1" @@ -9900,21 +9864,21 @@ rollup-pluginutils@^1.3.1: rollup@^2.43.1, rollup@^2.68.0: version "2.79.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.2.tgz#f150e4a5db4b121a21a747d762f701e5e9f49090" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz" integrity sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ== optionalDependencies: fsevents "~2.3.2" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" safe-array-concat@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz" integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== dependencies: call-bind "^1.0.8" @@ -9925,17 +9889,17 @@ safe-array-concat@^1.1.3: safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-push-apply@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5" + resolved "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz" integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== dependencies: es-errors "^1.3.0" @@ -9943,7 +9907,7 @@ safe-push-apply@^1.0.0: safe-regex-test@^1.0.3, safe-regex-test@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz" integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== dependencies: call-bound "^1.0.2" @@ -9952,17 +9916,17 @@ safe-regex-test@^1.0.3, safe-regex-test@^1.1.0: "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize.css@*: version "13.0.0" - resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-13.0.0.tgz#2675553974b27964c75562ade3bd85d79879f173" + resolved "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz" integrity sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA== sass-loader@^12.3.0: version "12.6.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz" integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== dependencies: klona "^2.0.4" @@ -9970,21 +9934,21 @@ sass-loader@^12.3.0: saxes@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + resolved "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz" integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== dependencies: xmlchars "^2.2.0" scheduler@^0.23.2: version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" schema-utils@2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== dependencies: "@types/json-schema" "^7.0.4" @@ -9993,7 +9957,7 @@ schema-utils@2.7.0: schema-utils@^2.6.5: version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: "@types/json-schema" "^7.0.5" @@ -10002,7 +9966,7 @@ schema-utils@^2.6.5: schema-utils@^3.0.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" @@ -10011,7 +9975,7 @@ schema-utils@^3.0.0: schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: version "4.3.3" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz" integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" @@ -10021,12 +9985,12 @@ schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3 select-hose@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== selfsigned@^2.1.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz" integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== dependencies: "@types/node-forge" "^1.3.0" @@ -10034,17 +9998,17 @@ selfsigned@^2.1.1: semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.1.2, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: version "7.7.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== send@0.19.0: version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" @@ -10063,26 +10027,26 @@ send@0.19.0: serialize-javascript@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz" integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== dependencies: randombytes "^2.1.0" serialize-javascript@^6.0.0, serialize-javascript@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" serialize-query-params@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/serialize-query-params/-/serialize-query-params-2.0.2.tgz#598a3fb9e13f4ea1c1992fbd20231aa16b31db81" + resolved "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-2.0.2.tgz" integrity sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q== serve-index@^1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== dependencies: accepts "~1.3.4" @@ -10095,7 +10059,7 @@ serve-index@^1.9.1: serve-static@1.16.2: version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz" integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: encodeurl "~2.0.0" @@ -10105,7 +10069,7 @@ serve-static@1.16.2: set-function-length@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: define-data-property "^1.1.4" @@ -10117,7 +10081,7 @@ set-function-length@^1.2.2: set-function-name@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz" integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: define-data-property "^1.1.4" @@ -10127,7 +10091,7 @@ set-function-name@^2.0.2: set-proto@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/set-proto/-/set-proto-1.0.0.tgz#0760dbcff30b2d7e801fd6e19983e56da337565e" + resolved "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz" integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw== dependencies: dunder-proto "^1.0.1" @@ -10136,39 +10100,39 @@ set-proto@^1.0.0: setprototypeof@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== setprototypeof@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== shallowequal@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3, shell-quote@^1.8.3: version "1.8.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz" integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== side-channel-list@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz" integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: es-errors "^1.3.0" @@ -10176,7 +10140,7 @@ side-channel-list@^1.0.0: side-channel-map@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + resolved "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz" integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== dependencies: call-bound "^1.0.2" @@ -10186,7 +10150,7 @@ side-channel-map@^1.0.1: side-channel-weakmap@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + resolved "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz" integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== dependencies: call-bound "^1.0.2" @@ -10197,7 +10161,7 @@ side-channel-weakmap@^1.0.2: side-channel@^1.0.6, side-channel@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz" integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== dependencies: es-errors "^1.3.0" @@ -10208,32 +10172,32 @@ side-channel@^1.0.6, side-channel@^1.1.0: signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== sisteransi@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slash@^5.0.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce" + resolved "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz" integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg== snake-case@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== dependencies: dot-case "^3.0.4" @@ -10241,7 +10205,7 @@ snake-case@^3.0.4: sockjs@^0.3.24: version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== dependencies: faye-websocket "^0.11.3" @@ -10250,17 +10214,17 @@ sockjs@^0.3.24: source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-js@^1.0.1, source-map-js@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== source-map-loader@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee" + resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz" integrity sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg== dependencies: abab "^2.0.5" @@ -10269,7 +10233,7 @@ source-map-loader@^3.0.0: source-map-support@0.5.13: version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" @@ -10277,7 +10241,7 @@ source-map-support@0.5.13: source-map-support@~0.5.20: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -10285,39 +10249,39 @@ source-map-support@~0.5.20: source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.5.7: version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.7.3: version "0.7.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz" integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== source-map@^0.8.0-beta.0: version "0.8.0-beta.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== dependencies: whatwg-url "^7.0.0" sourcemap-codec@^1.4.8: version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== space-separated-tokens@^1.0.0: version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== spdy-transport@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== dependencies: debug "^4.1.0" @@ -10329,7 +10293,7 @@ spdy-transport@^3.0.0: spdy@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== dependencies: debug "^4.1.0" @@ -10340,61 +10304,61 @@ spdy@^4.0.2: split-on-first@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stable@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-utils@^2.0.3: version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" stackframe@^1.3.4: version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== state-toggle@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz" integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== static-eval@2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.2.tgz#2d1759306b1befa688938454c546b7871f806a42" + resolved "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz" integrity sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg== dependencies: escodegen "^1.8.1" statuses@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== "statuses@>= 1.4.0 < 2": version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== statuses@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== stop-iteration-iterator@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz" integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ== dependencies: es-errors "^1.3.0" @@ -10402,17 +10366,17 @@ stop-iteration-iterator@^1.1.0: strict-event-emitter@^0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93" + resolved "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz" integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== strict-uri-encode@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== string-length@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" @@ -10420,7 +10384,7 @@ string-length@^4.0.1: string-length@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-5.0.1.tgz#3d647f497b6e8e8d41e422f7e0b23bc536c8381e" + resolved "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz" integrity sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow== dependencies: char-regex "^2.0.0" @@ -10428,12 +10392,12 @@ string-length@^5.0.1: string-natural-compare@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" + resolved "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -10442,7 +10406,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: string.prototype.includes@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz#eceef21283640761a81dbe16d6c7171a4edf7d92" + resolved "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz" integrity sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg== dependencies: call-bind "^1.0.7" @@ -10451,7 +10415,7 @@ string.prototype.includes@^2.0.1: string.prototype.matchall@^4.0.12, string.prototype.matchall@^4.0.6: version "4.0.12" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz" integrity sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA== dependencies: call-bind "^1.0.8" @@ -10470,7 +10434,7 @@ string.prototype.matchall@^4.0.12, string.prototype.matchall@^4.0.6: string.prototype.repeat@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" + resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz" integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== dependencies: define-properties "^1.1.3" @@ -10478,7 +10442,7 @@ string.prototype.repeat@^1.0.0: string.prototype.trim@^1.2.10: version "1.2.10" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz" integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== dependencies: call-bind "^1.0.8" @@ -10491,7 +10455,7 @@ string.prototype.trim@^1.2.10: string.prototype.trimend@^1.0.9: version "1.0.9" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz" integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== dependencies: call-bind "^1.0.8" @@ -10501,7 +10465,7 @@ string.prototype.trimend@^1.0.9: string.prototype.trimstart@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz" integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: call-bind "^1.0.7" @@ -10510,21 +10474,21 @@ string.prototype.trimstart@^1.0.8: string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" stringify-entities@^3.0.1: version "3.1.0" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-3.1.0.tgz#b8d3feac256d9ffcc9fa1fefdcf3ca70576ee903" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz" integrity sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg== dependencies: character-entities-html4 "^1.0.0" @@ -10533,7 +10497,7 @@ stringify-entities@^3.0.1: stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -10542,65 +10506,65 @@ stringify-object@^3.3.0: strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@^7.0.1: version "7.1.2" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== dependencies: ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-comments@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + resolved "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz" integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-indent@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== dependencies: min-indent "^1.0.0" strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== style-loader@^3.3.1: version "3.3.4" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz" integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== style-to-object@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz" integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== dependencies: inline-style-parser "0.1.1" styled-components@^6.1.0: version "6.1.19" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.19.tgz#9a41b4db79a3b7a2477daecabe8dd917235263d6" + resolved "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz" integrity sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA== dependencies: "@emotion/is-prop-valid" "1.2.2" @@ -10615,7 +10579,7 @@ styled-components@^6.1.0: stylehacks@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz" integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== dependencies: browserslist "^4.21.4" @@ -10623,41 +10587,41 @@ stylehacks@^5.1.1: stylis@4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== stylis@4.3.2: version "4.3.2" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz" integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== svg-parser@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + resolved "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== svgo@2.8.0, svgo@^2.7.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + resolved "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz" integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== dependencies: "@trysound/sax" "0.2.0" @@ -10670,7 +10634,7 @@ svgo@2.8.0, svgo@^2.7.0: svgo@^3.0.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.2.tgz#ad58002652dffbb5986fc9716afe52d869ecbda8" + resolved "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz" integrity sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw== dependencies: "@trysound/sax" "0.2.0" @@ -10683,32 +10647,32 @@ svgo@^3.0.2: symbol-tree@^3.2.4: version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tabbable@^5.3.3: version "5.3.3" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.3.3.tgz#aac0ff88c73b22d6c3c5a50b1586310006b47fbf" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz" integrity sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA== tapable@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tapable@^2.0.0, tapable@^2.2.0, tapable@^2.2.1, tapable@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== temp-dir@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz" integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== tempy@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + resolved "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz" integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== dependencies: is-stream "^2.0.0" @@ -10718,7 +10682,7 @@ tempy@^0.6.0: terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.11: version "5.3.14" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz" integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== dependencies: "@jridgewell/trace-mapping" "^0.3.25" @@ -10729,7 +10693,7 @@ terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.11: terser@^5.0.0, terser@^5.10.0, terser@^5.31.1: version "5.44.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.1.tgz#e391e92175c299b8c284ad6ded609e37303b0a9c" + resolved "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz" integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== dependencies: "@jridgewell/source-map" "^0.3.3" @@ -10739,7 +10703,7 @@ terser@^5.0.0, terser@^5.10.0, terser@^5.31.1: test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" @@ -10748,61 +10712,61 @@ test-exclude@^6.0.0: text-diff@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/text-diff/-/text-diff-1.0.1.tgz#6c105905435e337857375c9d2f6ca63e453ff565" + resolved "https://registry.npmjs.org/text-diff/-/text-diff-1.0.1.tgz" integrity sha512-jAnlP3ggZk7FeLX1awaMR8Y2sMyil9P9FXvNjaIJIQBAom1zvpKGGH31htOVrUFp0vlyygmJJpNrbJ4rfjsxrA== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== thunky@^1.0.2: version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== tiny-invariant@^1.0.6: version "1.3.3" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== tldts-core@^7.0.18: version "7.0.18" - resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-7.0.18.tgz#78edfd38e8c35e20fb4d2cde63c759139e169d31" + resolved "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.18.tgz" integrity sha512-jqJC13oP4FFAahv4JT/0WTDrCF9Okv7lpKtOZUGPLiAnNbACcSg8Y8T+Z9xthOmRBqi/Sob4yi0TE0miRCvF7Q== tldts@^7.0.5: version "7.0.18" - resolved "https://registry.yarnpkg.com/tldts/-/tldts-7.0.18.tgz#72cac7a2bdb6bba78f8a09fdf7ef84843b09aa94" + resolved "https://registry.npmjs.org/tldts/-/tldts-7.0.18.tgz" integrity sha512-lCcgTAgMxQ1JKOWrVGo6E69Ukbnx4Gc1wiYLRf6J5NN4HRYJtCby1rPF8rkQ4a6qqoFBK5dvjJ1zJ0F7VfDSvw== dependencies: tldts-core "^7.0.18" tmp@^0.2.1: version "0.2.5" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz" integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== tmpl@1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tough-cookie@^4.1.2: version "4.1.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz" integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== dependencies: psl "^1.1.33" @@ -10812,43 +10776,43 @@ tough-cookie@^4.1.2: tough-cookie@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-6.0.0.tgz#11e418b7864a2c0d874702bc8ce0f011261940e5" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz" integrity sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w== dependencies: tldts "^7.0.5" tr46@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== dependencies: punycode "^2.1.0" tr46@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz" integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== dependencies: punycode "^2.1.1" trim-trailing-lines@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" + resolved "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz" integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== trough@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== tryer@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + resolved "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== tsconfig-paths@^3.15.0: version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" @@ -10856,70 +10820,70 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.6.2: +tslib@2.6.2, tslib@^2.6.0: version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.6.0: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1: version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-check@~0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" type-detect@4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.16.0: version "0.16.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz" integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^4.26.1: version "4.41.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz" integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== type-is@~1.6.18: version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" @@ -10927,7 +10891,7 @@ type-is@~1.6.18: typed-array-buffer@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz" integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== dependencies: call-bound "^1.0.3" @@ -10936,7 +10900,7 @@ typed-array-buffer@^1.0.3: typed-array-byte-length@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz" integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== dependencies: call-bind "^1.0.8" @@ -10947,7 +10911,7 @@ typed-array-byte-length@^1.0.3: typed-array-byte-offset@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz" integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== dependencies: available-typed-arrays "^1.0.7" @@ -10960,7 +10924,7 @@ typed-array-byte-offset@^1.0.4: typed-array-length@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz" integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== dependencies: call-bind "^1.0.7" @@ -10972,29 +10936,29 @@ typed-array-length@^1.0.7: typedarray-to-buffer@^3.1.5: version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" typescript@~5.7.2: version "5.7.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz" integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw== uc.micro@^2.0.0, uc.micro@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" + resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz" integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== uglify-js@^3.7.7: version "3.19.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== unbox-primitive@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz" integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== dependencies: call-bound "^1.0.3" @@ -11004,27 +10968,22 @@ unbox-primitive@^1.1.0: underscore@1.12.1: version "1.12.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz" integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== underscore@~1.13.2: version "1.13.7" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.7.tgz#970e33963af9a7dda228f17ebe8399e5fbe63a10" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz" integrity sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g== undici-types@~6.21.0: version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz" integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== -undici-types@~7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" - integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== - unherit@^1.0.4: version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + resolved "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz" integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== dependencies: inherits "^2.0.0" @@ -11032,12 +10991,12 @@ unherit@^1.0.4: unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz" integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== unicode-match-property-ecmascript@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== dependencies: unicode-canonical-property-names-ecmascript "^2.0.0" @@ -11045,17 +11004,17 @@ unicode-match-property-ecmascript@^2.0.0: unicode-match-property-value-ecmascript@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz#65a7adfad8574c219890e219285ce4c64ed67eaa" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz" integrity sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg== unicode-property-aliases-ecmascript@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz#301d4f8a43d2b75c97adfad87c9dd5350c9475d1" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz" integrity sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ== unified@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" + resolved "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz" integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== dependencies: bail "^1.0.0" @@ -11067,60 +11026,60 @@ unified@^9.2.2: unique-string@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz" integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: crypto-random-string "^2.0.0" unist-builder@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + resolved "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz" integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== unist-util-generated@^1.0.0: version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" + resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz" integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== unist-util-is@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz" integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== unist-util-is@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz" integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== unist-util-position@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz" integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== unist-util-remove-position@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" + resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz" integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== dependencies: unist-util-visit "^2.0.0" unist-util-stringify-position@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== dependencies: "@types/unist" "^2.0.2" unist-util-visit-parents@^2.0.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz" integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== dependencies: unist-util-is "^3.0.0" unist-util-visit-parents@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz" integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== dependencies: "@types/unist" "^2.0.0" @@ -11128,14 +11087,14 @@ unist-util-visit-parents@^3.0.0: unist-util-visit@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz" integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== dependencies: unist-util-visit-parents "^2.0.0" unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== dependencies: "@types/unist" "^2.0.0" @@ -11144,22 +11103,22 @@ unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: universalify@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unload@2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" + resolved "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz" integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== dependencies: "@babel/runtime" "^7.6.2" @@ -11167,22 +11126,22 @@ unload@2.2.0: unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== until-async@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/until-async/-/until-async-3.0.2.tgz#447f1531fdd7bb2b4c7a98869bdb1a4c2a23865f" + resolved "https://registry.npmjs.org/until-async/-/until-async-3.0.2.tgz" integrity sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw== upath@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== update-browserslist-db@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz" integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== dependencies: escalade "^3.2.0" @@ -11190,14 +11149,14 @@ update-browserslist-db@^1.1.4: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" url-parse@^1.5.10, url-parse@^1.5.3: version "1.5.10" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== dependencies: querystringify "^2.1.1" @@ -11205,26 +11164,26 @@ url-parse@^1.5.10, url-parse@^1.5.3: use-callback-ref@^1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz#98d9fab067075841c5b2c6852090d5d0feabe2bf" + resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz" integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg== dependencies: tslib "^2.0.0" use-memo-one@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99" + resolved "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz" integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ== use-query-params@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/use-query-params/-/use-query-params-2.2.1.tgz#c558ab70706f319112fbccabf6867b9f904e947d" + resolved "https://registry.npmjs.org/use-query-params/-/use-query-params-2.2.1.tgz" integrity sha512-i6alcyLB8w9i3ZK3caNftdb+UnbfBRNPDnc89CNQWkGRmDrm/gfydHvMBfVsQJRq3NoHOM2dt/ceBWG2397v1Q== dependencies: serialize-query-params "^2.0.2" use-sidecar@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb" + resolved "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz" integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== dependencies: detect-node-es "^1.1.0" @@ -11232,32 +11191,32 @@ use-sidecar@^1.1.3: use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.2: version "1.6.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz" integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== utila@~0.4: version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz" integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-to-istanbul@^9.0.1: version "9.3.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz" integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" @@ -11266,17 +11225,17 @@ v8-to-istanbul@^9.0.1: vary@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== vfile-location@^3.0.0, vfile-location@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" + resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz" integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== vfile-message@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz" integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== dependencies: "@types/unist" "^2.0.0" @@ -11284,7 +11243,7 @@ vfile-message@^2.0.0: vfile@^4.0.0, vfile@^4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" + resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz" integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== dependencies: "@types/unist" "^2.0.0" @@ -11294,21 +11253,21 @@ vfile@^4.0.0, vfile@^4.2.1: w3c-xmlserializer@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz" integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== dependencies: xml-name-validator "^4.0.0" walker@^1.0.7, walker@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" watchpack@^2.4.4: version "2.4.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz" integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== dependencies: glob-to-regexp "^0.4.1" @@ -11316,29 +11275,29 @@ watchpack@^2.4.4: wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== dependencies: minimalistic-assert "^1.0.0" web-namespaces@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== webidl-conversions@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== webidl-conversions@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== webpack-dev-middleware@^5.3.4: version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz" integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== dependencies: colorette "^2.0.10" @@ -11349,7 +11308,7 @@ webpack-dev-middleware@^5.3.4: webpack-dev-server@^4.6.0: version "4.15.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz" integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== dependencies: "@types/bonjour" "^3.5.9" @@ -11385,7 +11344,7 @@ webpack-dev-server@^4.6.0: webpack-manifest-plugin@^4.0.2: version "4.1.1" - resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz#10f8dbf4714ff93a215d5a45bcc416d80506f94f" + resolved "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz" integrity sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow== dependencies: tapable "^2.0.0" @@ -11393,7 +11352,7 @@ webpack-manifest-plugin@^4.0.2: webpack-sources@^1.4.3: version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" @@ -11401,7 +11360,7 @@ webpack-sources@^1.4.3: webpack-sources@^2.2.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz" integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== dependencies: source-list-map "^2.0.1" @@ -11409,12 +11368,12 @@ webpack-sources@^2.2.0: webpack-sources@^3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz" integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.64.4: version "5.103.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.103.0.tgz#17a7c5a5020d5a3a37c118d002eade5ee2c6f3da" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz" integrity sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw== dependencies: "@types/eslint-scope" "^3.7.7" @@ -11445,7 +11404,7 @@ webpack@^5.64.4: websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== dependencies: http-parser-js ">=0.5.1" @@ -11454,29 +11413,29 @@ websocket-driver@>=0.5.1, websocket-driver@^0.7.4: websocket-extensions@>=0.1.1: version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== whatwg-encoding@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz" integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== dependencies: iconv-lite "0.6.3" whatwg-fetch@^3.6.2: version "3.6.20" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" + resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz" integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== whatwg-mimetype@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz" integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== whatwg-url@^11.0.0: version "11.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz" integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== dependencies: tr46 "^3.0.0" @@ -11484,7 +11443,7 @@ whatwg-url@^11.0.0: whatwg-url@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== dependencies: lodash.sortby "^4.7.0" @@ -11493,7 +11452,7 @@ whatwg-url@^7.0.0: which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz" integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== dependencies: is-bigint "^1.1.0" @@ -11504,7 +11463,7 @@ which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: which-builtin-type@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e" + resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz" integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== dependencies: call-bound "^1.0.2" @@ -11523,7 +11482,7 @@ which-builtin-type@^1.2.1: which-collection@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz" integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== dependencies: is-map "^2.0.3" @@ -11533,7 +11492,7 @@ which-collection@^1.0.2: which-typed-array@^1.1.16, which-typed-array@^1.1.19: version "1.1.19" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz" integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== dependencies: available-typed-arrays "^1.0.7" @@ -11546,42 +11505,42 @@ which-typed-array@^1.1.16, which-typed-array@^1.1.19: which@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" word-wrap@^1.2.5, word-wrap@~1.2.3: version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -workbox-background-sync@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz#08d603a33717ce663e718c30cc336f74909aff2f" - integrity sha512-trJd3ovpWCvzu4sW0E8rV3FUyIcC0W8G+AZ+VcqzzA890AsWZlUGOTSxIMmIHVusUw/FDq1HFWfy/kC/WTRqSg== +workbox-background-sync@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz" + integrity sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw== dependencies: idb "^7.0.1" - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-broadcast-update@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.6.1.tgz#0fad9454cf8e4ace0c293e5617c64c75d8a8c61e" - integrity sha512-fBhffRdaANdeQ1V8s692R9l/gzvjjRtydBOvR6WCSB0BNE2BacA29Z4r9/RHd9KaXCPl6JTdI9q0bR25YKP8TQ== +workbox-broadcast-update@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz" + integrity sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q== dependencies: - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-build@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.6.1.tgz#6010e9ce550910156761448f2dbea8cfcf759cb0" - integrity sha512-INPgDx6aRycAugUixbKgiEQBWD0MPZqU5r0jyr24CehvNuLPSXp/wGOpdRJmts656lNiXwqV7dC2nzyrzWEDnw== +workbox-build@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz" + integrity sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ== dependencies: "@apideck/better-ajv-errors" "^0.3.1" "@babel/core" "^7.11.1" @@ -11605,136 +11564,136 @@ workbox-build@6.6.1: strip-comments "^2.0.1" tempy "^0.6.0" upath "^1.2.0" - workbox-background-sync "6.6.1" - workbox-broadcast-update "6.6.1" - workbox-cacheable-response "6.6.1" - workbox-core "6.6.1" - workbox-expiration "6.6.1" - workbox-google-analytics "6.6.1" - workbox-navigation-preload "6.6.1" - workbox-precaching "6.6.1" - workbox-range-requests "6.6.1" - workbox-recipes "6.6.1" - workbox-routing "6.6.1" - workbox-strategies "6.6.1" - workbox-streams "6.6.1" - workbox-sw "6.6.1" - workbox-window "6.6.1" - -workbox-cacheable-response@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.6.1.tgz#284c2b86be3f4fd191970ace8c8e99797bcf58e9" - integrity sha512-85LY4veT2CnTCDxaVG7ft3NKaFbH6i4urZXgLiU4AiwvKqS2ChL6/eILiGRYXfZ6gAwDnh5RkuDbr/GMS4KSag== - dependencies: - workbox-core "6.6.1" - -workbox-core@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.6.1.tgz#7184776d4134c5ed2f086878c882728fc9084265" - integrity sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw== - -workbox-expiration@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.6.1.tgz#a841fa36676104426dbfb9da1ef6a630b4f93739" - integrity sha512-qFiNeeINndiOxaCrd2DeL1Xh1RFug3JonzjxUHc5WkvkD2u5abY3gZL1xSUNt3vZKsFFGGORItSjVTVnWAZO4A== + workbox-background-sync "6.6.0" + workbox-broadcast-update "6.6.0" + workbox-cacheable-response "6.6.0" + workbox-core "6.6.0" + workbox-expiration "6.6.0" + workbox-google-analytics "6.6.0" + workbox-navigation-preload "6.6.0" + workbox-precaching "6.6.0" + workbox-range-requests "6.6.0" + workbox-recipes "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" + workbox-streams "6.6.0" + workbox-sw "6.6.0" + workbox-window "6.6.0" + +workbox-cacheable-response@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz" + integrity sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw== + dependencies: + workbox-core "6.6.0" + +workbox-core@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz" + integrity sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ== + +workbox-expiration@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz" + integrity sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw== dependencies: idb "^7.0.1" - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-google-analytics@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.6.1.tgz#a07a6655ab33d89d1b0b0a935ffa5dea88618c5d" - integrity sha512-1TjSvbFSLmkpqLcBsF7FuGqqeDsf+uAXO/pjiINQKg3b1GN0nBngnxLcXDYo1n/XxK4N7RaRrpRlkwjY/3ocuA== +workbox-google-analytics@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz" + integrity sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q== dependencies: - workbox-background-sync "6.6.1" - workbox-core "6.6.1" - workbox-routing "6.6.1" - workbox-strategies "6.6.1" + workbox-background-sync "6.6.0" + workbox-core "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" -workbox-navigation-preload@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.6.1.tgz#61a34fe125558dd88cf09237f11bd966504ea059" - integrity sha512-DQCZowCecO+wRoIxJI2V6bXWK6/53ff+hEXLGlQL4Rp9ZaPDLrgV/32nxwWIP7QpWDkVEtllTAK5h6cnhxNxDA== +workbox-navigation-preload@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz" + integrity sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q== dependencies: - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-precaching@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.6.1.tgz#dedeeba10a2d163d990bf99f1c2066ac0d1a19e2" - integrity sha512-K4znSJ7IKxCnCYEdhNkMr7X1kNh8cz+mFgx9v5jFdz1MfI84pq8C2zG+oAoeE5kFrUf7YkT5x4uLWBNg0DVZ5A== +workbox-precaching@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz" + integrity sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw== dependencies: - workbox-core "6.6.1" - workbox-routing "6.6.1" - workbox-strategies "6.6.1" + workbox-core "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" -workbox-range-requests@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.6.1.tgz#ddaf7e73af11d362fbb2f136a9063a4c7f507a39" - integrity sha512-4BDzk28govqzg2ZpX0IFkthdRmCKgAKreontYRC5YsAPB2jDtPNxqx3WtTXgHw1NZalXpcH/E4LqUa9+2xbv1g== +workbox-range-requests@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz" + integrity sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw== dependencies: - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-recipes@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.6.1.tgz#ea70d2b2b0b0bce8de0a9d94f274d4a688e69fae" - integrity sha512-/oy8vCSzromXokDA+X+VgpeZJvtuf8SkQ8KL0xmRivMgJZrjwM3c2tpKTJn6PZA6TsbxGs3Sc7KwMoZVamcV2g== +workbox-recipes@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz" + integrity sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A== dependencies: - workbox-cacheable-response "6.6.1" - workbox-core "6.6.1" - workbox-expiration "6.6.1" - workbox-precaching "6.6.1" - workbox-routing "6.6.1" - workbox-strategies "6.6.1" + workbox-cacheable-response "6.6.0" + workbox-core "6.6.0" + workbox-expiration "6.6.0" + workbox-precaching "6.6.0" + workbox-routing "6.6.0" + workbox-strategies "6.6.0" -workbox-routing@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.6.1.tgz#cba9a1c7e0d1ea11e24b6f8c518840efdc94f581" - integrity sha512-j4ohlQvfpVdoR8vDYxTY9rA9VvxTHogkIDwGdJ+rb2VRZQ5vt1CWwUUZBeD/WGFAni12jD1HlMXvJ8JS7aBWTg== +workbox-routing@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz" + integrity sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw== dependencies: - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-strategies@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.6.1.tgz#38d0f0fbdddba97bd92e0c6418d0b1a2ccd5b8bf" - integrity sha512-WQLXkRnsk4L81fVPkkgon1rZNxnpdO5LsO+ws7tYBC6QQQFJVI6v98klrJEjFtZwzw/mB/HT5yVp7CcX0O+mrw== +workbox-strategies@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz" + integrity sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ== dependencies: - workbox-core "6.6.1" + workbox-core "6.6.0" -workbox-streams@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.6.1.tgz#b2f7ba7b315c27a6e3a96a476593f99c5d227d26" - integrity sha512-maKG65FUq9e4BLotSKWSTzeF0sgctQdYyTMq529piEN24Dlu9b6WhrAfRpHdCncRS89Zi2QVpW5V33NX8PgH3Q== +workbox-streams@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz" + integrity sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg== dependencies: - workbox-core "6.6.1" - workbox-routing "6.6.1" + workbox-core "6.6.0" + workbox-routing "6.6.0" -workbox-sw@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.6.1.tgz#d4c4ca3125088e8b9fd7a748ed537fa0247bd72c" - integrity sha512-R7whwjvU2abHH/lR6kQTTXLHDFU2izht9kJOvBRYK65FbwutT4VvnUAJIgHvfWZ/fokrOPhfoWYoPCMpSgUKHQ== +workbox-sw@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz" + integrity sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ== workbox-webpack-plugin@^6.4.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.1.tgz#4f81cc1ad4e5d2cd7477a86ba83c84ee2d187531" - integrity sha512-zpZ+ExFj9NmiI66cFEApyjk7hGsfJ1YMOaLXGXBoZf0v7Iu6hL0ZBe+83mnDq3YYWAfA3fnyFejritjOHkFcrA== + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz" + integrity sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A== dependencies: fast-json-stable-stringify "^2.1.0" pretty-bytes "^5.4.1" upath "^1.2.0" webpack-sources "^1.4.3" - workbox-build "6.6.1" + workbox-build "6.6.0" -workbox-window@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.6.1.tgz#f22a394cbac36240d0dadcbdebc35f711bb7b89e" - integrity sha512-wil4nwOY58nTdCvif/KEZjQ2NP8uk3gGeRNy2jPBbzypU4BT4D9L8xiwbmDBpZlSgJd2xsT9FvSNU0gsxV51JQ== +workbox-window@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz" + integrity sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw== dependencies: "@types/trusted-types" "^2.0.2" - workbox-core "6.6.1" + workbox-core "6.6.0" wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -11743,7 +11702,7 @@ wrap-ansi@^6.2.0: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -11752,12 +11711,12 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^3.0.0: version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: imurmurhash "^0.1.4" @@ -11767,7 +11726,7 @@ write-file-atomic@^3.0.0: write-file-atomic@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" @@ -11775,52 +11734,52 @@ write-file-atomic@^4.0.2: ws@^8.11.0, ws@^8.13.0: version "8.18.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz" integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== xml-name-validator@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== xmlchars@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== xmlcreate@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" + resolved "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz" integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== xtend@^4.0.0, xtend@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -11833,27 +11792,27 @@ yargs@^17.3.1, yargs@^17.7.2: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== yoctocolors-cjs@^2.1.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" + resolved "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz" integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== zod@^3.11.6: version "3.25.76" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" + resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz" integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== zustand@^4.4.1: version "4.5.7" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.7.tgz#7d6bb2026a142415dd8be8891d7870e6dbe65f55" + resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz" integrity sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw== dependencies: use-sync-external-store "^1.2.2" zwitch@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz" integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==